@@ -107,12 +107,18 @@ STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
107107}
108108
109109STATIC bool packet_buffer_on_ble_client_evt (ble_evt_t * ble_evt , void * param ) {
110- bleio_packet_buffer_obj_t * self = (bleio_packet_buffer_obj_t * ) param ;
110+ const uint16_t evt_id = ble_evt -> header .evt_id ;
111+ // Check if this is a GATTC event so we can make sure the conn_handle is valid.
112+ if (evt_id < BLE_GATTC_EVT_BASE || evt_id > BLE_GATTC_EVT_LAST ) {
113+ return false;
114+ }
115+
111116 uint16_t conn_handle = ble_evt -> evt .gattc_evt .conn_handle ;
117+ bleio_packet_buffer_obj_t * self = (bleio_packet_buffer_obj_t * ) param ;
112118 if (conn_handle != self -> conn_handle ) {
113119 return false;
114120 }
115- switch (ble_evt -> header . evt_id ) {
121+ switch (evt_id ) {
116122 case BLE_GATTC_EVT_HVX : {
117123 // A remote service wrote to this characteristic.
118124 ble_gattc_evt_hvx_t * evt_hvx = & ble_evt -> evt .gattc_evt .params .hvx ;
@@ -142,9 +148,9 @@ STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
142148
143149STATIC bool packet_buffer_on_ble_server_evt (ble_evt_t * ble_evt , void * param ) {
144150 bleio_packet_buffer_obj_t * self = (bleio_packet_buffer_obj_t * ) param ;
145- uint16_t conn_handle = ble_evt -> evt .gatts_evt .conn_handle ;
146151 switch (ble_evt -> header .evt_id ) {
147152 case BLE_GATTS_EVT_WRITE : {
153+ uint16_t conn_handle = ble_evt -> evt .gatts_evt .conn_handle ;
148154 // A client wrote to this server characteristic.
149155
150156 ble_gatts_evt_write_t * evt_write = & ble_evt -> evt .gatts_evt .params .write ;
@@ -168,7 +174,7 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
168174 break ;
169175 }
170176 case BLE_GAP_EVT_DISCONNECTED : {
171- if (self -> conn_handle == conn_handle ) {
177+ if (self -> conn_handle == ble_evt -> evt . gap_evt . conn_handle ) {
172178 self -> conn_handle = BLE_CONN_HANDLE_INVALID ;
173179 }
174180 }
@@ -202,7 +208,6 @@ void common_hal_bleio_packet_buffer_construct(
202208 }
203209
204210 if (incoming ) {
205- // This is a macro.
206211 ringbuf_alloc (& self -> ringbuf , buffer_size * (sizeof (uint16_t ) + characteristic -> max_length ), false);
207212
208213 if (self -> ringbuf .buf == NULL ) {
@@ -249,7 +254,7 @@ void common_hal_bleio_packet_buffer_construct(
249254 }
250255}
251256
252- int common_hal_bleio_packet_buffer_readinto (bleio_packet_buffer_obj_t * self , uint8_t * data , size_t len ) {
257+ mp_int_t common_hal_bleio_packet_buffer_readinto (bleio_packet_buffer_obj_t * self , uint8_t * data , size_t len ) {
253258 if (ringbuf_count (& self -> ringbuf ) < 2 ) {
254259 return 0 ;
255260 }
@@ -280,7 +285,7 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
280285 if (self -> conn_handle == BLE_CONN_HANDLE_INVALID ) {
281286 return ;
282287 }
283- uint16_t packet_size = common_hal_bleio_packet_buffer_get_packet_size (self );
288+ uint16_t packet_size = common_hal_bleio_packet_buffer_get_incoming_packet_length (self );
284289 uint16_t max_size = packet_size - len ;
285290 while (max_size < self -> pending_size && self -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
286291 RUN_BACKGROUND_TASKS ;
@@ -308,26 +313,30 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
308313 }
309314}
310315
311- uint16_t common_hal_bleio_packet_buffer_get_packet_size (bleio_packet_buffer_obj_t * self ) {
312- uint16_t mtu ;
313- if (self -> conn_handle == BLE_CONN_HANDLE_INVALID ) {
314- return 0 ;
315- }
316- bleio_connection_internal_t * connection ;
317- for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
318- connection = & bleio_connections [i ];
319- if (connection -> conn_handle == self -> conn_handle ) {
320- break ;
316+ mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length (bleio_packet_buffer_obj_t * self ) {
317+ // If this PacketBuffer is being used for NOTIFY or INDICATE from
318+ // a remote service, the maximum size is what can be sent in one
319+ // BLE packet. But we must be connected to know that value.
320+ //
321+ // Otherwise it can be a long as the characteristic
322+ // will permit, whether or not we're connected.
323+
324+ if (self -> characteristic != NULL &&
325+ self -> characteristic -> service != NULL &&
326+ self -> characteristic -> service -> is_remote &&
327+ (common_hal_bleio_characteristic_get_properties (self -> characteristic ) &
328+ (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY )) &&
329+ self -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
330+ bleio_connection_internal_t * connection = bleio_conn_handle_to_connection (self -> conn_handle );
331+ if (connection ) {
332+ return MIN (common_hal_bleio_connection_get_max_packet_length (connection ),
333+ self -> characteristic -> max_length );
321334 }
335+ // There's no current connection, so we don't know the MTU, and
336+ // we can't tell what the largest incoming packet length would be.
337+ return -1 ;
322338 }
323- if (connection -> mtu == 0 ) {
324- mtu = BLE_GATT_ATT_MTU_DEFAULT ;
325- }
326- if (self -> characteristic -> max_length > mtu ) {
327- mtu = self -> characteristic -> max_length ;
328- }
329- uint16_t att_overhead = 3 ;
330- return mtu - att_overhead ;
339+ return self -> characteristic -> max_length ;
331340}
332341
333342bool common_hal_bleio_packet_buffer_deinited (bleio_packet_buffer_obj_t * self ) {
0 commit comments