sforkowany z mirror/meshtastic-android
work around for software update vs scan race condition
rodzic
d536900808
commit
dcd1fd3b55
2
TODO.md
2
TODO.md
|
@ -4,6 +4,7 @@
|
|||
* get signal running under debugger
|
||||
* DONE add broadcasters for use by signal (node changes and packet received)
|
||||
* make test implementation of server (doesn't use bluetooth)
|
||||
* make compose based access show mesh state
|
||||
* make a test client of the android service
|
||||
* add real messaging code/protobufs
|
||||
* use https://codelabs.developers.google.com/codelabs/jetpack-compose-basics/#4 to show service state
|
||||
|
@ -21,6 +22,7 @@ nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb
|
|||
|
||||
# Medium priority
|
||||
|
||||
* change info() log strings to debug()
|
||||
* use platform theme (dark or light)
|
||||
* remove mixpanel analytics
|
||||
* require user auth to pair with the device (i.e. press button on device to allow a new phone to pair with it).
|
||||
|
|
|
@ -155,12 +155,16 @@ class MainActivity : AppCompatActivity(), Logging {
|
|||
}
|
||||
|
||||
private fun bindMeshService() {
|
||||
info("Binding to mesh service!")
|
||||
debug("Binding to mesh service!")
|
||||
// we bind using the well known name, to make sure 3rd party apps could also
|
||||
logAssert(meshService == null)
|
||||
// FIXME - finding by string does work
|
||||
val intent = Intent(this, MeshService::class.java)
|
||||
intent.action = IMeshService::class.java.name
|
||||
intent.setPackage("com.geeksville.mesh");
|
||||
|
||||
// This is the remote version that does not work! FIXME
|
||||
//val intent = Intent(IMeshService::class.java.name)
|
||||
//intent.setPackage("com.geeksville.mesh");
|
||||
isBound = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
|
||||
logAssert(isBound)
|
||||
}
|
||||
|
@ -170,7 +174,7 @@ class MainActivity : AppCompatActivity(), Logging {
|
|||
// it, then now is the time to unregister.
|
||||
// if we never connected, do nothing
|
||||
if(isBound) {
|
||||
info("Unbinding from mesh service!")
|
||||
debug("Unbinding from mesh service!")
|
||||
unbindService(serviceConnection)
|
||||
meshService = null
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
}
|
||||
|
||||
fun startUpdate() {
|
||||
info("starting update")
|
||||
firmwareStream = assets.open("firmware.bin")
|
||||
|
||||
// Start the update by writing the # of bytes in the image
|
||||
|
@ -46,6 +47,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
|
||||
// Send the next block of our file to the device
|
||||
fun sendNextBlock() {
|
||||
info("sending next block")
|
||||
if (firmwareStream.available() > 0) {
|
||||
var blockSize = 512
|
||||
|
||||
|
@ -64,22 +66,8 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
private val scanCallback = object : ScanCallback() {
|
||||
override fun onScanFailed(errorCode: Int) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun onBatchScanResults(results: MutableList<ScanResult>?) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
// For each device that appears in our scan, ask for its GATT, when the gatt arrives,
|
||||
// check if it is an eligable device and store it in our list of candidates
|
||||
// if that device later disconnects remove it as a candidate
|
||||
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||
|
||||
// We don't need any more results now
|
||||
bluetoothAdapter.bluetoothLeScanner.stopScan(this)
|
||||
fun connectToDevice(device: BluetoothDevice) {
|
||||
debug("Connect to $device")
|
||||
|
||||
lateinit var bluetoothGatt: BluetoothGatt // late init so we can declare our callback and use this there
|
||||
|
||||
|
@ -112,14 +100,16 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
|
||||
// New services discovered
|
||||
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
||||
info("onServicesDiscovered")
|
||||
logAssert(status == BluetoothGatt.GATT_SUCCESS)
|
||||
|
||||
// broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED)
|
||||
|
||||
val service = gatt.services.find { it.uuid == SW_UPDATE_UUID }
|
||||
if (service != null) {
|
||||
logAssert(service != null)
|
||||
|
||||
// FIXME instead of slamming in the target device here, instead make it a param for startUpdate
|
||||
updateService = service
|
||||
updateService = service!!
|
||||
totalSizeDesc = service.getCharacteristic(SW_UPDATE_TOTALSIZE_CHARACTER)
|
||||
dataDesc = service.getCharacteristic(SW_UPDATE_DATA_CHARACTER)
|
||||
crc32Desc = service.getCharacteristic(SW_UPDATE_CRC32_CHARACTER)
|
||||
|
@ -129,7 +119,6 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
updateGatt = bluetoothGatt
|
||||
enqueueWork(this@SoftwareUpdateService, startUpdateIntent)
|
||||
}
|
||||
}
|
||||
|
||||
// Result of a characteristic read operation
|
||||
override fun onCharacteristicRead(
|
||||
|
@ -137,6 +126,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
characteristic: BluetoothGattCharacteristic,
|
||||
status: Int
|
||||
) {
|
||||
debug("onCharacteristicRead")
|
||||
logAssert(status == BluetoothGatt.GATT_SUCCESS)
|
||||
|
||||
if (characteristic == totalSizeDesc) {
|
||||
|
@ -146,6 +136,9 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
logAssert(readvalue != 0) // FIXME - handle this case
|
||||
enqueueWork(this@SoftwareUpdateService, sendNextBlockIntent)
|
||||
}
|
||||
else {
|
||||
warn("Unexpected read: $characteristic")
|
||||
}
|
||||
|
||||
// broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic)
|
||||
}
|
||||
|
@ -155,6 +148,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
characteristic: BluetoothGattCharacteristic?,
|
||||
status: Int
|
||||
) {
|
||||
debug("onCharacteristicWrite")
|
||||
logAssert(status == BluetoothGatt.GATT_SUCCESS)
|
||||
|
||||
if(characteristic == totalSizeDesc) {
|
||||
|
@ -163,17 +157,46 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
} else if (characteristic == dataDesc) {
|
||||
enqueueWork(this@SoftwareUpdateService, sendNextBlockIntent)
|
||||
}
|
||||
else {
|
||||
warn("Unexpected write: $characteristic")
|
||||
}
|
||||
}
|
||||
}
|
||||
bluetoothGatt =
|
||||
result.device.connectGatt(this@SoftwareUpdateService.applicationContext, true, gattCallback)!!
|
||||
toast("FISH " + bluetoothGatt)
|
||||
device.connectGatt(this@SoftwareUpdateService.applicationContext, true, gattCallback)!!
|
||||
toast("Connected to $device")
|
||||
|
||||
// too early to do this here
|
||||
// logAssert(bluetoothGatt.discoverServices())
|
||||
}
|
||||
|
||||
private val scanCallback = object : ScanCallback() {
|
||||
override fun onScanFailed(errorCode: Int) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun onBatchScanResults(results: MutableList<ScanResult>?) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
// For each device that appears in our scan, ask for its GATT, when the gatt arrives,
|
||||
// check if it is an eligable device and store it in our list of candidates
|
||||
// if that device later disconnects remove it as a candidate
|
||||
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||
|
||||
info("onScanResult")
|
||||
|
||||
// We don't need any more results now
|
||||
bluetoothAdapter.bluetoothLeScanner.stopScan(this)
|
||||
|
||||
connectToDevice(result.device)
|
||||
}
|
||||
}
|
||||
|
||||
// Until my race condition with scanning is fixed
|
||||
fun connectToTestDevice() {
|
||||
connectToDevice(bluetoothAdapter.getRemoteDevice("B4:E6:2D:EA:32:B7"))
|
||||
}
|
||||
|
||||
private fun scanLeDevice(enable: Boolean) {
|
||||
when (enable) {
|
||||
|
@ -217,7 +240,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
toast("Executing: $label")
|
||||
|
||||
when (intent.action) {
|
||||
scanDevicesIntent.action -> scanLeDevice(true)
|
||||
scanDevicesIntent.action -> connectToTestDevice() // FIXME scanLeDevice(true)
|
||||
startUpdateIntent.action -> startUpdate()
|
||||
sendNextBlockIntent.action -> sendNextBlock()
|
||||
else -> logAssert(false)
|
||||
|
|
Ładowanie…
Reference in New Issue