From 5da86129faefdf3c0f6eaf8ec0e3711826d58f60 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 30 Jun 2020 09:32:35 -0700 Subject: [PATCH 1/8] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..7633f54ef --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,51 @@ +name: "Code scanning - action" + +on: + push: + pull_request: + schedule: + - cron: '0 18 * * 4' + +jobs: + CodeQL-Build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + # Override language selection by uncommenting this and choosing your languages + # with: + # languages: go, javascript, csharp, python, cpp, java + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 010d63d2dba7d3eb85e3128c5940717cdc1c4506 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 10:56:27 -0700 Subject: [PATCH 2/8] Revert "Create codeql-analysis.yml" This reverts commit 5da86129faefdf3c0f6eaf8ec0e3711826d58f60. --- .github/workflows/codeql-analysis.yml | 51 --------------------------- 1 file changed, 51 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 7633f54ef..000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: "Code scanning - action" - -on: - push: - pull_request: - schedule: - - cron: '0 18 * * 4' - -jobs: - CodeQL-Build: - - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - # Override language selection by uncommenting this and choosing your languages - # with: - # languages: go, javascript, csharp, python, cpp, java - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 From 17faecc170f2d473d958b9122553018c2c5fb120 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 11:13:18 -0700 Subject: [PATCH 3/8] fix autobug --- TODO.md | 34 +------------------ app/build.gradle | 4 +-- .../geeksville/mesh/service/MeshService.kt | 3 +- 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/TODO.md b/TODO.md index b06166bb6..c05937a7d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,38 +1,6 @@ # Remaining tasks before declaring 1.0 -- turning off Bluetooth on oneplus causes a harmless exception - devwork is null - - -06-29 08:47:10.007 29788-29812/com.geeksville.mesh D/BluetoothGatt: configureMTU() - device: 24:62:AB:F8:40:9A mtu: 512 -06-29 08:47:10.007 29788-31466/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth: Starting failsafe timer 5000 -06-29 08:47:10.014 29788-29812/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth: work reconnect is completed, resuming status=0, res=kotlin.Unit -06-29 08:47:10.016 29788-31466/com.geeksville.mesh I/com.geeksville.mesh.service.BluetoothInterface: Connected to radio! -06-29 08:47:10.016 29788-31466/com.geeksville.mesh D/BluetoothGatt: refresh() - device: 24:62:AB:F8:40:9A -06-29 08:47:10.220 29788-31466/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth: Enqueuing work: reqMtu -06-29 08:47:15.009 29788-31466/com.geeksville.mesh E/com.geeksville.mesh.service.SafeBluetooth: Failsafe BLE timer expired! (exception none -06-29 08:47:15.011 29788-29859/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth: Starting failsafe timer 5000 -06-29 08:47:15.015 29788-31466/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth$BluetoothContinuation: Starting work: reqMtu -06-29 08:47:15.016 29788-31466/com.geeksville.mesh D/BluetoothGatt: configureMTU() - device: 24:62:AB:F8:40:9A mtu: 512 -06-29 08:47:15.028 29788-31466/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth: work reqMtu is completed, resuming status=4404, res=kotlin.Unit -06-29 08:47:15.029 29788-31466/com.geeksville.mesh W/com.geeksville.mesh.service.BluetoothInterface: Scheduling reconnect because Giving up on setting MTUs, forcing disconnect com.geeksville.mesh.service.SafeBluetooth$BLEStatusException: Bluetooth status=4404 while doing reqMtu -06-29 08:47:15.034 29788-30155/com.geeksville.mesh W/com.geeksville.mesh.service.BluetoothInterface: Forcing disconnect and hopefully device will comeback (disabling forced refresh) -06-29 08:47:15.034 29788-30155/com.geeksville.mesh I/com.geeksville.mesh.service.SafeBluetooth: Closing our GATT connection -06-29 08:47:15.035 29788-30155/com.geeksville.mesh D/BluetoothGatt: cancelOpen() - device: 24:62:AB:F8:40:9A -06-29 08:47:15.036 29788-30155/com.geeksville.mesh D/BluetoothGatt: close() -06-29 08:47:15.037 29788-30155/com.geeksville.mesh D/BluetoothGatt: unregisterApp() - mClientIf=5 -06-29 08:47:15.037 29788-29813/com.geeksville.mesh D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=24:62:AB:F8:40:9A -06-29 08:47:15.037 29788-29813/com.geeksville.mesh W/BluetoothGatt: Unhandled exception in callback - java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.BluetoothGattCallback.onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)' on a null object reference - at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:182) - at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70) - at android.os.Binder.execTransact(Binder.java:446) -06-29 08:47:16.040 29788-31466/com.geeksville.mesh W/com.geeksville.mesh.service.BluetoothInterface: Attempting reconnect -06-29 08:47:16.041 29788-31466/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth: Enqueuing work: connect -06-29 08:47:16.041 29788-31466/com.geeksville.mesh D/com.geeksville.mesh.service.SafeBluetooth$BluetoothContinuation: Starting work: connect -06-29 08:47:16.043 29788-31466/com.geeksville.mesh D/BluetoothGatt: connect() - device: 24:62:AB:F8:40:9A, auto: false -06-29 08:47:16.043 29788-31466/com.geeksville.mesh D/BluetoothGatt: registerApp() - -- soyes sx ble problems (again) +- fix release build inclusion of firmware - Android frontend should refetch the android messages from backend service on Resume - disable software update button after update finishes - first message sent is still doubled for some people diff --git a/app/build.gradle b/app/build.gradle index e9010b104..6f06e641c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 10782 // format is Mmmss (where M is 1+the numeric major number - versionName "0.7.82" + versionCode 10783 // format is Mmmss (where M is 1+the numeric major number + versionName "0.7.83" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 21daedcbb..3835ec0d6 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -398,7 +398,8 @@ class MeshService : Service(), Logging { } - override fun toString() = summaryString + // Note: do not override toString, it causes infinite recursion on some androids (because contextWrapper.getResources calls to string) + // override fun toString() = summaryString /** * Generate a new version of our notification - reflecting current app state From e6fd79f477a102cb6dc9c53584b003f7ed1d9c7a Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 11:39:04 -0700 Subject: [PATCH 4/8] fix another autobug - clear gatt first, because close() can fail --- .../main/java/com/geeksville/mesh/service/SafeBluetooth.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt index 008fb0f99..aae882bb3 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt @@ -676,10 +676,11 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD msecsLeft -= 100 } - if (gatt != null) { + gatt?.let { g2 -> warn("Android onConnectionStateChange did not run, manually closing") - gatt?.close() - gatt = null + gatt = + null // clear gat before calling close, bcause close might throw dead object exception + g2.close() } } catch (ex: DeadObjectException) { warn("Ignoring dead object exception, probably bluetooth was just disabled") From 4571eeea2a1608c4461dd6cc962c4364b2beeba1 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 12:01:48 -0700 Subject: [PATCH 5/8] get logs from oneplus devices --- geeksville-androidlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geeksville-androidlib b/geeksville-androidlib index b2d359e2e..792b33a4a 160000 --- a/geeksville-androidlib +++ b/geeksville-androidlib @@ -1 +1 @@ -Subproject commit b2d359e2e1c9ed0a931eb6f2d909355b2fd93cff +Subproject commit 792b33a4a82316d0e15be1e15fcf2d777fdc41e0 From 0349e823f81ccd944c173a25653340c63eb619f5 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 12:02:12 -0700 Subject: [PATCH 6/8] don't spam crashlytics with non-bug reports --- .../java/com/geeksville/mesh/service/BluetoothInterface.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt b/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt index 6560919c4..8adbf0675 100644 --- a/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt @@ -169,6 +169,7 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String * this is created in onCreate() * We do an ugly hack of keeping it in the singleton so we can share it for the rare software update case */ + @Volatile var safe: SafeBluetooth? = null } @@ -332,7 +333,10 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String delay(1000) // Give some nasty time for buggy BLE stacks to shutdown (500ms was not enough) reconnectJob = null // Any new reconnect requests after this will be allowed to run warn("Attempting reconnect") - startConnect() + if (safe != null) // check again, because we just slept for 1sec, and someone might have closed our interface + startConnect() + else + warn("Not connecting, because safe==null, someone must have closed us") } else { warn("Abandoning reconnect because safe==null, someone must have closed the device") } From fed418dae2a8dc2559864c3fdea8f5b45c4c01cd Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 12:18:49 -0700 Subject: [PATCH 7/8] better debug output for the next time an autobug occurs --- .../java/com/geeksville/mesh/service/BluetoothInterface.kt | 2 +- .../main/java/com/geeksville/mesh/service/SafeBluetooth.kt | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt b/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt index 8adbf0675..92ba0eb7e 100644 --- a/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/service/BluetoothInterface.kt @@ -425,7 +425,7 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String override fun close() { if (safe != null) { - info("Closing radio interface service") + info("Closing BluetoothInterface") val s = safe safe = null // We do this first, because if we throw we still want to mark that we no longer have a valid connection diff --git a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt index aae882bb3..500207a8d 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt @@ -11,7 +11,6 @@ import com.geeksville.concurrent.CallbackContinuation import com.geeksville.concurrent.Continuation import com.geeksville.concurrent.SyncContinuation import com.geeksville.util.exceptionReporter -import com.geeksville.util.ignoreException import kotlinx.coroutines.* import java.io.Closeable import java.util.* @@ -387,6 +386,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD */ private fun failAllWork(ex: Exception) { synchronized(workQueue) { + warn("Failing ${workQueue.size} works, because ${ex.message}") workQueue.forEach { it.completion.resumeWithException(ex) } @@ -704,10 +704,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD closeGatt() - ignoreException { - // Hmm - sometimes the "Connection closing" exception comes back to us - ignore it - failAllWork(BLEException("Connection closing")) - } + failAllWork(BLEException("Connection closing")) } /** From 4172b221f03c2094df67dee30387b401cd0ff2d7 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 30 Jun 2020 12:35:58 -0700 Subject: [PATCH 8/8] autobug: failure to start should be treated like any other BLE exception --- .../java/com/geeksville/mesh/service/SafeBluetooth.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt index 500207a8d..ec3bf6dee 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt @@ -121,6 +121,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD // Our own custom BLE status codes private val STATUS_RELIABLE_WRITE_FAILED = 4403 private val STATUS_TIMEOUT = 4404 + private val STATUS_NOSTART = 4405 private val gattCallback = object : BluetoothGattCallback() { @@ -310,7 +311,14 @@ 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 - logAssert(newWork.startWork()) + 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 + } } }