Skip to content

Commit 01979ac

Browse files
authored
Merge pull request #4604 from tannewt/buffer_size
Assume max characteristic size when the client
2 parents 14abea2 + 68d5839 commit 01979ac

File tree

11 files changed

+76
-26
lines changed

11 files changed

+76
-26
lines changed

devices/ble_hci/common-hal/_bleio/Characteristic.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character
7878
return self->service;
7979
}
8080

81+
size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self) {
82+
return self->max_length;
83+
}
84+
8185
size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len) {
8286
// Do GATT operations only if this characteristic has been added to a registered service.
8387
if (self->handle != BLE_GATT_HANDLE_INVALID) {

devices/ble_hci/common-hal/_bleio/PacketBuffer.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void bleio_packet_buffer_update(bleio_packet_buffer_obj_t *self, mp_buffer_info_
8181

8282
void common_hal_bleio_packet_buffer_construct(
8383
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
84-
size_t buffer_size) {
84+
size_t buffer_size, size_t max_packet_size) {
8585

8686
self->characteristic = characteristic;
8787
self->client = self->characteristic->service->is_remote;
@@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct(
101101
}
102102

103103
if (incoming) {
104-
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
104+
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size), false)) {
105105
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
106106
}
107107
}
@@ -110,12 +110,13 @@ void common_hal_bleio_packet_buffer_construct(
110110
self->packet_queued = false;
111111
self->pending_index = 0;
112112
self->pending_size = 0;
113-
self->outgoing[0] = m_malloc(characteristic->max_length, false);
114-
self->outgoing[1] = m_malloc(characteristic->max_length, false);
113+
self->outgoing[0] = m_malloc(max_packet_size, false);
114+
self->outgoing[1] = m_malloc(max_packet_size, false);
115115
} else {
116116
self->outgoing[0] = NULL;
117117
self->outgoing[1] = NULL;
118118
}
119+
self->max_packet_size = max_packet_size;
119120

120121
bleio_characteristic_set_observer(self->characteristic, self);
121122
}
@@ -243,15 +244,16 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_
243244
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
244245
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
245246
if (connection) {
246-
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
247-
self->characteristic->max_length);
247+
return MIN(MIN(common_hal_bleio_connection_get_max_packet_length(connection),
248+
self->max_packet_size),
249+
self->characteristic->max_length);
248250
}
249251
}
250252
// There's no current connection, so we don't know the MTU, and
251253
// we can't tell what the largest outgoing packet length would be.
252254
return -1;
253255
}
254-
return self->characteristic->max_length;
256+
return MIN(self->characteristic->max_length, self->max_packet_size);
255257
}
256258

257259
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {

devices/ble_hci/common-hal/_bleio/PacketBuffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ typedef struct {
4242
// We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
4343
// We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
4444
volatile uint16_t conn_handle;
45+
uint16_t max_packet_size;
4546
uint8_t pending_index;
4647
uint8_t write_type;
4748
bool client;

locale/circuitpython.pot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ msgid "Too many displays"
21322132
msgstr ""
21332133

21342134
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
2135-
msgid "Total data to write is larger than outgoing_packet_length"
2135+
msgid "Total data to write is larger than %q"
21362136
msgstr ""
21372137

21382138
#: py/obj.c

ports/nrf/common-hal/_bleio/Characteristic.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel
131131
return 0;
132132
}
133133

134+
size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self) {
135+
return self->max_length;
136+
}
137+
134138
void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
135139
// Do GATT operations only if this characteristic has been added to a registered service.
136140
if (self->handle != BLE_GATT_HANDLE_INVALID) {

ports/nrf/common-hal/_bleio/PacketBuffer.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242

4343
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
4444
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
45-
// This shouldn't happen.
45+
// This shouldn't happen but can if our buffer size was much smaller than
46+
// the writes the client actually makes.
4647
return;
4748
}
4849
// Push all the data onto the ring buffer.
@@ -189,7 +190,7 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
189190

190191
void common_hal_bleio_packet_buffer_construct(
191192
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
192-
size_t buffer_size) {
193+
size_t buffer_size, size_t max_packet_size) {
193194

194195
self->characteristic = characteristic;
195196
self->client = self->characteristic->service->is_remote;
@@ -206,8 +207,11 @@ void common_hal_bleio_packet_buffer_construct(
206207
self->conn_handle = BLE_CONN_HANDLE_INVALID;
207208
}
208209

210+
// Cap the packet size to our implementation limits.
211+
self->max_packet_size = MIN(max_packet_size, BLE_GATTS_VAR_ATTR_LEN_MAX - 3);
212+
209213
if (incoming) {
210-
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
214+
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + self->max_packet_size), false)) {
211215
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
212216
}
213217
}
@@ -216,8 +220,8 @@ void common_hal_bleio_packet_buffer_construct(
216220
self->packet_queued = false;
217221
self->pending_index = 0;
218222
self->pending_size = 0;
219-
self->outgoing[0] = m_malloc(characteristic->max_length, false);
220-
self->outgoing[1] = m_malloc(characteristic->max_length, false);
223+
self->outgoing[0] = m_malloc(self->max_packet_size, false);
224+
self->outgoing[1] = m_malloc(self->max_packet_size, false);
221225
} else {
222226
self->outgoing[0] = NULL;
223227
self->outgoing[1] = NULL;
@@ -296,10 +300,16 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, u
296300
}
297301
uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
298302

299-
if (len + header_len > outgoing_packet_length) {
303+
uint16_t total_len = len + header_len;
304+
if (total_len > outgoing_packet_length) {
305+
// Supplied data will not fit in a single BLE packet.
306+
mp_raise_ValueError_varg(translate("Total data to write is larger than %q"), MP_QSTR_outgoing_packet_length);
307+
}
308+
if (total_len > self->max_packet_size) {
300309
// Supplied data will not fit in a single BLE packet.
301-
mp_raise_ValueError(translate("Total data to write is larger than outgoing_packet_length"));
310+
mp_raise_ValueError_varg(translate("Total data to write is larger than %q"), MP_QSTR_max_packet_size);
302311
}
312+
outgoing_packet_length = MIN(outgoing_packet_length, self->max_packet_size);
303313

304314
if (len + self->pending_size > outgoing_packet_length) {
305315
// No room to append len bytes to packet. Wait until we get a free buffer,
@@ -390,8 +400,9 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_
390400
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
391401
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
392402
if (connection) {
393-
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
394-
self->characteristic->max_length);
403+
return MIN(MIN(common_hal_bleio_connection_get_max_packet_length(connection),
404+
self->max_packet_size),
405+
self->characteristic->max_length);
395406
}
396407
}
397408
// There's no current connection, so we don't know the MTU, and
@@ -406,11 +417,12 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_
406417
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
407418
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
408419
if (connection) {
409-
return common_hal_bleio_connection_get_max_packet_length(connection);
420+
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
421+
self->max_packet_size);
410422
}
411423
}
412424
}
413-
return self->characteristic->max_length;
425+
return MIN(self->characteristic->max_length, self->max_packet_size);
414426
}
415427

416428
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {

ports/nrf/common-hal/_bleio/PacketBuffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef struct {
4444
// We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
4545
// We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
4646
volatile uint16_t conn_handle;
47+
uint16_t max_packet_size;
4748
uint8_t pending_index;
4849
uint8_t write_type;
4950
bool client;

shared-bindings/_bleio/Characteristic.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,23 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
219219
(mp_obj_t)&mp_const_none_obj },
220220
};
221221

222+
//| max_length: int
223+
//| """The max length of this characteristic."""
224+
//|
225+
STATIC mp_obj_t bleio_characteristic_get_max_length(mp_obj_t self_in) {
226+
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
227+
228+
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_max_length(self));
229+
}
230+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_max_length_obj, bleio_characteristic_get_max_length);
231+
232+
const mp_obj_property_t bleio_characteristic_max_length_obj = {
233+
.base.type = &mp_type_property,
234+
.proxy = { (mp_obj_t)&bleio_characteristic_get_max_length_obj,
235+
(mp_obj_t)&mp_const_none_obj,
236+
(mp_obj_t)&mp_const_none_obj },
237+
};
238+
222239
//| descriptors: Descriptor
223240
//| """A tuple of :py:class:`Descriptor` objects related to this characteristic. (read-only)"""
224241
//|

shared-bindings/_bleio/Characteristic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_pro
4040
extern mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self);
4141
extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self);
4242
extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
43+
extern size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self);
4344
extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len);
4445
extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor);
4546
extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);

shared-bindings/_bleio/PacketBuffer.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
//| When we're the server, we ignore all connections besides the first to subscribe to
4545
//| notifications."""
4646
//|
47-
//| def __init__(self, characteristic: Characteristic, *, buffer_size: int) -> None:
47+
//| def __init__(self, characteristic: Characteristic, *, buffer_size: int, max_packet_size: Optional[int] = None) -> None:
4848
//| """Monitor the given Characteristic. Each time a new value is written to the Characteristic
4949
//| add the newly-written bytes to a FIFO buffer.
5050
//|
@@ -55,14 +55,17 @@
5555
//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
5656
//| in a remote Service that a Central has connected to.
5757
//| :param int buffer_size: Size of ring buffer (in packets of the Characteristic's maximum
58-
//| length) that stores incoming packets coming from the peer."""
58+
//| length) that stores incoming packets coming from the peer.
59+
//| :param int max_packet_size: Maximum size of packets. Overrides value from the characteristic.
60+
//| (Remote characteristics may not have the correct length.)"""
5961
//| ...
6062
//|
6163
STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
62-
enum { ARG_characteristic, ARG_buffer_size };
64+
enum { ARG_characteristic, ARG_buffer_size, ARG_max_packet_size };
6365
static const mp_arg_t allowed_args[] = {
6466
{ MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ },
6567
{ MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
68+
{ MP_QSTR_max_packet_size, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none}},
6669
};
6770

6871
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -79,10 +82,15 @@ STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n
7982
mp_raise_TypeError(translate("Expected a Characteristic"));
8083
}
8184

85+
size_t max_packet_size = common_hal_bleio_characteristic_get_max_length(characteristic);
86+
if (args[ARG_max_packet_size].u_obj != mp_const_none) {
87+
max_packet_size = mp_obj_get_int(args[ARG_max_packet_size].u_obj);
88+
}
89+
8290
bleio_packet_buffer_obj_t *self = m_new_obj(bleio_packet_buffer_obj_t);
8391
self->base.type = &bleio_packet_buffer_type;
8492

85-
common_hal_bleio_packet_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), buffer_size);
93+
common_hal_bleio_packet_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), buffer_size, max_packet_size);
8694

8795
return MP_OBJ_FROM_PTR(self);
8896
}
@@ -133,7 +141,7 @@ STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_
133141
enum { ARG_data, ARG_header };
134142
static const mp_arg_t allowed_args[] = {
135143
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
136-
{ MP_QSTR_header, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
144+
{ MP_QSTR_header, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none}},
137145
};
138146

139147
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -147,7 +155,7 @@ STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_
147155

148156
mp_buffer_info_t header_bufinfo;
149157
header_bufinfo.len = 0;
150-
if (args[ARG_header].u_obj != MP_OBJ_NULL) {
158+
if (args[ARG_header].u_obj != mp_const_none) {
151159
mp_get_buffer_raise(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ);
152160
}
153161

shared-bindings/_bleio/PacketBuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extern const mp_obj_type_t bleio_packet_buffer_type;
3333

3434
extern void common_hal_bleio_packet_buffer_construct(
3535
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
36-
size_t buffer_size);
36+
size_t buffer_size, size_t max_packet_size);
3737
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t *header, size_t header_len);
3838
mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len);
3939
mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self);

0 commit comments

Comments
 (0)