Skip to content

Commit 88ef740

Browse files
committed
extmod/modbluetooth: Add gap_indicate_service_changed.
This function triggers an indication on the GATT service changed characteristic.
1 parent 27b7bf3 commit 88ef740

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

docs/library/bluetooth.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,32 @@ Pairing and bonding
749749
should show the passkey that was provided in the ``_IRQ_PASSKEY_ACTION`` event
750750
and then respond with either ``0`` (cancel pairing), or ``1`` (accept pairing).
751751

752+
.. method:: BLE.gap_indicate_service_changed(conn_handle, handle_start, handle_end, /)
753+
754+
When a client is bonded to a server it will typically cache the results of the discovery
755+
process to speed up future connections. If the services/characteristic handles change on
756+
the server in future a previously-bonded client may not be able to communicate correctly
757+
as it will be using the previously cached handles.
758+
This function can be run on the server to send an indication to the client that handles
759+
have changed and trigger service discovery on the client.
760+
761+
If ``conn_handle`` is None, then all connected devices will be indicated. If CCCD bonding
762+
is supported then any un-connected bonded devices will automatically be indicated the next
763+
time they connect.
764+
765+
The ``handle_start`` and ``handle_end`` arguments can be used to specify the range of
766+
characteristics that have changed, or typically ``handle_start=0x0000, handle_end=0xFFFF``
767+
will be used to discover all again.
768+
769+
Note: with an iOS client it's been seen that if this function is called greater than ~100ms
770+
after a new connection is established the connection can be dropped, or the characteristics
771+
covered by the declared range will lock up and be no longer readable, so it's important to
772+
send this command within the first few ms after a connection is made.
773+
774+
Alternatively, it appears that if the start and end handles are both set to ``0x0000``,
775+
the lock-up doesn't occur regardless of when the call is made. Android clients appear to
776+
accept the null handles as a re-discover all, though the BLE spec makes no mention of this.
777+
752778

753779
class UUID
754780
----------

extmod/modbluetooth.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,21 @@ static mp_obj_t bluetooth_ble_gap_disconnect(mp_obj_t self_in, mp_obj_t conn_han
710710
static MP_DEFINE_CONST_FUN_OBJ_2(bluetooth_ble_gap_disconnect_obj, bluetooth_ble_gap_disconnect);
711711

712712
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
713+
static mp_obj_t bluetooth_indicate_service_changed(size_t n_args, const mp_obj_t *args) {
714+
(void)n_args;
715+
int16_t handle = -1;
716+
if (args[1] != mp_const_none) {
717+
handle = mp_obj_get_int(args[1]);
718+
}
719+
720+
uint16_t hdl_start = mp_obj_get_int(args[2]);
721+
uint16_t hdl_end = mp_obj_get_int(args[3]);
722+
723+
mp_bluetooth_indicate_service_changed(handle, hdl_start, hdl_end);
724+
return mp_const_none;
725+
}
726+
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_indicate_service_changed_obj, 4, 4, bluetooth_indicate_service_changed);
727+
713728
static mp_obj_t bluetooth_ble_gap_pair(mp_obj_t self_in, mp_obj_t conn_handle_in) {
714729
(void)self_in;
715730
uint16_t conn_handle = mp_obj_get_int(conn_handle_in);
@@ -944,6 +959,7 @@ static const mp_rom_map_elem_t bluetooth_ble_locals_dict_table[] = {
944959
#endif
945960
{ MP_ROM_QSTR(MP_QSTR_gap_disconnect), MP_ROM_PTR(&bluetooth_ble_gap_disconnect_obj) },
946961
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
962+
{ MP_ROM_QSTR(MP_QSTR_gap_indicate_service_changed), MP_ROM_PTR(&bluetooth_indicate_service_changed_obj) },
947963
{ MP_ROM_QSTR(MP_QSTR_gap_pair), MP_ROM_PTR(&bluetooth_ble_gap_pair_obj) },
948964
{ MP_ROM_QSTR(MP_QSTR_gap_passkey), MP_ROM_PTR(&bluetooth_ble_gap_passkey_obj) },
949965
#endif

extmod/modbluetooth.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ int mp_bluetooth_get_preferred_mtu(void);
355355
int mp_bluetooth_set_preferred_mtu(uint16_t mtu);
356356

357357
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
358+
// Send an indication on the service changed characteristic, send -1 on conn_handle to indicate to all devices.
359+
void mp_bluetooth_indicate_service_changed(int16_t conn_handle, uint16_t hdl_start, uint16_t hdl_end);
360+
358361
// Initiate pairing on the specified connection.
359362
int mp_bluetooth_gap_pair(uint16_t conn_handle);
360363

extmod/nimble/modbluetooth_nimble.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,16 @@ int mp_bluetooth_set_preferred_mtu(uint16_t mtu) {
11061106
}
11071107

11081108
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
1109+
void mp_bluetooth_indicate_service_changed(int16_t conn_handle, uint16_t hdl_start, uint16_t hdl_end) {
1110+
if (conn_handle == -1) {
1111+
DEBUG_printf("mp_bluetooth_indicate_service_changed all\n");
1112+
return ble_svc_gatt_changed(hdl_start, hdl_end);
1113+
} else {
1114+
DEBUG_printf("mp_bluetooth_indicate_service_changed: conn_handle=%d\n", conn_handle);
1115+
return ble_svc_conn_gatt_changed(conn_handle, hdl_start, hdl_end);
1116+
}
1117+
}
1118+
11091119
int mp_bluetooth_gap_pair(uint16_t conn_handle) {
11101120
DEBUG_printf("mp_bluetooth_gap_pair: conn_handle=%d\n", conn_handle);
11111121
return ble_hs_err_to_errno(ble_gap_security_initiate(conn_handle));

0 commit comments

Comments
 (0)