From 518e2438e80f7dd54be90f78701cece3b1c3ba41 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 6 Jan 2021 11:10:01 +0800 Subject: [PATCH 1/7] fix autobug: don't fail updates (for now) if the spiffs has problems --- .../geeksville/mesh/service/MeshService.kt | 2 +- .../mesh/service/SoftwareUpdateService.kt | 24 +++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index bde6821fc..72e6ef6f1 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -892,7 +892,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) { diff --git a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt index 84bcfbc1a..6504601bf 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt @@ -194,8 +194,16 @@ class SoftwareUpdateService : JobIntentService(), Logging { } - fun sendProgress(context: Context, p: Int) { - if(progress != p) { + /** + * 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 && progress < 0) + reportError("Error while writing spiffs $progress") // See if this is happening in the wild + + if(progress != p && (progress >= 0 || isAppload)) { progress = p val intent = Intent(ACTION_UPDATE_PROGRESS).putExtra( @@ -280,7 +288,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 +300,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 +316,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 +364,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 +394,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 +405,7 @@ class SoftwareUpdateService : JobIntentService(), Logging { } } } catch (ex: BLEException) { - sendProgress(context, ProgressBleException) + sendProgress(context, ProgressBleException, isAppload) throw ex // Unexpected BLE exception } } From 8b259367321ce1307e23ed9be64a253038624947 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 6 Jan 2021 11:34:26 +0800 Subject: [PATCH 2/7] don't warn about good things ;-) --- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index b5686f564..81ad5342d 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -711,6 +711,10 @@ class MainActivity : AppCompatActivity(), Logging, intent.getParcelableExtra(EXTRA_PAYLOAD)!! when (payload.dataType) { + Portnums.PortNum.POSITION_APP_VALUE -> { + // This is expected + debug("activity class ignores position messages") + } Portnums.PortNum.TEXT_MESSAGE_APP_VALUE -> { model.messagesState.addMessage(payload) } From 53b4f59e291492e83e9b19e0db4d7d86e1e23b40 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 8 Jan 2021 14:45:51 +0800 Subject: [PATCH 3/7] 1.1.34 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8292c32a8..06752e429 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 20134 // format is Mmmss (where M is 1+the numeric major number + versionName "1.1.34" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { From 633200ac44b02907d368f4bfdc4a69b0c1c2409a Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 8 Jan 2021 14:51:19 +0800 Subject: [PATCH 4/7] if we lose device connection at a bad time, don't leave UI confused (autobug) --- .../java/com/geeksville/mesh/MainActivity.kt | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 81ad5342d..25c34f612 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -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() { @@ -803,7 +815,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 = @@ -853,7 +866,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() { From 7ff7686ccb88c471ae83755212ca5377d5be3dd8 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 8 Jan 2021 15:19:20 +0800 Subject: [PATCH 5/7] less logspam for expected msgs --- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 25c34f612..4f5a1fce3 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -607,7 +607,7 @@ class MainActivity : AppCompatActivity(), Logging, /// Called when we gain/lose a connection to our mesh radio private fun onMeshConnectionChanged(connected: MeshService.ConnectionState) { debug("connchange ${model.isConnected.value}") - + if (connected == MeshService.ConnectionState.CONNECTED) { model.meshService?.let { service -> @@ -723,15 +723,11 @@ class MainActivity : AppCompatActivity(), Logging, intent.getParcelableExtra(EXTRA_PAYLOAD)!! when (payload.dataType) { - Portnums.PortNum.POSITION_APP_VALUE -> { - // This is expected - debug("activity class ignores position messages") - } Portnums.PortNum.TEXT_MESSAGE_APP_VALUE -> { model.messagesState.addMessage(payload) } else -> - warn("Ignored dataType ${payload.dataType}") + debug("activity only cares about text messages, ignoring dataType ${payload.dataType}") } } From a20fffcc2c12bccb268fd8eac4fdcdb729ff7473 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 8 Jan 2021 15:19:39 +0800 Subject: [PATCH 6/7] don't send BLE commands to meshservice while updating --- app/src/main/java/com/geeksville/mesh/service/MeshService.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 72e6ef6f1..d8ef31baf 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -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) } From 3835a85b8e62d9825060295dbbd176e58bc2ac6e Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 8 Jan 2021 15:19:59 +0800 Subject: [PATCH 7/7] 1.1.35 fix nasty progress related bug in firmware update --- app/build.gradle | 4 ++-- .../com/geeksville/mesh/service/SoftwareUpdateService.kt | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 06752e429..80bad0b4f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 20134 // format is Mmmss (where M is 1+the numeric major number - versionName "1.1.34" + versionCode 20135 // format is Mmmss (where M is 1+the numeric major number + versionName "1.1.35" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt index 6504601bf..507ee007b 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt @@ -194,16 +194,21 @@ class SoftwareUpdateService : JobIntentService(), Logging { } + /** + * 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 && progress < 0) + if(!isAppload && p < 0) reportError("Error while writing spiffs $progress") // See if this is happening in the wild - if(progress != p && (progress >= 0 || isAppload)) { + if(progress != p && (p >= 0 || isAppload)) { progress = p val intent = Intent(ACTION_UPDATE_PROGRESS).putExtra(