mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
commit
e458c85cb8
4 changed files with 67 additions and 31 deletions
|
|
@ -31,8 +31,8 @@ android {
|
|||
applicationId "com.geeksville.mesh"
|
||||
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
|
||||
targetSdkVersion 29
|
||||
versionCode 20133 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "1.1.33"
|
||||
versionCode 20135 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "1.1.35"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
|
|
|||
|
|
@ -606,34 +606,46 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
|
||||
/// Called when we gain/lose a connection to our mesh radio
|
||||
private fun onMeshConnectionChanged(connected: MeshService.ConnectionState) {
|
||||
model.isConnected.value = connected
|
||||
debug("connchange ${model.isConnected.value}")
|
||||
|
||||
if (connected == MeshService.ConnectionState.CONNECTED) {
|
||||
|
||||
model.meshService?.let { service ->
|
||||
|
||||
val oldConnection = model.isConnected.value
|
||||
model.isConnected.value = connected
|
||||
|
||||
debug("Getting latest radioconfig from service")
|
||||
model.radioConfig.value =
|
||||
MeshProtos.RadioConfig.parseFrom(service.radioConfig)
|
||||
try {
|
||||
model.radioConfig.value =
|
||||
MeshProtos.RadioConfig.parseFrom(service.radioConfig)
|
||||
|
||||
val info = service.myNodeInfo
|
||||
model.myNodeInfo.value = info
|
||||
val info = service.myNodeInfo
|
||||
model.myNodeInfo.value = info
|
||||
|
||||
val isOld = info.minAppVersion > BuildConfig.VERSION_CODE
|
||||
if (isOld)
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.app_too_old))
|
||||
.setMessage(getString(R.string.must_update))
|
||||
.setPositiveButton("Okay") { _, _ ->
|
||||
info("User acknowledged app is old")
|
||||
}
|
||||
.show()
|
||||
val isOld = info.minAppVersion > BuildConfig.VERSION_CODE
|
||||
if (isOld)
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.app_too_old))
|
||||
.setMessage(getString(R.string.must_update))
|
||||
.setPositiveButton("Okay") { _, _ ->
|
||||
info("User acknowledged app is old")
|
||||
}
|
||||
.show()
|
||||
|
||||
updateNodesFromDevice()
|
||||
updateNodesFromDevice()
|
||||
|
||||
// we have a connection to our device now, do the channel change
|
||||
perhapsChangeChannel()
|
||||
// we have a connection to our device now, do the channel change
|
||||
perhapsChangeChannel()
|
||||
} catch (ex: RemoteException) {
|
||||
warn("Abandoning connect $ex, because we probably just lost device connection")
|
||||
model.isConnected.value = oldConnection
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// For other connection states, just slam them in
|
||||
model.isConnected.value = connected
|
||||
}
|
||||
}
|
||||
|
||||
private fun perhapsChangeChannel() {
|
||||
|
|
@ -715,7 +727,7 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
model.messagesState.addMessage(payload)
|
||||
}
|
||||
else ->
|
||||
warn("Ignored dataType ${payload.dataType}")
|
||||
debug("activity only cares about text messages, ignoring dataType ${payload.dataType}")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -799,7 +811,8 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
registerMeshReceiver()
|
||||
|
||||
// Init our messages table with the service's record of past text messages (ignore all other message types)
|
||||
val msgs = service.oldMessages.filter { p -> p.dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE }
|
||||
val msgs =
|
||||
service.oldMessages.filter { p -> p.dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE }
|
||||
debug("Service provided ${msgs.size} messages")
|
||||
model.messagesState.setMessages(msgs)
|
||||
val connectionState =
|
||||
|
|
@ -849,7 +862,11 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
}
|
||||
|
||||
// ALSO bind so we can use the api
|
||||
mesh.connect(this, MeshService.createIntent(), Context.BIND_AUTO_CREATE + Context.BIND_ABOVE_CLIENT)
|
||||
mesh.connect(
|
||||
this,
|
||||
MeshService.createIntent(),
|
||||
Context.BIND_AUTO_CREATE + Context.BIND_ABOVE_CLIENT
|
||||
)
|
||||
}
|
||||
|
||||
private fun unbindMeshService() {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class MeshService : Service(), Logging {
|
|||
|
||||
class IdNotFoundException(id: String) : Exception("ID not found $id")
|
||||
class NodeNumNotFoundException(id: Int) : Exception("NodeNum not found $id")
|
||||
class IsUpdatingException() : Exception("Operation prohibited during firmware update")
|
||||
|
||||
/**
|
||||
* Talk to our running service and try to set a new device address. And then immediately
|
||||
|
|
@ -228,6 +229,9 @@ class MeshService : Service(), Logging {
|
|||
private fun sendToRadio(p: ToRadio.Builder) {
|
||||
val b = p.build().toByteArray()
|
||||
|
||||
if(SoftwareUpdateService.isUpdating)
|
||||
throw IsUpdatingException()
|
||||
|
||||
connectedRadio.sendToRadio(b)
|
||||
}
|
||||
|
||||
|
|
@ -892,7 +896,7 @@ class MeshService : Service(), Logging {
|
|||
// Do our startup init
|
||||
try {
|
||||
connectTimeMsec = System.currentTimeMillis()
|
||||
SoftwareUpdateService.sendProgress(this, ProgressNotStarted) // Kinda crufty way of reiniting software update
|
||||
SoftwareUpdateService.sendProgress(this, ProgressNotStarted, true) // Kinda crufty way of reiniting software update
|
||||
startConfig()
|
||||
|
||||
} catch (ex: InvalidProtocolBufferException) {
|
||||
|
|
|
|||
|
|
@ -194,8 +194,21 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
}
|
||||
|
||||
|
||||
fun sendProgress(context: Context, p: Int) {
|
||||
if(progress != p) {
|
||||
/**
|
||||
* true if we are busy with an update right now
|
||||
*/
|
||||
val isUpdating get() = progress >= 0
|
||||
|
||||
/**
|
||||
* Update our progress indication for GUIs
|
||||
*
|
||||
* @param isAppload if false, we don't report failure indications (because we consider spiffs non critical for now). But do report to analytics
|
||||
*/
|
||||
fun sendProgress(context: Context, p: Int, isAppload: Boolean) {
|
||||
if(!isAppload && p < 0)
|
||||
reportError("Error while writing spiffs $progress") // See if this is happening in the wild
|
||||
|
||||
if(progress != p && (p >= 0 || isAppload)) {
|
||||
progress = p
|
||||
|
||||
val intent = Intent(ACTION_UPDATE_PROGRESS).putExtra(
|
||||
|
|
@ -280,7 +293,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
errormsg("Ignoring failure to update spiffs on old appload")
|
||||
}
|
||||
assets.appLoad?.let { doUpdate(context, sync, it, FLASH_REGION_APPLOAD) }
|
||||
sendProgress(context, ProgressSuccess)
|
||||
sendProgress(context, ProgressSuccess, true)
|
||||
}
|
||||
|
||||
// writable region codes in the ESP32 update code
|
||||
|
|
@ -292,6 +305,8 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
* you can use it for the software update.
|
||||
*/
|
||||
private fun doUpdate(context: Context, sync: SafeBluetooth, assetName: String, flashRegion: Int = FLASH_REGION_APPLOAD) {
|
||||
val isAppload = flashRegion == FLASH_REGION_APPLOAD
|
||||
|
||||
try {
|
||||
val g = sync.gatt!!
|
||||
val service = g.services.find { it.uuid == SW_UPDATE_UUID }
|
||||
|
|
@ -306,7 +321,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
|
||||
info("Starting firmware update for $assetName, flash region $flashRegion")
|
||||
|
||||
sendProgress(context,0)
|
||||
sendProgress(context,0, isAppload)
|
||||
val totalSizeDesc = getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER)
|
||||
val dataDesc = getCharacteristic(SW_UPDATE_DATA_CHARACTER)
|
||||
val crc32Desc = getCharacteristic(SW_UPDATE_CRC32_CHARACTER)
|
||||
|
|
@ -354,7 +369,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
// yet
|
||||
val maxProgress = if(flashRegion != FLASH_REGION_APPLOAD)
|
||||
50 else 100
|
||||
sendProgress(context, firmwareNumSent * maxProgress / firmwareSize)
|
||||
sendProgress(context, firmwareNumSent * maxProgress / firmwareSize, isAppload)
|
||||
debug("sending block ${progress}%")
|
||||
var blockSize = 512 - 3 // Max size MTU excluding framing
|
||||
|
||||
|
|
@ -384,7 +399,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
sync.readCharacteristic(updateResultDesc)
|
||||
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)
|
||||
if (updateResult != 0) {
|
||||
sendProgress(context, ProgressUpdateFailed)
|
||||
sendProgress(context, ProgressUpdateFailed, isAppload)
|
||||
throw Exception("Device update failed, reason=$updateResult")
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +410,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
}
|
||||
}
|
||||
} catch (ex: BLEException) {
|
||||
sendProgress(context, ProgressBleException)
|
||||
sendProgress(context, ProgressBleException, isAppload)
|
||||
throw ex // Unexpected BLE exception
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue