aboutsummaryrefslogtreecommitdiff
path: root/extmod/modbluetooth.c
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2020-05-28 10:51:45 +1000
committerDamien George <damien.p.george@gmail.com>2020-06-05 14:11:46 +1000
commit8b7ae4e099c18d839d1999c49dd8a1795bf9d1ae (patch)
treef05fcb52735534ee6c44a48024ad059dac0a21c4 /extmod/modbluetooth.c
parent1cad63c0bcf63b12436a1438aa8512cd05ad4da0 (diff)
extmod/modbluetooth: Support bigger characteristic values.
The ring buffer previously used a single unsigned byte field to save the length, meaning that it would overflow for large characteristic value responses. With this commit it now use a 16-bit length instead and has code to explicitly truncate at UINT16_MAX (although this should be impossible to achieve in practice).
Diffstat (limited to 'extmod/modbluetooth.c')
-rw-r--r--extmod/modbluetooth.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c
index 34d18b0b7..da40a1548 100644
--- a/extmod/modbluetooth.c
+++ b/extmod/modbluetooth.c
@@ -835,7 +835,7 @@ STATIC void ringbuf_extract(ringbuf_t *ringbuf, mp_obj_tuple_t *data_tuple, size
// put more than bt->irq_data_data_alloc bytes into the ringbuf, because
// that's what's available here in bt->irq_data_bytes.
if (bytes_data) {
- bytes_data->len = ringbuf_get(ringbuf);
+ bytes_data->len = ringbuf_get16(ringbuf);
for (size_t i = 0; i < bytes_data->len; ++i) {
// cast away const, this is actually bt->irq_data_bytes.
((uint8_t *)bytes_data->data)[i] = ringbuf_get(ringbuf);
@@ -1001,7 +1001,7 @@ void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uin
MICROPY_PY_BLUETOOTH_ENTER
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
data_len = MIN(o->irq_data_data_alloc, data_len);
- if (enqueue_irq(o, 1 + 6 + 1 + 1 + 1 + data_len, MP_BLUETOOTH_IRQ_SCAN_RESULT)) {
+ if (enqueue_irq(o, 1 + 6 + 1 + 1 + 2 + data_len, MP_BLUETOOTH_IRQ_SCAN_RESULT)) {
ringbuf_put(&o->ringbuf, addr_type);
for (int i = 0; i < 6; ++i) {
ringbuf_put(&o->ringbuf, addr[i]);
@@ -1010,7 +1010,9 @@ void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, uin
ringbuf_put(&o->ringbuf, adv_type);
// Note conversion of int8_t rssi to uint8_t. Must un-convert on the way out.
ringbuf_put(&o->ringbuf, (uint8_t)rssi);
- ringbuf_put(&o->ringbuf, data_len);
+ // Length field is 16-bit.
+ data_len = MIN(UINT16_MAX, data_len);
+ ringbuf_put16(&o->ringbuf, data_len);
for (size_t i = 0; i < data_len; ++i) {
ringbuf_put(&o->ringbuf, data[i]);
}
@@ -1069,10 +1071,12 @@ size_t mp_bluetooth_gattc_on_data_available_start(uint8_t event, uint16_t conn_h
*atomic_state_out = atomic_state;
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
data_len = MIN(o->irq_data_data_alloc, data_len);
- if (enqueue_irq(o, 2 + 2 + 1 + data_len, event)) {
+ if (enqueue_irq(o, 2 + 2 + 2 + data_len, event)) {
ringbuf_put16(&o->ringbuf, conn_handle);
ringbuf_put16(&o->ringbuf, value_handle);
- ringbuf_put(&o->ringbuf, data_len);
+ // Length field is 16-bit.
+ data_len = MIN(UINT16_MAX, data_len);
+ ringbuf_put16(&o->ringbuf, data_len);
return data_len;
} else {
return 0;