1414
1515#include "hci_api.h"
1616
17+ #include "py/obj.h"
18+
1719// Zephyr include files to define HCI communication values and structs.
1820#include "hci_include/hci.h"
1921#include "hci_include/hci_err.h"
2022
2123#include <string.h>
2224
2325#include "supervisor/shared/tick.h"
26+ #include "shared-bindings/_bleio/__init__.h"
27+ #include "common-hal/_bleio/Adapter.h"
2428
2529// HCI H4 protocol packet types: first byte in the packet.
2630#define H4_CMD 0x01
3135//FIX replace
3236#define ATT_CID 0x0004
3337
38+ #define sizeof_field (TYPE , MEMBER ) sizeof((((TYPE *)0)->MEMBER))
39+
3440#define RX_BUFFER_SIZE (3 + 255)
3541#define ACL_PKT_BUFFER_SIZE (255)
3642
3743#define CTS_TIMEOUT_MSECS (1000)
3844#define RESPONSE_TIMEOUT_MSECS (1000)
3945
40- STATIC bleio_adapter_obj_t * adapter ;
46+ #define adapter (&common_hal_bleio_adapter_obj)
4147
4248STATIC uint8_t rx_buffer [RX_BUFFER_SIZE ];
4349STATIC size_t rx_idx ;
@@ -81,12 +87,55 @@ typedef struct __attribute__ ((packed)) {
8187} h4_hci_evt_hdr_t ;
8288
8389
90+ STATIC void dump_cmd_pkt (bool tx , uint8_t pkt_len , uint8_t pkt_data []) {
91+ if (debug ) {
92+ h4_hci_cmd_hdr_t * pkt = (h4_hci_cmd_hdr_t * ) pkt_data ;
93+ mp_printf (& mp_plat_print ,
94+ "%s HCI COMMAND (%x) opcode: %04x, len: %d, data: " ,
95+ tx ? "TX->" : "RX<-" ,
96+ pkt -> pkt_type , pkt -> opcode , pkt -> param_len );
97+ uint8_t i ;
98+ for (i = sizeof (h4_hci_cmd_hdr_t ); i < pkt_len ; i ++ ) {
99+ mp_printf (& mp_plat_print , "%02x " , pkt_data [i ]);
100+ }
101+ if (i != pkt -> param_len + sizeof (h4_hci_cmd_hdr_t )) {
102+ mp_printf (& mp_plat_print , " LENGTH MISMATCH" );
103+ }
104+ mp_printf (& mp_plat_print , "\n" );
105+ }
106+ }
84107
85- STATIC void dump_pkt ( const char * prefix , uint8_t pkt_len , uint8_t pkt_data []) {
108+ STATIC void dump_acl_pkt ( bool tx , uint8_t pkt_len , uint8_t pkt_data []) {
86109 if (debug ) {
87- mp_printf (& mp_plat_print , "%s" , prefix );
88- for (uint8_t i = 0 ; i < pkt_len ; i ++ ) {
89- mp_printf (& mp_plat_print , "%02x" , pkt_data [i ]);
110+ h4_hci_acl_hdr_t * pkt = (h4_hci_acl_hdr_t * ) pkt_data ;
111+ mp_printf (& mp_plat_print ,
112+ "%s HCI ACLDATA (%x) handle: %04x, total_data_len: %d, acl_data_len: %d, cid: %04x, data: " ,
113+ tx ? "TX->" : "RX<-" ,
114+ pkt -> pkt_type , pkt -> handle , pkt -> total_data_len , pkt -> acl_data_len , pkt -> cid );
115+ uint8_t i ;
116+ for (i = sizeof (h4_hci_acl_hdr_t ); i < pkt_len ; i ++ ) {
117+ mp_printf (& mp_plat_print , "%02x " , pkt_data [i ]);
118+ }
119+ if (i != pkt -> acl_data_len + sizeof (h4_hci_acl_hdr_t )) {
120+ mp_printf (& mp_plat_print , " LENGTH MISMATCH" );
121+ }
122+ mp_printf (& mp_plat_print , "\n" );
123+ }
124+ }
125+
126+ STATIC void dump_evt_pkt (bool tx , uint8_t pkt_len , uint8_t pkt_data []) {
127+ if (debug ) {
128+ h4_hci_evt_hdr_t * pkt = (h4_hci_evt_hdr_t * ) pkt_data ;
129+ mp_printf (& mp_plat_print ,
130+ "%s HCI EVENT (%x) evt: %02x, param_len: %d, data: " ,
131+ tx ? "TX->" : "RX<-" ,
132+ pkt -> pkt_type , pkt -> evt , pkt -> param_len );
133+ uint8_t i ;
134+ for (i = sizeof (h4_hci_evt_hdr_t ); i < pkt_len ; i ++ ) {
135+ mp_printf (& mp_plat_print , "%02x " , pkt_data [i ]);
136+ }
137+ if (i != pkt -> param_len + sizeof (h4_hci_evt_hdr_t )) {
138+ mp_printf (& mp_plat_print , " LENGTH MISMATCH" );
90139 }
91140 mp_printf (& mp_plat_print , "\n" );
92141 }
@@ -184,9 +233,11 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
184233 cmd_response_received = true;
185234 cmd_response_opcode = evt -> cmd_complete .opcode ;
186235 cmd_response_status = evt -> cc_status .status ;
187- // All the bytes following status.
188- cmd_response_data = & evt_data [sizeof (struct cmd_complete_with_status )];
189- cmd_response_len = evt_hdr -> param_len - sizeof (struct cmd_complete_with_status );
236+ // All the bytes following cmd_complete, -including- the status byte, which is
237+ // included in all the _bt_hci_rp_* structs.
238+ cmd_response_data = & evt_data [sizeof_field (struct cmd_complete_with_status , cmd_complete )];
239+ // Includes status byte.
240+ cmd_response_len = evt_hdr -> param_len - sizeof_field (struct cmd_complete_with_status , cmd_complete );
190241
191242 break ;
192243 }
@@ -265,23 +316,22 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt[])
265316 }
266317}
267318
268- void hci_init (bleio_adapter_obj_t * adapter_in ) {
269- adapter = adapter_in ;
319+ void hci_init (void ) {
270320 rx_idx = 0 ;
271321 pending_pkt = 0 ;
272322}
273323
274324hci_result_t hci_poll_for_incoming_pkt (void ) {
275325 // Assert RTS low to say we're ready to read data.
276- common_hal_digitalio_digitalinout_set_value (& adapter -> rts_digitalinout , false);
326+ common_hal_digitalio_digitalinout_set_value (adapter -> rts_digitalinout , false);
277327
278328 int errcode = 0 ;
279329 bool packet_is_complete = false;
280330
281331 // Read bytes until we run out, or accumulate a complete packet.
282332 while (common_hal_busio_uart_rx_characters_available (adapter -> hci_uart )) {
283333 common_hal_busio_uart_read (adapter -> hci_uart , rx_buffer + rx_idx , 1 , & errcode );
284- if (! errcode ) {
334+ if (errcode ) {
285335 return HCI_READ_ERROR ;
286336 }
287337 rx_idx ++ ;
@@ -313,22 +363,23 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
313363 }
314364
315365 // Stop incoming data while processing packet.
316- common_hal_digitalio_digitalinout_set_value (& adapter -> rts_digitalinout , true);
366+ common_hal_digitalio_digitalinout_set_value (adapter -> rts_digitalinout , true);
317367 size_t pkt_len = rx_idx ;
368+ // Reset for next pack
318369 rx_idx = 0 ;
319370
320371 switch (rx_buffer [0 ]) {
321372 case H4_ACL :
322373 if (debug ) {
323- dump_pkt ( "HCI EVENT RX <- " , rx_idx , rx_buffer );
374+ dump_acl_pkt (false, pkt_len , rx_buffer );
324375 }
325376
326377 process_acl_data_pkt (pkt_len , rx_buffer );
327378 break ;
328379
329380 case H4_EVT :
330381 if (debug ) {
331- dump_pkt ( "HCI ACLDATA RX <- " , rx_idx , rx_buffer );
382+ dump_evt_pkt (false, pkt_len , rx_buffer );
332383 }
333384
334385 process_evt_pkt (pkt_len , rx_buffer );
@@ -338,7 +389,7 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
338389 break ;
339390 }
340391
341- common_hal_digitalio_digitalinout_set_value (& adapter -> rts_digitalinout , true);
392+ common_hal_digitalio_digitalinout_set_value (adapter -> rts_digitalinout , true);
342393
343394 return HCI_OK ;
344395}
@@ -348,7 +399,8 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
348399STATIC hci_result_t write_pkt (uint8_t * buffer , size_t len ) {
349400 // Wait for CTS to go low before writing to HCI adapter.
350401 uint64_t start = supervisor_ticks_ms64 ();
351- while (common_hal_digitalio_digitalinout_get_value (& adapter -> cts_digitalinout )) {
402+
403+ while (common_hal_digitalio_digitalinout_get_value (adapter -> cts_digitalinout )) {
352404 RUN_BACKGROUND_TASKS ;
353405 if (supervisor_ticks_ms64 () - start > CTS_TIMEOUT_MSECS ) {
354406 return HCI_WRITE_TIMEOUT ;
@@ -377,7 +429,7 @@ STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* para
377429 memcpy (& tx_buffer [sizeof (h4_hci_cmd_hdr_t )], params , params_len );
378430
379431 if (debug ) {
380- dump_pkt ( "HCI COMMAND TX -> " , sizeof (tx_buffer ), tx_buffer );
432+ dump_cmd_pkt (true , sizeof (tx_buffer ), tx_buffer );
381433 }
382434
383435 int result = write_pkt (tx_buffer , sizeof (h4_hci_cmd_hdr_t ) + params_len );
@@ -426,7 +478,7 @@ STATIC int __attribute__((unused)) send_acl_pkt(uint16_t handle, uint8_t cid, vo
426478 }
427479
428480 // data_len does not include cid.
429- const size_t cid_len = sizeof ((( h4_hci_acl_hdr_t * ) 0 ) -> cid );
481+ const size_t cid_len = sizeof_field ( h4_hci_acl_hdr_t , cid );
430482 // buf_len is size of entire packet including header.
431483 const size_t buf_len = sizeof (h4_hci_acl_hdr_t ) + cid_len + data_len ;
432484 uint8_t tx_buffer [buf_len ];
@@ -441,7 +493,7 @@ STATIC int __attribute__((unused)) send_acl_pkt(uint16_t handle, uint8_t cid, vo
441493 memcpy (& tx_buffer [sizeof (h4_hci_acl_hdr_t )], data , data_len );
442494
443495 if (debug ) {
444- dump_pkt ( "HCI ACLDATA TX -> " , buf_len , tx_buffer );
496+ dump_acl_pkt (true , buf_len , tx_buffer );
445497 }
446498
447499 pending_pkt ++ ;
@@ -478,7 +530,7 @@ hci_result_t hci_read_bd_addr(bt_addr_t *addr) {
478530 int result = send_command (BT_HCI_OP_READ_BD_ADDR , 0 , NULL );
479531 if (result == HCI_OK ) {
480532 struct bt_hci_rp_read_bd_addr * response = (struct bt_hci_rp_read_bd_addr * ) cmd_response_data ;
481- memcpy (addr -> val , response -> bdaddr .val , sizeof (bt_addr_t ));
533+ memcpy (addr -> val , response -> bdaddr .val , sizeof_field (bt_addr_t , val ));
482534 }
483535
484536 return result ;
0 commit comments