8000 extmod/modbluetooth: Add gap_indicate_service_changed. · micropython/micropython@fc08bd3 · GitHub
[go: up one dir, main page]

Skip to content

Commit fc08bd3

Browse files
committed
extmod/modbluetooth: Add gap_indicate_service_changed.
This function triggers an indication on the GATT service changed characteristic.
1 parent 98bd7e3 commit fc08bd3

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
@@ -746,6 +746,32 @@ Pairing and bonding
746746
should show the passkey that was provided in the ``_IRQ_PASSKEY_ACTION`` event
747747
and then respond with either ``0`` (cancel pairing), or ``1`` (accept pairing).
748748

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

750776
class UUID
751777
----------

extmod/modbluetooth.c

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

711711
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
712+
STATIC mp_obj_t bluetooth_indicate_service_changed(size_t n_args, const mp_obj_t *args) {
713+
(void)n_args;
714+
int16_t handle = -1;
715+
if (args[1] != mp_const_none) {
716+
handle = mp_obj_get_int(args[1]);
717+
}
718+
719+
uint16_t hdl_start = mp_obj_get_int(args[2]);
720+
uint16_t hdl_end = mp_obj_get_int(args[3]);
721+
722+
mp_bluetooth_indicate_service_changed(handle, hdl_start, hdl_end);
723+
return mp_const_none;
724+
}
725+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_indicate_service_changed_obj, 4, 4, bluetooth_indicate_service_changed);
726+
712727
STATIC mp_obj_t bluetooth_ble_gap_pair(mp_obj_t self_in, mp_obj_t conn_handle_in) {
713728
(void)self_in;
714729
uint16_t conn_handle = mp_obj_get_int(conn_handle_in);
@@ -946,6 +961,7 @@ STATIC const mp_rom_map_elem_t bluetooth_ble_locals_dict_table[] = {
946961
#endif
947962
{ MP_ROM_QSTR(MP_QSTR_gap_disconnect), MP_ROM_PTR(&bluetooth_ble_gap_disconnect_obj) },
948963
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
964+
{ MP_ROM_QSTR(MP_QSTR_gap_indicate_service_changed), MP_ROM_PTR(&bluetooth_indicate_service_changed_obj) },
949965
{ MP_ROM_QSTR(MP_QSTR_gap_pair), MP_ROM_PTR(&bluetooth_ble_gap_pair_obj) },
950966
{ MP_ROM_QSTR(MP_QSTR_gap_passkey), MP_ROM_PTR(&bluetooth_ble_gap_passkey_obj) },
951967
#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
@@ -1082,6 +1082,16 @@ int mp_bluetooth_set_preferred_mtu(uint16_t mtu) {
10821082
}
10831083

10841084
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
1085+
void mp_bluetooth_indicate_service_changed(int16_t conn_handle, uint16_t hdl_start, uint16_t hdl_end) {
1086+
if (conn_handle == -1) {
1087+
DEBUG_printf("mp_bluetooth_indicate_service_changed all\n");
1088+
return ble_svc_gatt_changed(hdl_start, hdl_end);
1089+
} else {
1090+
DEBUG_printf("mp_bluetooth_indicate_service_changed: conn_handle=%d\n", conn_handle);
1091+
return ble_svc_conn_gatt_changed(conn_handle, hdl_start, hdl_end);
1092+
}
1093+
}
1094+
10851095
int mp_bluetooth_gap_pair(uint16_t conn_handle) {
10861096
DEBUG_printf("mp_bluetooth_gap_pair: conn_handle=%d\n", conn_handle);
10871097
return ble_hs_err_to_errno(ble_gap_security_initiate(conn_handle));

0 commit comments

Comments
 (0)
0