@@ -259,18 +259,22 @@ STATIC mp_obj_t bluetooth_write_callback(mp_obj_t char_in) {
259
259
uint8_t value [20 ]; // maximum BLE packet size
260
260
uint16_t tail = update_buf .tail ;
261
261
size_t value_len ;
262
+ uint16_t conn_handle = MP_BT_INVALID_CONN_HANDLE ;
262
263
if (update_buf .dropped_packets ) {
263
264
// Handle dropped packet.
264
265
update_buf .dropped_packets -- ;
265
266
value_len = (size_t )-1 ;
266
267
} else {
267
268
// Copy regular incoming packet.
268
- value_len = update_buf .data [tail ++ % UPDATE_BUF_SIZE ];
269
- update_buf .tail = tail + value_len ;
269
+ size_t data_len = update_buf .data [tail ++ % UPDATE_BUF_SIZE ];
270
+ value_len = data_len - 2 ;
271
+ update_buf .tail = tail + data_len ;
270
272
if (value_len > sizeof (value )) {
271
273
// Packet was too big, only pass the first N bytes.
272
274
value_len = sizeof (value );
273
275
}
276
+ conn_handle = update_buf .data [tail ++ % UPDATE_BUF_SIZE ];
277
+ conn_handle |= update_buf .data [tail ++ % UPDATE_BUF_SIZE ] << 8 ;
274
278
for (size_t i = 0 ; i < value_len ; i ++ ) {
275
279
value [i ] = update_buf .data [tail ++ % UPDATE_BUF_SIZE ];
276
280
}
@@ -292,12 +296,25 @@ STATIC mp_obj_t bluetooth_write_callback(mp_obj_t char_in) {
292
296
if (value_len == (size_t )-1 ) {
293
297
// Unfortunately, there was a dropped packet.
294
298
// Report this event by passing None.
295
- mp_call_function_2_protected (item -> callback , MP_OBJ_FROM_PTR (item -> characteristic ), mp_const_none );
299
+ mp_obj_t args [3 ] = {
300
+ mp_const_none ,
301
+ MP_OBJ_FROM_PTR (item -> characteristic ),
302
+ mp_const_none ,
303
+ };
304
+ mp_call_function_n_kw (item -> callback , 3 , 0 , args );
296
305
} else {
297
306
// Pass the written data directly as a bytearray to the callback.
298
307
// WARNING: this array must not be modified by the callee.
299
308
mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , value_len , value };
300
- mp_call_function_2_protected (item -> callback , MP_OBJ_FROM_PTR (item -> characteristic ), MP_OBJ_FROM_PTR (& ar ));
309
+ mp_bt_device_t device = {0 };
310
+ device .base .type = & device_type ;
311
+ device .conn_handle = conn_handle ;
312
+ mp_obj_t args [3 ] = {
313
+ & device ,
314
+ MP_OBJ_FROM_PTR (item -> characteristic ),
315
+ MP_OBJ_FROM_PTR (& ar ),
316
+ };
317
+ mp_call_function_n_kw (item -> callback , 3 , 0 , args );
301
318
}
302
319
303
320
return mp_const_none ;
@@ -306,7 +323,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluetooth_write_callback_obj, bluetooth_write_c
306
323
307
324
// Call the registered callback for this characteristic, if one has been
308
325
// registered.
309
- void mp_bt_characteristic_on_write (uint16_t value_handle , const void * value , size_t value_len ) {
326
+ void mp_bt_characteristic_on_write (uint16_t conn_handle , uint16_t value_handle , const void * value , size_t value_len ) {
310
327
// Iterate through the linked list to find to find the characteristic
311
328
// with the given handle.
312
329
mp_bt_characteristic_callback_t * item = MP_STATE_PORT (bt_characteristic_callbacks );
@@ -321,15 +338,22 @@ void mp_bt_characteristic_on_write(uint16_t value_handle, const void *value, siz
321
338
uint16_t head = update_buf .head ;
322
339
uint16_t tail = update_buf .tail ;
323
340
size_t bytes_left = ((uint16_t )UPDATE_BUF_SIZE - (head - tail ));
324
- while (bytes_left < value_len + 1 ) {
341
+ // A packet has the following components:
342
+ // - 1 byte packet size (excluding this byte)
343
+ // - 2 byte conn_handle
344
+ // - N bytes data
345
+ size_t packet_len = value_len + 3 ;
346
+ while (bytes_left < packet_len ) {
325
347
// Drop oldest packet.
326
348
uint8_t packet_len = update_buf .data [tail % UPDATE_BUF_SIZE ];
327
349
tail += packet_len + 1 ;
328
350
update_buf .tail = tail ;
329
351
bytes_left = ((uint16_t )UPDATE_BUF_SIZE - (head - tail ));
330
352
update_buf .dropped_packets ++ ;
331
353
}
332
- update_buf .data [head ++ % UPDATE_BUF_SIZE ] = (uint8_t )value_len ;
354
+ update_buf .data [head ++ % UPDATE_BUF_SIZE ] = (uint8_t )(packet_len - 1 );
355
+ update_buf .data [head ++ % UPDATE_BUF_SIZE ] = (uint8_t )(conn_handle & 0xff ); // low bits
356
+ update_buf .data [head ++ % UPDATE_BUF_SIZE ] = (uint8_t )(conn_handle >> 8 ); // high bits
333
357
for (size_t i = 0 ; i < value_len ; i ++ ) {
334
358
update_buf .data [head ++ % UPDATE_BUF_SIZE ] = ((uint8_t * )value )[i ];
335
359
}
@@ -555,9 +579,22 @@ STATIC mp_obj_t device_connected(mp_obj_t self_in) {
555
579
}
556
580
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (device_connected_obj , device_connected );
557
581
582
+ STATIC mp_obj_t device_disconnect (mp_obj_t self_in ) {
583
+ mp_bt_device_t * device = self_in ;
584
+ if (device -> conn_handle != MP_BT_INVALID_CONN_HANDLE ) {
585
+ uint16_t conn_handle = device -> conn_handle ;
586
+ device -> conn_handle = MP_BT_INVALID_CONN_HANDLE ;
587
+ int errno_ = mp_bt_device_disconnect (conn_handle );
588
+ return bluetooth_handle_errno (errno_ );
589
+ }
590
+ return mp_const_none ;
591
+ }
592
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (device_disconnect_obj , device_disconnect );
593
+
558
594
STATIC const mp_rom_map_elem_t device_locals_dict_table [] = {
559
- { MP_ROM_QSTR (MP_QSTR_address ), MP_ROM_PTR (& device_address_obj ) },
560
- { MP_ROM_QSTR (MP_QSTR_connected ), MP_ROM_PTR (& device_connected_obj ) },
595
+ { MP_ROM_QSTR (MP_QSTR_address ), MP_ROM_PTR (& device_address_obj ) },
596
+ { MP_ROM_QSTR (MP_QSTR_connected ), MP_ROM_PTR (& device_connected_obj ) },
597
+ { MP_ROM_QSTR (MP_QSTR_disconnect ), MP_ROM_PTR (& device_disconnect_obj ) },
561
598
};
562
599
STATIC MP_DEFINE_CONST_DICT (device_locals_dict , device_locals_dict_table );
563
600
0 commit comments