8000 extmod/modbluetooth: Simplify management of pre-allocated event data. · rlangoy/micropython@e873d35 · GitHub
[go: up one dir, main page]

Skip to content

Commit e873d35

Browse files
jimmodpgeorge
authored andcommitted
extmod/modbluetooth: Simplify management of pre-allocated event data.
The address, adv payload and uuid fields of the event are pre-allocated by modbluetooth, and reused in the IRQ handler. Simplify this and move all storage into the `mp_obj_bluetooth_ble_t` instance. This now allows users to hold on to a reference to these instances without crashes, although they may be overwritten by future events. If they want to hold onto the values longer term they need to copy them.
1 parent fbb7646 commit e873d35

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

docs/library/ubluetooth.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ Event Handling
5252
The optional *trigger* parameter allows you to set a mask of events that
5353
your program is interested in. The default is all events.
5454

55+
Note: the ``addr``, ``adv_data`` and ``uuid`` entries in the tuples are
56+
references to data managed by the :mod:`ubluetooth` module (i.e. the same
57+
instance will be re-used across multiple calls to the event handler). If
58+
your program wants to use this data outside of the handler, then it must
59+
copy them first, e.g. by using ``bytes(addr)`` or ``bluetooth.UUID(uuid)``.
60+
5561
An event handler showing all possible events::
5662

5763
def bt_irq(event, data):

extmod/modbluetooth.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ STATIC const mp_obj_type_t bluetooth_uuid_type;
5959
typedef struct {
6060
mp_obj_base_t base;
6161
mp_obj_t irq_handler;
62-
mp_obj_t irq_data_tuple;
63-
uint8_t irq_addr_bytes[6];
64-
uint8_t irq_data_bytes[MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_BYTES_LEN];
65-
mp_obj_t irq_data_uuid;
6662
uint16_t irq_trigger;
63+
mp_obj_t irq_data_tuple;
64+
uint8_t irq_data_addr_bytes[6];
65+
uint8_t irq_data_data_bytes[MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_BYTES_LEN];
66+
mp_obj_str_t irq_data_addr;
67+
mp_obj_str_t irq_data_data;
68+
mp_obj_bluetooth_uuid_t irq_data_uuid;
6769
ringbuf_t ringbuf;
6870
} mp_obj_bluetooth_ble_t;
6971

@@ -234,16 +236,25 @@ STATIC const mp_obj_type_t bluetooth_uuid_type = {
234236

235237
STATIC mp_obj_t bluetooth_ble_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
236238
if (MP_STATE_VM(bluetooth) == MP_OBJ_NULL) {
237-
mp_obj_bluetooth_ble_t *o = m_new_obj(mp_obj_bluetooth_ble_t);
239+
mp_obj_bluetooth_ble_t *o = m_new0(mp_obj_bluetooth_ble_t, 1);
238240
o->base.type = &bluetooth_ble_type;
241+
239242
o->irq_handler = mp_const_none;
243+
o->irq_trigger = 0;
244+
240245
// Pre-allocate the event data tuple to prevent needing to allocate in the IRQ handler.
241246
o->irq_data_tuple = mp_obj_new_tuple(MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_TUPLE_LEN, NULL);
242-
mp_obj_bluetooth_uuid_t *uuid = m_new_obj(mp_obj_bluetooth_uuid_t);
243-
uuid->base.type = &bluetooth_uuid_type;
244-
o->irq_data_uuid = MP_OBJ_FROM_PTR(uuid);
245-
o->irq_trigger = 0;
247+
248+
// Pre-allocated buffers for address, payload and uuid.
249+
o->irq_data_addr.base.type = &mp_type_bytes;
250+
o->irq_data_addr.data = o->irq_data_addr_bytes;
251+
o->irq_data_data.base.type = &mp_type_bytes;
252+
o->irq_data_data.data = o->irq_data_data_bytes;
253+
o->irq_data_uuid.base.type = &bluetooth_uuid_type;
254+
255+
// Allocate the ringbuf. TODO: Consider making the size user-specified.
246256
ringbuf_alloc(&o->ringbuf, MICROPY_PY_BLUETOOTH_RINGBUF_SIZE);
257+
247258
MP_STATE_VM(bluetooth) = MP_OBJ_FROM_PTR(o);
248259
}
249260
return MP_STATE_VM(bluetooth);
@@ -764,36 +775,31 @@ STATIC mp_obj_t bluetooth_ble_invoke_irq(mp_obj_t none_in) {
764775
mp_obj_t handler = handler = o->irq_handler;
765776
mp_obj_tuple_t *data_tuple = MP_OBJ_TO_PTR(o->irq_data_tuple);
766777

767-
// Some events need to pass bytes objects to their handler, using the
768-
// pre-allocated bytes array.
769-
mp_obj_str_t irq_data_bytes_addr = {{&mp_type_bytes}, 0, 6, o->irq_addr_bytes};
770-
mp_obj_str_t irq_data_bytes_data = {{&mp_type_bytes}, 0, 0, o->irq_data_bytes};
771-
772778
if (event == MP_BLUETOOTH_IRQ_CENTRAL_CONNECT || event == MP_BLUETOOTH_IRQ_PERIPHERAL_CONNECT || event == MP_BLUETOOTH_IRQ_CENTRAL_DISCONNECT || event == MP_BLUETOOTH_IRQ_PERIPHERAL_DISCONNECT) {
773779
// conn_handle, addr_type, addr
774-
ringbuf_extract(&o->ringbuf, data_tuple, 1, 1, &irq_data_bytes_addr, 0, 0, NULL, NULL);
780+
ringbuf_extract(&o->ringbuf, data_tuple, 1, 1, &o->irq_data_addr, 0, 0, NULL, NULL);
775781
} else if (event == MP_BLUETOOTH_IRQ_GATTS_WRITE) {
776782
// conn_handle, value_handle
777783
ringbuf_extract(&o->ringbuf, data_tuple, 2, 0, NULL, 0, 0, NULL, NULL);
778784
#if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE
779785
} else if (event == MP_BLUETOOTH_IRQ_SCAN_RESULT) {
780786
// addr_type, addr, connectable, rssi, adv_data
781-
ringbuf_extract(&o->ringbuf, data_tuple, 0, 1, &irq_data_bytes_addr, 1, 1, NULL, &irq_data_bytes_data);
787+
ringbuf_extract(&o->ringbuf, data_tuple, 0, 1, &o->irq_data_addr, 1, 1, NULL, &o->irq_data_data);
782788
} else if (event == MP_BLUETOOTH_IRQ_SCAN_COMPLETE) {
783789
// No params required.
784790
data_tuple->len = 0;
785791
} else if (event == MP_BLUETOOTH_IRQ_GATTC_SERVICE_RESULT) {
786792
// conn_handle, start_handle, end_handle, uuid
787-
ringbuf_extract(&o->ringbuf, data_tuple, 3, 0, NULL, 0, 0, MP_OBJ_TO_PTR(o->irq_data_uuid), NULL);
793+
ringbuf_extract(&o->ringbuf, data_tuple, 3, 0, NULL, 0, 0, &o->irq_data_uuid, NULL);
788794
} else if (event == MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_RESULT) {
789795
// conn_handle, def_handle, value_handle, properties, uuid
790-
ringbuf_extract(&o->ringbuf, data_tuple, 3, 1, NULL, 0, 0, MP_OBJ_TO_PTR(o->irq_data_uuid), NULL);
796+
ringbuf_extract(&o->ringbuf, data_tuple, 3, 1, NULL, 0, 0, &o->irq_data_uuid, NULL);
791797
} else if (event == MP_BLUETOOTH_IRQ_GATTC_DESCRIPTOR_RESULT) {
792798
// conn_handle, handle, uuid
793-
ringbuf_extract(&o->ringbuf, data_tuple, 2, 0, NULL, 0, 0, MP_OBJ_TO_PTR(o->irq_data_uuid), NULL);
799+
ringbuf_extract(&o->ringbuf, data_tuple, 2, 0, NULL, 0, 0, &o->irq_data_uuid, NULL);
794800
} else if (event == MP_BLUETOOTH_IRQ_GATTC_READ_RESULT || event == MP_BLUETOOTH_IRQ_GATTC_NOTIFY || event == MP_BLUETOOTH_IRQ_GATTC_INDICATE) {
795801
// conn_handle, value_handle, data
796-
ringbuf_extract(&o->ringbuf, data_tuple, 2, 0, NULL, 0, 0, NULL, &irq_data_bytes_data);
802+
ringbuf_extract(&o->ringbuf, data_tuple, 2, 0, NULL, 0, 0, NULL, &o->irq_data_data);
797803
} else if (event == MP_BLUETOOTH_IRQ_GATTC_WRITE_STATUS) {
798804
// conn_handle, value_handle, status
799805
ringbuf_extract(&o->ringbuf, data_tuple, 3, 0, NULL, 0, 0, NULL, NULL);

0 commit comments

Comments
 (0)
0