Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 1b3e2e4

Browse files
authored
Merge pull request #121 from semireg/feature/ble-char-subscribe-callback
Add Bluetooth.CHAR_SUBSCRIBE_EVENT
2 parents 70fb03c + 2dcdffe commit 1b3e2e4

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

docs/library/network.Bluetooth.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,18 @@ Constants
289289

290290
Characteristic properties (bit values that can be combined)
291291

292+
.. data:: Bluetooth.CHAR_CONFIG_NOTIFY
293+
Bluetooth.CHAR_CONFIG_INDICATE
294+
295+
Characteristic configurations representing the current value of the characteristic's configuration descriptor.
296+
292297
.. data:: Bluetooth.CHAR_READ_EVENT
293298
Bluetooth.CHAR_WRITE_EVENT
294299
Bluetooth.NEW_ADV_EVENT
295300
Bluetooth.CLIENT_CONNECTED
296301
Bluetooth.CLIENT_DISCONNECTED
297302
Bluetooth.CHAR_NOTIFY_EVENT
303+
Bluetooth.CHAR_SUBSCRIBE_EVENT
298304

299305
Charactertistic callback events
300306

@@ -418,6 +424,12 @@ The following class allows you to manage characteristics from a **Client**.
418424

419425
characteristic.properties()
420426

427+
.. method:: characteristic.config()
428+
429+
Returns an integer indicating the client configuration of the characteristic. Configurations are represented by bit values that can be ORed together. The configuration is often updated when the CHAR_SUBSCRIBE_EVENT is generated. See the constants section for more details. ::
430+
431+
characteristic.config()
432+
421433
.. method:: characteristic.read()
422434

423435
Read the value of the characteristic. For now it always returns a bytes object representing the characteristic value. In the future a specific type (integer, string, bytes) will be returned depending on the characteristic in question. ::
@@ -491,7 +503,7 @@ The following class allows you to manage **Server** characteristics.
491503

492504
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
493505

494-
- ``trigger`` can be either ``Bluetooth.CHAR_READ_EVENT`` or ``Bluetooth.CHAR_WRITE_EVENT``.
506+
- ``trigger`` can be either ``Bluetooth.CHAR_READ_EVENT`` or ``Bluetooth.CHAR_WRITE_EVENT`` or ``Bluetooth.CHAR_SUBSCRIBE_EVENT``.
495507
- ``handler`` is the function that will be executed when the callback is triggered.
496508
- ``arg`` is the argument that gets passed to the callback. If nothing is given, the characteristic object that owns the callback will be used.
497509

esp32/mods/modbt.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#define MOD_BT_GATTS_WRITE_EVT (0x0010)
7070
#define MOD_BT_GATTC_NOTIFY_EVT (0x0020)
7171
#define MOD_BT_GATTC_INDICATE_EVT (0x0040)
72+
#define MOD_BT_GATTS_SUBSCRIBE_EVT (0x0080)
7273

7374
/******************************************************************************
7475
DEFINE PRIVATE TYPES
@@ -197,6 +198,7 @@ typedef struct {
197198
uint32_t events;
198199
uint32_t trans_id;
199200
bool read_request;
201+
uint16_t config;
200202
} bt_gatts_char_obj_t;
201203

202204
/******************************************************************************
@@ -566,6 +568,13 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
566568
} else { // descriptor
567569
if (attr_obj->uuid.len == ESP_UUID_LEN_16 && attr_obj->uuid.uuid.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) {
568570
uint16_t value = param->write.value[1] << 8 | param->write.value[0];
571+
bt_gatts_char_obj_t *char_obj = (bt_gatts_char_obj_t *)attr_obj->parent;
572+
char_obj->config = value;
573+
char_obj->events |= MOD_BT_GATTS_SUBSCRIBE_EVT;
574+
if (char_obj->trigger & MOD_BT_GATTS_SUBSCRIBE_EVT) {
575+
mp_irq_queue_interrupt(gatts_char_callback_handler, char_obj);
576+
}
577+
569578
if (value == 0x0001) { // notifications enabled
570579
bt_gatts_char_obj_t *char_obj = (bt_gatts_char_obj_t *)attr_obj->parent;
571580
// the size of value[] needs to be less than MTU size
@@ -1341,11 +1350,18 @@ STATIC mp_obj_t bt_characteristic_events(mp_obj_t self_in) {
13411350
}
13421351
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bt_characteristic_events_obj, bt_characteristic_events);
13431352

1353+
STATIC mp_obj_t bt_characteristic_config(mp_obj_t self_in) {
1354+
bt_gatts_char_obj_t *self = self_in;
1355+
return mp_obj_new_int(self->config);
1356+
}
1357+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bt_characteristic_config_obj, bt_characteristic_config);
1358+
13441359
STATIC const mp_map_elem_t bt_gatts_char_locals_dict_table[] = {
13451360
// instance methods
13461361
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&bt_characteristic_value_obj },
13471362
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&bt_characteristic_callback_obj },
13481363
{ MP_OBJ_NEW_QSTR(MP_QSTR_events), (mp_obj_t)&bt_characteristic_events_obj },
1364+
{ MP_OBJ_NEW_QSTR(MP_QSTR_config), (mp_obj_t)&bt_characteristic_config_obj },
13491365
};
13501366
STATIC MP_DEFINE_CONST_DICT(bt_gatts_char_locals_dict, bt_gatts_char_locals_dict_table);
13511367

@@ -1422,12 +1438,17 @@ STATIC const mp_map_elem_t bt_locals_dict_table[] = {
14221438
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROP_AUTH), MP_OBJ_NEW_SMALL_INT(ESP_GATT_CHAR_PROP_BIT_AUTH) },
14231439
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROP_EXT_PROP), MP_OBJ_NEW_SMALL_INT(ESP_GATT_CHAR_PROP_BIT_EXT_PROP) },
14241440

1441+
// Defined at https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
1442+
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_CONFIG_NOTIFY), MP_OBJ_NEW_SMALL_INT(1 << 0) },
1443+
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_CONFIG_INDICATE), MP_OBJ_NEW_SMALL_INT(1 << 1) },
1444+
14251445
{ MP_OBJ_NEW_QSTR(MP_QSTR_NEW_ADV_EVENT), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTC_ADV_EVT) },
14261446
{ MP_OBJ_NEW_QSTR(MP_QSTR_CLIENT_CONNECTED), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTS_CONN_EVT) },
14271447
{ MP_OBJ_NEW_QSTR(MP_QSTR_CLIENT_DISCONNECTED), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTS_DISCONN_EVT) },
14281448
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_READ_EVENT), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTS_READ_EVT) },
14291449
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_WRITE_EVENT), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTS_WRITE_EVT) },
14301450
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_NOTIFY_EVENT), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTC_NOTIFY_EVT) },
1451+
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_SUBSCRIBE_EVENT), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTS_SUBSCRIBE_EVT) },
14311452
// { MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_INDICATE_EVENT), MP_OBJ_NEW_SMALL_INT(MOD_BT_GATTC_INDICATE_EVT) },
14321453
};
14331454
STATIC MP_DEFINE_CONST_DICT(bt_locals_dict, bt_locals_dict_table);

0 commit comments

Comments
 (0)