kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
channelset wip
rodzic
0743feadc4
commit
bd796524b9
|
@ -5,6 +5,7 @@
|
|||
<w>errormsg</w>
|
||||
<w>geeksville</w>
|
||||
<w>meshtastic</w>
|
||||
<w>protobuf</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
|
@ -133,7 +133,7 @@
|
|||
<!-- The QR codes to share channel settings are shared as meshtastic URLS
|
||||
|
||||
an approximate example:
|
||||
http://www.meshtastic.org/c/YXNkZnF3ZXJhc2RmcXdlcmFzZGZxd2Vy
|
||||
http://www.meshtastic.org/d/YXNkZnF3ZXJhc2RmcXdlcmFzZGZxd2Vy
|
||||
-->
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
|
@ -143,11 +143,11 @@
|
|||
<data
|
||||
android:scheme="https"
|
||||
android:host="www.meshtastic.org"
|
||||
android:pathPrefix="/c/" />
|
||||
android:pathPrefix="/d/" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="www.meshtastic.org"
|
||||
android:pathPrefix="/C/" />
|
||||
android:pathPrefix="/D/" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
|
|
|
@ -20,7 +20,7 @@ data class Channel(
|
|||
companion object {
|
||||
// Note: this string _SHOULD NOT BE LOCALIZED_ because it directly hashes to values used on the device for the default channel name.
|
||||
// FIXME - make this work with new channel name system
|
||||
val defaultChannelName = "Default"
|
||||
const val defaultChannelName = "Default"
|
||||
|
||||
// These bytes must match the well known and not secret bytes used the default channel AES128 key device code
|
||||
val channelDefaultKey = byteArrayOfInts(
|
||||
|
@ -33,27 +33,8 @@ data class Channel(
|
|||
MeshProtos.ChannelSettings.newBuilder().setName(defaultChannelName)
|
||||
.setModemConfig(MeshProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128).build()
|
||||
)
|
||||
|
||||
const val prefix = "https://www.meshtastic.org/c/#"
|
||||
|
||||
private const val base64Flags = Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING
|
||||
|
||||
private fun urlToSettings(url: Uri): MeshProtos.ChannelSettings {
|
||||
val urlStr = url.toString()
|
||||
|
||||
// We no longer support the super old (about 0.8ish? verison of the URLs that don't use the # separator - I doubt
|
||||
// anyone is still using that old format
|
||||
val pathRegex = Regex("$prefix(.*)", RegexOption.IGNORE_CASE)
|
||||
val (base64) = pathRegex.find(urlStr)?.destructured
|
||||
?: throw MalformedURLException("Not a meshtastic URL: ${urlStr.take(40)}")
|
||||
val bytes = Base64.decode(base64, base64Flags)
|
||||
|
||||
return MeshProtos.ChannelSettings.parseFrom(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(url: Uri) : this(urlToSettings(url))
|
||||
|
||||
/// Return the name of our channel as a human readable string. If empty string, assume "Default" per mesh.proto spec
|
||||
val name: String
|
||||
get() = if (settings.name.isEmpty()) {
|
||||
|
@ -106,32 +87,4 @@ data class Channel(
|
|||
|
||||
return "#${name}-${suffix}"
|
||||
}
|
||||
|
||||
/// Can this channel be changed right now?
|
||||
var editable = false
|
||||
|
||||
/// Return an URL that represents the current channel values
|
||||
/// @param upperCasePrefix - portions of the URL can be upper case to make for more efficient QR codes
|
||||
fun getChannelUrl(upperCasePrefix: Boolean = false): Uri {
|
||||
// If we have a valid radio config use it, othterwise use whatever we have saved in the prefs
|
||||
|
||||
val channelBytes = settings.toByteArray() ?: ByteArray(0) // if unset just use empty
|
||||
val enc = Base64.encodeToString(channelBytes, base64Flags)
|
||||
|
||||
val p = if(upperCasePrefix)
|
||||
prefix.toUpperCase()
|
||||
else
|
||||
prefix
|
||||
return Uri.parse("$p$enc")
|
||||
}
|
||||
|
||||
fun getChannelQR(): Bitmap {
|
||||
val multiFormatWriter = MultiFormatWriter()
|
||||
|
||||
// We encode as UPPER case for the QR code URL because QR codes are more efficient for that special case
|
||||
val bitMatrix =
|
||||
multiFormatWriter.encode(getChannelUrl(true).toString(), BarcodeFormat.QR_CODE, 192, 192);
|
||||
val barcodeEncoder = BarcodeEncoder()
|
||||
return barcodeEncoder.createBitmap(bitMatrix)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package com.geeksville.mesh.model
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.util.Base64
|
||||
import com.geeksville.mesh.AppOnlyProtos
|
||||
import com.geeksville.mesh.MeshProtos
|
||||
import com.google.protobuf.ByteString
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.MultiFormatWriter
|
||||
import com.journeyapps.barcodescanner.BarcodeEncoder
|
||||
import java.net.MalformedURLException
|
||||
|
||||
/** Utility function to make it easy to declare byte arrays - FIXME move someplace better */
|
||||
fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos].toByte() }
|
||||
|
||||
|
||||
data class ChannelSet(
|
||||
val protobuf: AppOnlyProtos.ChannelSet = AppOnlyProtos.ChannelSet.getDefaultInstance()
|
||||
) {
|
||||
companion object {
|
||||
|
||||
// Placeholder when emulating
|
||||
val emulated = ChannelSet(
|
||||
AppOnlyProtos.ChannelSet.newBuilder().addSettings(Channel.emulated.settings).build()
|
||||
)
|
||||
|
||||
const val prefix = "https://www.meshtastic.org/d/#"
|
||||
|
||||
private const val base64Flags = Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING
|
||||
|
||||
private fun urlToChannels(url: Uri): AppOnlyProtos.ChannelSet {
|
||||
val urlStr = url.toString()
|
||||
|
||||
// We no longer support the super old (about 0.8ish? verison of the URLs that don't use the # separator - I doubt
|
||||
// anyone is still using that old format
|
||||
val pathRegex = Regex("$prefix(.*)", RegexOption.IGNORE_CASE)
|
||||
val (base64) = pathRegex.find(urlStr)?.destructured
|
||||
?: throw MalformedURLException("Not a meshtastic URL: ${urlStr.take(40)}")
|
||||
val bytes = Base64.decode(base64, base64Flags)
|
||||
|
||||
return AppOnlyProtos.ChannelSet.parseFrom(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(url: Uri) : this(urlToChannels(url))
|
||||
|
||||
/// Can this channel be changed right now?
|
||||
var editable = false
|
||||
|
||||
/// Return an URL that represents the current channel values
|
||||
/// @param upperCasePrefix - portions of the URL can be upper case to make for more efficient QR codes
|
||||
fun getChannelUrl(upperCasePrefix: Boolean = false): Uri {
|
||||
// If we have a valid radio config use it, othterwise use whatever we have saved in the prefs
|
||||
|
||||
val channelBytes = protobuf.toByteArray() ?: ByteArray(0) // if unset just use empty
|
||||
val enc = Base64.encodeToString(channelBytes, base64Flags)
|
||||
|
||||
val p = if(upperCasePrefix)
|
||||
prefix.toUpperCase()
|
||||
else
|
||||
prefix
|
||||
return Uri.parse("$p$enc")
|
||||
}
|
||||
|
||||
fun getChannelQR(): Bitmap {
|
||||
val multiFormatWriter = MultiFormatWriter()
|
||||
|
||||
// We encode as UPPER case for the QR code URL because QR codes are more efficient for that special case
|
||||
val bitMatrix =
|
||||
multiFormatWriter.encode(getChannelUrl(true).toString(), BarcodeFormat.QR_CODE, 192, 192);
|
||||
val barcodeEncoder = BarcodeEncoder()
|
||||
return barcodeEncoder.createBitmap(bitMatrix)
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue