Skip to content

Commit 7444b7a

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

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

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

742768
class UUID
743769
----------

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_passkey(size_t n_args, const mp_obj_t *args) {
710710
return bluetooth_handle_errno(mp_bluetooth_gap_passkey(conn_handle, action, passkey));
711711
}
712712
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_passkey_obj, 4, 4, bluetooth_ble_gap_passkey);
713+
714+
STATIC mp_obj_t bluetooth_indicate_service_changed(size_t n_args, const mp_obj_t *args) {
715+
(void)n_args;
716+
int16_t handle = -1;
717+
if (args[1] != mp_const_none) {
718+
handle = mp_obj_get_int(args[1]);
719+
}
720+
721+
uint16_t hdl_start = mp_obj_get_int(args[2]);
722+
uint16_t hdl_end = mp_obj_get_int(args[3]);
723+
724+
mp_bluetooth_indicate_service_changed(handle, hdl_start, hdl_end);
725+
return mp_const_none;
726+
}
727+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_indicate_service_changed_obj, 4, 4, bluetooth_indicate_service_changed);
713728
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
714729

715730
// ----------------------------------------------------------------------------
@@ -935,6 +950,7 @@ STATIC const mp_rom_map_elem_t bluetooth_ble_locals_dict_table[] = {
935950
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
936951
{ MP_ROM_QSTR(MP_QSTR_gap_pair), MP_ROM_PTR(&bluetooth_ble_gap_pair_obj) },
937952
{ MP_ROM_QSTR(MP_QSTR_gap_passkey), MP_ROM_PTR(&bluetooth_ble_gap_passkey_obj) },
953+
{ MP_ROM_QSTR(MP_QSTR_gap_indicate_service_changed), MP_ROM_PTR(&bluetooth_indicate_service_changed_obj) },
938954
#endif
939955
// GATT Server
940956
{ MP_ROM_QSTR(MP_QSTR_gatts_register_services), MP_ROM_PTR(&bluetooth_ble_gatts_register_services_obj) },

extmod/modbluetooth.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,9 @@ int mp_bluetooth_gap_pair(uint16_t conn_handle);
360360

361361
// Respond to a pairing request.
362362
int mp_bluetooth_gap_passkey(uint16_t conn_handle, uint8_t action, mp_int_t passkey);
363+
364+
// Send an indication on the service changed characteristic, send -1 on conn_handle to indicate to all devices.
365+
void mp_bluetooth_indicate_service_changed(int16_t conn_handle, uint16_t hdl_start, uint16_t hdl_end);
363366
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
364367

365368
#if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE

extmod/nimble/modbluetooth_nimble.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,16 @@ int mp_bluetooth_gap_passkey(uint16_t conn_handle, uint8_t action, mp_int_t pass
11131113
DEBUG_printf("mp_bluetooth_gap_passkey: injecting IO: conn_handle=%d, action=%d, passkey=" UINT_FMT ", numcmp_accept=%d\n", conn_handle, io.action, (mp_uint_t)io.passkey, io.numcmp_accept);
11141114
return ble_hs_err_to_errno(ble_sm_inject_io(conn_handle, &io));
11151115
}
1116+
1117+
void mp_bluetooth_indicate_service_changed(int16_t conn_handle, uint16_t hdl_start, uint16_t hdl_end) {
1118+
if (conn_handle == -1) {
1119+
DEBUG_printf("mp_bluetooth_indicate_service_changed all\n");
1120+
return ble_svc_gatt_changed(hdl_start, hdl_end);
1121+
} else {
1122+
DEBUG_printf("mp_bluetooth_indicate_service_changed: conn_handle=%d\n", conn_handle);
1123+
return ble_svc_conn_gatt_changed(conn_handle, hdl_start, hdl_end);
1124+
}
1125+
}
11161126
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
11171127

11181128
#if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy