kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
set aside ble sw update for now
rodzic
3c338aec61
commit
c06f5f1c39
|
@ -226,12 +226,27 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
completeWork(status, characteristic)
|
||||
}
|
||||
|
||||
override fun onReliableWriteCompleted(gatt: BluetoothGatt, status: Int) {
|
||||
completeWork(status, Unit)
|
||||
}
|
||||
|
||||
override fun onCharacteristicWrite(
|
||||
gatt: BluetoothGatt,
|
||||
characteristic: BluetoothGattCharacteristic,
|
||||
status: Int
|
||||
) {
|
||||
completeWork(status, characteristic)
|
||||
val reliable = currentReliableWrite
|
||||
if (reliable != null)
|
||||
if (!characteristic.value.contentEquals(reliable)) {
|
||||
errormsg("A reliable write failed!")
|
||||
gatt.abortReliableWrite();
|
||||
completeWork(42, characteristic) // skanky code to indicate failure
|
||||
} else {
|
||||
logAssert(gatt.executeReliableWrite())
|
||||
// After this execute reliable completes - we can continue with normal operations (see onReliableWriteCompleted)
|
||||
}
|
||||
else // Just a standard write - do the normal flow
|
||||
completeWork(status, characteristic)
|
||||
}
|
||||
|
||||
override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) {
|
||||
|
@ -481,10 +496,15 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
|
||||
fun requestMtu(len: Int): Unit = makeSync { queueRequestMtu(len, it) }
|
||||
|
||||
private var currentReliableWrite: ByteArray? = null
|
||||
|
||||
private fun queueWriteCharacteristic(
|
||||
c: BluetoothGattCharacteristic,
|
||||
cont: Continuation<BluetoothGattCharacteristic>
|
||||
) = queueWork("writeC ${c.uuid}", cont) { gatt!!.writeCharacteristic(c) }
|
||||
) = queueWork("writeC ${c.uuid}", cont) {
|
||||
currentReliableWrite = null
|
||||
gatt!!.writeCharacteristic(c)
|
||||
}
|
||||
|
||||
fun asyncWriteCharacteristic(
|
||||
c: BluetoothGattCharacteristic,
|
||||
|
@ -494,6 +514,26 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
fun writeCharacteristic(c: BluetoothGattCharacteristic): BluetoothGattCharacteristic =
|
||||
makeSync { queueWriteCharacteristic(c, it) }
|
||||
|
||||
/** Like write, but we use the extra reliable flow documented here:
|
||||
* https://stackoverflow.com/questions/24485536/what-is-reliable-write-in-ble
|
||||
*/
|
||||
private fun queueWriteReliable(
|
||||
c: BluetoothGattCharacteristic,
|
||||
cont: Continuation<Unit>
|
||||
) = queueWork("rwriteC ${c.uuid}", cont) {
|
||||
logAssert(gatt!!.beginReliableWrite())
|
||||
currentReliableWrite = c.value.clone()
|
||||
gatt!!.writeCharacteristic(c)
|
||||
}
|
||||
|
||||
/* fun asyncWriteReliable(
|
||||
c: BluetoothGattCharacteristic,
|
||||
cb: (Result<Unit>) -> Unit
|
||||
) = queueWriteCharacteristic(c, CallbackContinuation(cb)) */
|
||||
|
||||
fun writeReliable(c: BluetoothGattCharacteristic): Unit =
|
||||
makeSync { queueWriteReliable(c, it) }
|
||||
|
||||
private fun queueWriteDescriptor(
|
||||
c: BluetoothGattDescriptor,
|
||||
cont: Continuation<BluetoothGattDescriptor>
|
||||
|
|
|
@ -145,7 +145,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
// FIXME, instead compare version strings carefully to see if less than
|
||||
val needsUpdate = (curver != swVer)
|
||||
|
||||
return needsUpdate && !isDevBuild
|
||||
return needsUpdate && !isDevBuild && false // temporarily disabled because it fails occasionally
|
||||
}
|
||||
|
||||
/** Return the filename this device needs to use as an update (or null if no update needed)
|
||||
|
@ -199,6 +199,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
|
||||
info("Starting firmware update for $assetName")
|
||||
|
||||
progress = 0
|
||||
val totalSizeDesc = service.getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER)
|
||||
val dataDesc = service.getCharacteristic(SW_UPDATE_DATA_CHARACTER)
|
||||
val crc32Desc = service.getCharacteristic(SW_UPDATE_CRC32_CHARACTER)
|
||||
|
@ -219,7 +220,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
)
|
||||
sync.writeCharacteristic(totalSizeDesc)
|
||||
|
||||
// Our write completed, queue up a readback
|
||||
// Our write completed, queue up a readback
|
||||
val totalSizeReadback = sync.readCharacteristic(totalSizeDesc)
|
||||
.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)
|
||||
if (totalSizeReadback == 0) // FIXME - handle this case
|
||||
|
@ -238,8 +239,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
// slightly expensive to keep reallocing this buffer, but whatever
|
||||
logAssert(firmwareStream.read(buffer) == blockSize)
|
||||
firmwareCrc.update(buffer)
|
||||
|
||||
// updateGatt.beginReliableWrite()
|
||||
|
||||
dataDesc.value = buffer
|
||||
sync.writeCharacteristic(dataDesc)
|
||||
firmwareNumSent += blockSize
|
||||
|
|
|
@ -320,6 +320,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
debug("User started firmware update")
|
||||
updateFirmwareButton.isEnabled = false // Disable until things complete
|
||||
updateProgressBar.visibility = View.VISIBLE
|
||||
updateProgressBar.progress = 0 // start from scratch
|
||||
|
||||
scanStatusText.text = "Updating firmware, wait up to eight minutes..."
|
||||
service.startFirmwareUpdate()
|
||||
|
@ -342,6 +343,32 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
return inflater.inflate(R.layout.settings_fragment, container, false)
|
||||
}
|
||||
|
||||
private fun initNodeInfo() {
|
||||
val connected = model.isConnected.value
|
||||
|
||||
// If actively connected possibly let the user update firmware
|
||||
val info = model.myNodeInfo.value
|
||||
if (connected == MeshService.ConnectionState.CONNECTED && info != null && info.shouldUpdate) {
|
||||
updateFirmwareButton.visibility = View.VISIBLE
|
||||
updateFirmwareButton.text =
|
||||
getString(R.string.update_to).format(getString(R.string.cur_firmware_version))
|
||||
} else {
|
||||
updateFirmwareButton.visibility = View.GONE
|
||||
updateProgressBar.visibility = View.GONE
|
||||
}
|
||||
|
||||
when (connected) {
|
||||
MeshService.ConnectionState.CONNECTED -> {
|
||||
val fwStr = info?.firmwareString ?: ""
|
||||
scanStatusText.text = getString(R.string.connected_to).format(fwStr)
|
||||
}
|
||||
MeshService.ConnectionState.DISCONNECTED ->
|
||||
scanStatusText.text = getString(R.string.not_connected)
|
||||
MeshService.ConnectionState.DEVICE_SLEEP ->
|
||||
scanStatusText.text = getString(R.string.connected_sleeping)
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup the ui widgets unrelated to BLE scanning
|
||||
private fun initCommonUI() {
|
||||
model.ownerName.observe(viewLifecycleOwner, Observer { name ->
|
||||
|
@ -351,29 +378,12 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
// Only let user edit their name or set software update while connected to a radio
|
||||
model.isConnected.observe(viewLifecycleOwner, Observer { connected ->
|
||||
usernameView.isEnabled = connected == MeshService.ConnectionState.CONNECTED
|
||||
initNodeInfo()
|
||||
})
|
||||
|
||||
// If actively connected possibly let the user update firmware
|
||||
val info = model.myNodeInfo.value
|
||||
if (connected == MeshService.ConnectionState.CONNECTED && info != null && info.couldUpdate) {
|
||||
updateFirmwareButton.visibility = View.VISIBLE
|
||||
updateFirmwareButton.text =
|
||||
getString(R.string.update_to).format(getString(R.string.cur_firmware_version))
|
||||
} else {
|
||||
updateFirmwareButton.visibility = View.GONE
|
||||
updateProgressBar.visibility = View.GONE
|
||||
}
|
||||
|
||||
when (connected) {
|
||||
MeshService.ConnectionState.CONNECTED -> {
|
||||
val fwStr = info?.firmwareString ?: ""
|
||||
scanStatusText.text = getString(R.string.connected_to).format(fwStr)
|
||||
}
|
||||
MeshService.ConnectionState.DISCONNECTED ->
|
||||
scanStatusText.text = getString(R.string.not_connected)
|
||||
MeshService.ConnectionState.DEVICE_SLEEP ->
|
||||
scanStatusText.text = getString(R.string.connected_sleeping)
|
||||
}
|
||||
|
||||
// Also watch myNodeInfo because it might change later
|
||||
model.myNodeInfo.observe(viewLifecycleOwner, Observer {
|
||||
initNodeInfo()
|
||||
})
|
||||
|
||||
updateFirmwareButton.setOnClickListener {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b53b7f90b326ef6b1dedca32a2472784e63d10e6
|
||||
Subproject commit 8ccbd0b688e9ed1e2ccd836414d535f7a6d5366e
|
Ładowanie…
Reference in New Issue