From 02df2b09d4c2793ca97ad48a46640eea7945b9a1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 11 Feb 2024 15:08:08 +1100 Subject: [PATCH] extmod/btstack: Reset pending_value_handle before calling read-done cb. Similar to the previous commit but for MP_BLUETOOTH_IRQ_GATTC_READ_DONE: the pending_value_handle needs to be reset before calling mp_bluetooth_gattc_on_read_write_status(), which will call the Python IRQ handler, which may in turn call back into BTstack to perform an action like a write. In that case the pending_value_handle will need to be available for the write/read/etc to proceed. Fixes issue #13634. Signed-off-by: Damien George --- extmod/btstack/modbluetooth_btstack.c | 3 ++- tests/multi_bluetooth/ble_irq_calls.py | 18 ++++++++++++------ tests/multi_bluetooth/ble_irq_calls.py.exp | 4 ++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index 08d64ab012..b3d349c2dc 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -462,8 +462,9 @@ STATIC void btstack_packet_handler_read(uint8_t packet_type, uint16_t channel, u if (!conn) { return; } - mp_bluetooth_gattc_on_read_write_status(MP_BLUETOOTH_IRQ_GATTC_READ_DONE, conn_handle, conn->pending_value_handle, status); + uint16_t value_handle = conn->pending_value_handle; conn->pending_value_handle = 0xffff; + mp_bluetooth_gattc_on_read_write_status(MP_BLUETOOTH_IRQ_GATTC_READ_DONE, conn_handle, value_handle, status); } else if (event_type == GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT) { DEBUG_printf(" --> gatt characteristic value query result\n"); uint16_t conn_handle = gatt_event_characteristic_value_query_result_get_handle(packet); diff --git a/tests/multi_bluetooth/ble_irq_calls.py b/tests/multi_bluetooth/ble_irq_calls.py index 131ea90929..c8c673daab 100644 --- a/tests/multi_bluetooth/ble_irq_calls.py +++ b/tests/multi_bluetooth/ble_irq_calls.py @@ -65,8 +65,9 @@ class Central: self.done = False self._conn_handle = None self._service = None - self._characteristic = None + self._characteristic_handle = None self._cccd_handle = None + self._reads_remaining = None ble.active(1) ble.irq(self._ble_event_handler) ble.gap_connect(*BDADDR) @@ -101,7 +102,8 @@ class Central: _, end_handle, value_handle, properties, uuid = data assert uuid == STATE_UUID print("characteristic found:", uuid) - self._characteristic = (end_handle, value_handle, properties) + assert self._characteristic_handle is None + self._characteristic_handle = value_handle elif event == _IRQ_GATTC_CHARACTERISTIC_DONE: start_handle, end_handle = self._service @@ -128,17 +130,21 @@ class Central: elif event == _IRQ_GATTC_WRITE_DONE: conn_handle, _, result = data print("CCCD write result:", result) - _, state_handle, _ = self._characteristic print("issue gattc_read") - ble.gattc_read(self._conn_handle, state_handle) + self._reads_remaining = 2 + ble.gattc_read(self._conn_handle, self._characteristic_handle) elif event == _IRQ_GATTC_READ_RESULT: _, _, char_data = data print("gattc_read result:", bytes(char_data)) elif event == _IRQ_GATTC_READ_DONE: - self.done = True - ble.gap_disconnect(self._conn_handle) + self._reads_remaining -= 1 + if self._reads_remaining > 0: + ble.gattc_read(self._conn_handle, self._characteristic_handle) + else: + self.done = True + ble.gap_disconnect(self._conn_handle) class Peripheral: diff --git a/tests/multi_bluetooth/ble_irq_calls.py.exp b/tests/multi_bluetooth/ble_irq_calls.py.exp index 85d2f585ad..d655c507d3 100644 --- a/tests/multi_bluetooth/ble_irq_calls.py.exp +++ b/tests/multi_bluetooth/ble_irq_calls.py.exp @@ -3,6 +3,7 @@ peripheral start _IRQ_CENTRAL_CONNECT _IRQ_MTU_EXCHANGED _IRQ_GATTS_READ_REQUEST +_IRQ_GATTS_READ_REQUEST _IRQ_CENTRAL_DISCONNECT --- instance1 --- central start @@ -27,5 +28,8 @@ issue gattc_read _IRQ_GATTC_READ_RESULT gattc_read result: b'' _IRQ_GATTC_READ_DONE +_IRQ_GATTC_READ_RESULT +gattc_read result: b'' +_IRQ_GATTC_READ_DONE _IRQ_PERIPHERAL_DISCONNECT connection closed