kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
Add stress tester that simulates super high chance of BLE failures
and fix bug that it revealed (missing handling of error during discovery)pull/81/head
rodzic
e5d6ffc4bd
commit
103b21aafd
1
TODO.md
1
TODO.md
|
@ -1,5 +1,6 @@
|
||||||
# Remaining tasks before declaring 1.0
|
# Remaining tasks before declaring 1.0
|
||||||
|
|
||||||
|
- add faq entry about range and antennas and rain
|
||||||
- first message sent is still doubled for some people
|
- first message sent is still doubled for some people
|
||||||
- disable software update button after update finishes
|
- disable software update button after update finishes
|
||||||
- let users set arbitrary params in android
|
- let users set arbitrary params in android
|
||||||
|
|
|
@ -354,9 +354,9 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String
|
||||||
private var isFirstTime = true
|
private var isFirstTime = true
|
||||||
|
|
||||||
private fun doDiscoverServicesAndInit() {
|
private fun doDiscoverServicesAndInit() {
|
||||||
// FIXME - no need to discover services more than once - instead use lazy() to use them in future attempts
|
|
||||||
safe!!.asyncDiscoverServices { discRes ->
|
safe!!.asyncDiscoverServices { discRes ->
|
||||||
discRes.getOrThrow() // FIXME, instead just try to reconnect?
|
try {
|
||||||
|
discRes.getOrThrow()
|
||||||
|
|
||||||
service.serviceScope.handledLaunch {
|
service.serviceScope.handledLaunch {
|
||||||
try {
|
try {
|
||||||
|
@ -384,6 +384,11 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (ex: BLEException) {
|
||||||
|
scheduleReconnect(
|
||||||
|
"Unexpected error discovering services, forcing disconnect $ex"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,11 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
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_RELIABLE_WRITE_FAILED = 4403
|
||||||
private val STATUS_TIMEOUT = 4404
|
private val STATUS_TIMEOUT = 4404
|
||||||
private val STATUS_NOSTART = 4405
|
private val STATUS_NOSTART = 4405
|
||||||
|
private val STATUS_SIMFAILURE = 4406
|
||||||
|
|
||||||
private val gattCallback = object : BluetoothGattCallback() {
|
private val gattCallback = object : BluetoothGattCallback() {
|
||||||
|
|
||||||
|
@ -157,6 +161,10 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
||||||
if (oldstate == BluetoothProfile.STATE_CONNECTED) {
|
if (oldstate == BluetoothProfile.STATE_CONNECTED) {
|
||||||
info("Lost connection - aborting current work: $currentWork")
|
info("Lost connection - aborting current work: $currentWork")
|
||||||
|
|
||||||
|
// If we get a disconnect, just try again otherwise fail all current operations
|
||||||
|
if (currentWork?.isConnect() == true)
|
||||||
|
dropAndReconnect()
|
||||||
|
else
|
||||||
lostConnection("lost connection")
|
lostConnection("lost connection")
|
||||||
} else if (status == 133) {
|
} else if (status == 133) {
|
||||||
// We were not previously connected and we just failed with our non-auto connection attempt. Therefore we now need
|
// We were not previously connected and we just failed with our non-auto connection attempt. Therefore we now need
|
||||||
|
@ -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
|
private var activeTimeout: Job? = null
|
||||||
|
|
||||||
|
@ -311,6 +325,14 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
||||||
|
|
||||||
isSettingMtu =
|
isSettingMtu =
|
||||||
false // Most work is not doing MTU stuff, the work that is will re set this flag
|
false // Most work is not doing MTU stuff, the work that is will re set this flag
|
||||||
|
|
||||||
|
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()
|
val started = newWork.startWork()
|
||||||
if (!started) {
|
if (!started) {
|
||||||
errormsg("Failed to start work, returned error status")
|
errormsg("Failed to start work, returned error status")
|
||||||
|
@ -321,6 +343,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun <T> queueWork(
|
private fun <T> queueWork(
|
||||||
tag: String,
|
tag: String,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2f9243202d9db33b0aa0c7656bc8916ad3712914
|
Subproject commit 95c5a9aa950f917857a3cc0c7cd84a4a56993032
|
Ładowanie…
Reference in New Issue