Merge pull request #216 from geeksville/dev

Dev
This commit is contained in:
Kevin Hester 2021-01-08 15:29:05 +08:00 committed by GitHub
commit e458c85cb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 31 deletions

View file

@ -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 {

View file

@ -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() {

View file

@ -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) {

View file

@ -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
}
}