extmod/modbluetooth: Add send_update arg to gatts_write.
This allows the write to trigger a notification or indication, but only to subscribed clients. This is different to gatts_notify/gatts_indicate, which will unconditionally notify/indicate. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
parent
5733c49174
commit
1d9e489af3
@ -485,10 +485,14 @@ writes from a client to a given characteristic, use
|
||||
Reads the local value for this handle (which has either been written by
|
||||
:meth:`gatts_write <BLE.gatts_write>` or by a remote client).
|
||||
|
||||
.. method:: BLE.gatts_write(value_handle, data, /)
|
||||
.. method:: BLE.gatts_write(value_handle, data, send_update=False, /)
|
||||
|
||||
Writes the local value for this handle, which can be read by a client.
|
||||
|
||||
If *send_update* is ``True``, then any subscribed clients will be notified
|
||||
(or indicated, depending on what they're subscribed to and which operations
|
||||
the characteristic supports) about this write.
|
||||
|
||||
.. method:: BLE.gatts_notify(conn_handle, value_handle, data=None, /)
|
||||
|
||||
Sends a notification request to a connected client.
|
||||
@ -499,17 +503,20 @@ writes from a client to a given characteristic, use
|
||||
Otherwise, if *data* is ``None``, then the current local value (as
|
||||
set with :meth:`gatts_write <BLE.gatts_write>`) will be sent.
|
||||
|
||||
**Note:** The notification will be sent regardless of the subscription
|
||||
status of the client to this characteristic.
|
||||
|
||||
.. method:: BLE.gatts_indicate(conn_handle, value_handle, /)
|
||||
|
||||
Sends an indication request to a connected client.
|
||||
|
||||
**Note:** This does not currently support sending a custom value, it will
|
||||
always send the current local value (as set with :meth:`gatts_write
|
||||
<BLE.gatts_write>`).
|
||||
Sends an indication request containing the characteristic's current value to
|
||||
a connected client.
|
||||
|
||||
On acknowledgment (or failure, e.g. timeout), the
|
||||
``_IRQ_GATTS_INDICATE_DONE`` event will be raised.
|
||||
|
||||
**Note:** The indication will be sent regardless of the subscription
|
||||
status of the client to this characteristic.
|
||||
|
||||
.. method:: BLE.gatts_set_buffer(value_handle, len, append=False, /)
|
||||
|
||||
Sets the internal buffer size for a value in bytes. This will limit the
|
||||
|
@ -1085,11 +1085,14 @@ int mp_bluetooth_gatts_read(uint16_t value_handle, uint8_t **value, size_t *valu
|
||||
return mp_bluetooth_gatts_db_read(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
}
|
||||
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len) {
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len, bool send_update) {
|
||||
DEBUG_printf("mp_bluetooth_gatts_write\n");
|
||||
if (!mp_bluetooth_is_active()) {
|
||||
return ERRNO_BLUETOOTH_NOT_ACTIVE;
|
||||
}
|
||||
if (send_update) {
|
||||
return MP_EOPNOTSUPP;
|
||||
}
|
||||
return mp_bluetooth_gatts_db_write(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
}
|
||||
|
||||
|
@ -717,15 +717,17 @@ STATIC mp_obj_t bluetooth_ble_gatts_read(mp_obj_t self_in, mp_obj_t value_handle
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(bluetooth_ble_gatts_read_obj, bluetooth_ble_gatts_read);
|
||||
|
||||
STATIC mp_obj_t bluetooth_ble_gatts_write(mp_obj_t self_in, mp_obj_t value_handle_in, mp_obj_t data) {
|
||||
(void)self_in;
|
||||
STATIC mp_obj_t bluetooth_ble_gatts_write(size_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t bufinfo = {0};
|
||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
||||
int err = mp_bluetooth_gatts_write(mp_obj_get_int(value_handle_in), bufinfo.buf, bufinfo.len);
|
||||
bluetooth_handle_errno(err);
|
||||
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
|
||||
bool send_update = false;
|
||||
if (n_args > 3) {
|
||||
send_update = mp_obj_is_true(args[3]);
|
||||
}
|
||||
bluetooth_handle_errno(mp_bluetooth_gatts_write(mp_obj_get_int(args[1]), bufinfo.buf, bufinfo.len, send_update));
|
||||
return MP_OBJ_NEW_SMALL_INT(bufinfo.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(bluetooth_ble_gatts_write_obj, bluetooth_ble_gatts_write);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gatts_write_obj, 3, 4, bluetooth_ble_gatts_write);
|
||||
|
||||
STATIC mp_obj_t bluetooth_ble_gatts_notify(size_t n_args, const mp_obj_t *args) {
|
||||
mp_int_t conn_handle = mp_obj_get_int(args[1]);
|
||||
|
@ -334,8 +334,8 @@ int mp_bluetooth_gatts_register_service_end(void);
|
||||
|
||||
// Read the value from the local gatts db (likely this has been written by a central).
|
||||
int mp_bluetooth_gatts_read(uint16_t value_handle, uint8_t **value, size_t *value_len);
|
||||
// Write a value to the local gatts db (ready to be queried by a central).
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len);
|
||||
// Write a value to the local gatts db (ready to be queried by a central). Optionally send notifications/indications.
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len, bool send_update);
|
||||
// Notify the central that it should do a read.
|
||||
int mp_bluetooth_gatts_notify(uint16_t conn_handle, uint16_t value_handle);
|
||||
// Notify the central, including a data payload. (Note: does not set the gatts db value).
|
||||
|
@ -512,6 +512,11 @@ STATIC int central_gap_event_cb(struct ble_gap_event *event, void *arg) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case BLE_GAP_EVENT_SUBSCRIBE: {
|
||||
DEBUG_printf("central_gap_event_cb: subscribe: handle=%d, reason=%d notify=%d indicate=%d \n", event->subscribe.attr_handle, event->subscribe.reason, event->subscribe.cur_notify, event->subscribe.cur_indicate);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return commmon_gap_event_cb(event, arg);
|
||||
@ -1004,11 +1009,15 @@ int mp_bluetooth_gatts_read(uint16_t value_handle, uint8_t **value, size_t *valu
|
||||
return mp_bluetooth_gatts_db_read(MP_STATE_PORT(bluetooth_nimble_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
}
|
||||
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len) {
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len, bool send_update) {
|
||||
if (!mp_bluetooth_is_active()) {
|
||||
return ERRNO_BLUETOOTH_NOT_ACTIVE;
|
||||
}
|
||||
return mp_bluetooth_gatts_db_write(MP_STATE_PORT(bluetooth_nimble_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
int err = mp_bluetooth_gatts_db_write(MP_STATE_PORT(bluetooth_nimble_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
if (err == 0 && send_update) {
|
||||
ble_gatts_chr_updated(value_handle);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// TODO: Could use ble_gatts_chr_updated to send to all subscribed centrals.
|
||||
|
@ -308,10 +308,13 @@ int mp_bluetooth_gatts_read(uint16_t value_handle, uint8_t **value, size_t *valu
|
||||
return mp_bluetooth_gatts_db_read(MP_STATE_PORT(bluetooth_zephyr_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
}
|
||||
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len) {
|
||||
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len, bool send_update) {
|
||||
if (!mp_bluetooth_is_active()) {
|
||||
return ERRNO_BLUETOOTH_NOT_ACTIVE;
|
||||
}
|
||||
if (send_update) {
|
||||
return MP_EOPNOTSUPP;
|
||||
}
|
||||
return mp_bluetooth_gatts_db_write(MP_STATE_PORT(bluetooth_zephyr_root_pointers)->gatts_db, value_handle, value, value_len);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user