kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
commit
cfc7dc8355
2
TODO.md
2
TODO.md
|
@ -1,7 +1,7 @@
|
|||
# Remaining tasks before declaring 1.0
|
||||
|
||||
- add faq entry about range and antennas and rain
|
||||
- first message sent is still doubled for some people
|
||||
- disable software update button after update finishes
|
||||
- let users set arbitrary params in android
|
||||
- add a low level settings screen (let user change any of the RadioConfig parameters)
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ android {
|
|||
applicationId "com.geeksville.mesh"
|
||||
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
|
||||
targetSdkVersion 29
|
||||
versionCode 10785 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "0.7.85"
|
||||
versionCode 10787 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "0.7.87"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../../../../meshtastic-esp32/release/latest/bins
|
|
@ -772,7 +772,12 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
if (model.meshService != null)
|
||||
Exceptions.reportError("meshService was supposed to be null, ignoring (but reporting a bug)")
|
||||
|
||||
MeshService.startService(this) // Start the service so it stays running even after we unbind
|
||||
try {
|
||||
MeshService.startService(this) // Start the service so it stays running even after we unbind
|
||||
} catch (ex: Exception) {
|
||||
// Old samsung phones have a race condition andthis might rarely fail. Which is probably find because the bind will be sufficient most of the time
|
||||
errormsg("Failed to start service from activity - but ignoring because bind will work ${ex.message}")
|
||||
}
|
||||
|
||||
// ALSO bind so we can use the api
|
||||
mesh.connect(this, MeshService.intent, Context.BIND_AUTO_CREATE + Context.BIND_ABOVE_CLIENT)
|
||||
|
|
|
@ -354,35 +354,40 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String
|
|||
private var isFirstTime = true
|
||||
|
||||
private fun doDiscoverServicesAndInit() {
|
||||
// FIXME - no need to discover services more than once - instead use lazy() to use them in future attempts
|
||||
safe!!.asyncDiscoverServices { discRes ->
|
||||
discRes.getOrThrow() // FIXME, instead just try to reconnect?
|
||||
try {
|
||||
discRes.getOrThrow()
|
||||
|
||||
service.serviceScope.handledLaunch {
|
||||
try {
|
||||
debug("Discovered services!")
|
||||
delay(1000) // android BLE is buggy and needs a 500ms sleep before calling getChracteristic, or you might get back null
|
||||
service.serviceScope.handledLaunch {
|
||||
try {
|
||||
debug("Discovered services!")
|
||||
delay(1000) // android BLE is buggy and needs a 500ms sleep before calling getChracteristic, or you might get back null
|
||||
|
||||
/* if (isFirstTime) {
|
||||
isFirstTime = false
|
||||
throw BLEException("Faking a BLE failure")
|
||||
} */
|
||||
/* if (isFirstTime) {
|
||||
isFirstTime = false
|
||||
throw BLEException("Faking a BLE failure")
|
||||
} */
|
||||
|
||||
fromNum = getCharacteristic(BTM_FROMNUM_CHARACTER)
|
||||
fromNum = getCharacteristic(BTM_FROMNUM_CHARACTER)
|
||||
|
||||
// We treat the first send by a client as special
|
||||
isFirstSend = true
|
||||
// We treat the first send by a client as special
|
||||
isFirstSend = true
|
||||
|
||||
// Now tell clients they can (finally use the api)
|
||||
service.onConnect()
|
||||
// Now tell clients they can (finally use the api)
|
||||
service.onConnect()
|
||||
|
||||
// Immediately broadcast any queued packets sitting on the device
|
||||
doReadFromRadio(true)
|
||||
} catch (ex: BLEException) {
|
||||
scheduleReconnect(
|
||||
"Unexpected error in initial device enumeration, forcing disconnect $ex"
|
||||
)
|
||||
// Immediately broadcast any queued packets sitting on the device
|
||||
doReadFromRadio(true)
|
||||
} catch (ex: BLEException) {
|
||||
scheduleReconnect(
|
||||
"Unexpected error in initial device enumeration, forcing disconnect $ex"
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (ex: BLEException) {
|
||||
scheduleReconnect(
|
||||
"Unexpected error discovering services, forcing disconnect $ex"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1461,6 +1461,8 @@ class MeshService : Service(), Logging {
|
|||
errormsg("Unable to update", ex)
|
||||
null
|
||||
}
|
||||
|
||||
debug("setFirmwareUpdateFilename $firmwareUpdateFilename")
|
||||
}
|
||||
|
||||
private fun doFirmwareUpdate() {
|
||||
|
|
|
@ -85,8 +85,11 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return super.toString()
|
||||
return "Work:$tag"
|
||||
}
|
||||
|
||||
/// Connection work items are treated specially
|
||||
fun isConnect() = tag == "connect" || tag == "reconnect"
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,6 +125,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
private val STATUS_RELIABLE_WRITE_FAILED = 4403
|
||||
private val STATUS_TIMEOUT = 4404
|
||||
private val STATUS_NOSTART = 4405
|
||||
private val STATUS_SIMFAILURE = 4406
|
||||
|
||||
private val gattCallback = object : BluetoothGattCallback() {
|
||||
|
||||
|
@ -157,7 +161,11 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
if (oldstate == BluetoothProfile.STATE_CONNECTED) {
|
||||
info("Lost connection - aborting current work: $currentWork")
|
||||
|
||||
dropAndReconnect()
|
||||
// If we get a disconnect, just try again otherwise fail all current operations
|
||||
if (currentWork?.isConnect() == true)
|
||||
dropAndReconnect()
|
||||
else
|
||||
lostConnection("lost connection")
|
||||
} else if (status == 133) {
|
||||
// We were not previously connected and we just failed with our non-auto connection attempt. Therefore we now need
|
||||
// to do an autoconnection attempt. When that attempt succeeds/fails the normal callbacks will be called
|
||||
|
@ -285,6 +293,12 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
}
|
||||
}
|
||||
|
||||
// To test loss of BLE faults we can randomly fail a certain % of all work items. We
|
||||
// skip this for "connect" items because the handling for connection failure is special
|
||||
var simFailures = false
|
||||
var failPercent =
|
||||
10 // 15% failure is unusably high because of constant reconnects, 7% somewhat usable, 10% pretty bad
|
||||
private val failRandom = Random()
|
||||
|
||||
private var activeTimeout: Job? = null
|
||||
|
||||
|
@ -311,13 +325,22 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
|
||||
isSettingMtu =
|
||||
false // Most work is not doing MTU stuff, the work that is will re set this flag
|
||||
val started = newWork.startWork()
|
||||
if (!started) {
|
||||
errormsg("Failed to start work, returned error status")
|
||||
completeWork(
|
||||
STATUS_NOSTART,
|
||||
Unit
|
||||
) // abandon the current attempt and try for another
|
||||
|
||||
val failThis =
|
||||
simFailures && !newWork.isConnect() && failRandom.nextInt(100) < failPercent
|
||||
|
||||
if (failThis) {
|
||||
errormsg("Simulating random work failure!")
|
||||
completeWork(STATUS_SIMFAILURE, Unit)
|
||||
} else {
|
||||
val started = newWork.startWork()
|
||||
if (!started) {
|
||||
errormsg("Failed to start work, returned error status")
|
||||
completeWork(
|
||||
STATUS_NOSTART,
|
||||
Unit
|
||||
) // abandon the current attempt and try for another
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,8 +522,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
}
|
||||
}
|
||||
|
||||
/// Drop our current connection and then requeue a connect as needed
|
||||
private fun dropAndReconnect() {
|
||||
private fun lostConnection(reason: String) {
|
||||
/*
|
||||
Supposedly this reconnect attempt happens automatically
|
||||
"If the connection was established through an auto connect, Android will
|
||||
|
@ -511,7 +533,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
|
||||
closeConnection()
|
||||
*/
|
||||
failAllWork(BLEException("Lost connection"))
|
||||
failAllWork(BLEException(reason))
|
||||
|
||||
// Cancel any notifications - because when the device comes back it might have forgotten about us
|
||||
notifyHandlers.clear()
|
||||
|
@ -520,6 +542,11 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
|||
debug("calling lostConnect handler")
|
||||
it.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop our current connection and then requeue a connect as needed
|
||||
private fun dropAndReconnect() {
|
||||
lostConnection("lost connection, reconnecting")
|
||||
|
||||
// Queue a new connection attempt
|
||||
val cb = connectionCallback
|
||||
|
|
|
@ -230,10 +230,12 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
val (region) = regionRegex.find(hwVer)?.destructured
|
||||
?: throw Exception("Malformed hw version")
|
||||
|
||||
val name = "firmware/firmware-$mfg-$region-$curver.bin"
|
||||
val base = "firmware-$mfg-$region-$curver.bin"
|
||||
|
||||
// Check to see if the file exists (some builds might not include update files for size reasons)
|
||||
return if (!context.assets.list(name).isNullOrEmpty())
|
||||
name
|
||||
val firmwareFiles = context.assets.list("firmware") ?: arrayOf()
|
||||
return if (firmwareFiles.contains(base))
|
||||
"firmware/$base"
|
||||
else
|
||||
null
|
||||
}
|
||||
|
|
|
@ -484,10 +484,12 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
updateProgressBar.progress = service.updateStatus
|
||||
delay(2000) // Only check occasionally
|
||||
}
|
||||
|
||||
val isSuccess = (service.updateStatus == -1)
|
||||
scanStatusText.text =
|
||||
if (service.updateStatus == -1) "Update successful" else "Update failed"
|
||||
if (isSuccess) "Update successful" else "Update failed"
|
||||
updateProgressBar.isEnabled = false
|
||||
updateFirmwareButton.isEnabled = true
|
||||
updateFirmwareButton.isEnabled = !isSuccess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +506,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
|
||||
// If actively connected possibly let the user update firmware
|
||||
val info = model.myNodeInfo.value
|
||||
if (connected == MeshService.ConnectionState.CONNECTED && info != null && info.shouldUpdate) {
|
||||
if (connected == MeshService.ConnectionState.CONNECTED && info != null && info.shouldUpdate && info.couldUpdate) {
|
||||
updateFirmwareButton.visibility = View.VISIBLE
|
||||
updateFirmwareButton.text =
|
||||
getString(R.string.update_to).format(getString(R.string.cur_firmware_version))
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 10d3b2e62b26d41b9b2568eefb3c207442c1cc5c
|
||||
Subproject commit 95c5a9aa950f917857a3cc0c7cd84a4a56993032
|
Ładowanie…
Reference in New Issue