pbio/drv/bluetooth_btstack: Make scan, connect, and pairing more robust. #445
+481
−305
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This makes the scan/connect/pair function more robust. In our other drivers, the
scan_and_connect_funcwas already a protothread that the user could would await until completion. In thebluetooth_btstack.cdriver, this was a little different. Instead, the protothread would kick off a state machine in the btstack event handler, and await until it got into the connected state.This worked well enough for some cases, but there was no mechanism to bubble up intermediate errors so we could not recover from bad states. It was also quite hard to follow, because the btstack event handler does not map to the same states. For example,
GATT_EVENT_QUERY_COMPLETEmeans something different if you're reading, writing, or discovering a characteristic, and then it would have to be mapped to a specific peripheral (once we support more than one, see below.)We can rewrite it so it is more like this, where we drive the Bluetooth process forward on each normal event as well as each btstack event:
Between each step, we can return errors if they occur, and each step is cancellable by the user or by timeout.
Operations that are not cancellable still don't get the hub stuck. If we an irrecoverable Bluetooth state and the user stops the program, the hub will gracefully shut down.
This also further generalizes the btstack driver towards allowing more than one peripheral in the future, a process that has been started in commits prior to this PR. In this step, we further reduce the dependency on hardcoded singletons by moving the btstack peripheral state instance into the peripheral object. The tasks are also written to use the peripheral reference rather than the singleton. Later, we can pass the specific instance to each task.