work around for software update vs scan race condition

1.2-legacy
geeksville 2020-01-23 09:04:06 -08:00
rodzic d536900808
commit dcd1fd3b55
3 zmienionych plików z 123 dodań i 94 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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