@@ -270,6 +270,23 @@ static inline void receive_signal_raise(void)
270
270
mpsl_work_submit (& receive_work );
271
271
}
272
272
273
+ /** Storage for HCI packets from controller to host */
274
+ static struct {
275
+ /* Buffer for the HCI packet. */
276
+ uint8_t buf [HCI_RX_BUF_SIZE ];
277
+ /* Type of the HCI packet the buffer contains. */
278
+ sdc_hci_msg_type_t type ;
279
+ } rx_hci_msg ;
280
+
281
+ static void bt_buf_rx_freed_cb (enum bt_buf_type type_mask )
282
+ {
283
+ if (((rx_hci_msg .type == SDC_HCI_MSG_TYPE_EVT && (type_mask & BT_BUF_EVT ) != 0u ) ||
284
+ (rx_hci_msg .type == SDC_HCI_MSG_TYPE_DATA && (type_mask & BT_BUF_ACL_IN ) != 0u ) ||
285
+ (rx_hci_msg .type == SDC_HCI_MSG_TYPE_ISO && (type_mask & BT_BUF_ISO_IN ) != 0u ))) {
286
+ receive_signal_raise ();
287
+ }
288
+ }
289
+
273
290
static int cmd_handle (struct net_buf * cmd )
274
291
{
275
292
LOG_DBG ("" );
@@ -371,16 +388,16 @@ static int hci_driver_send(struct net_buf *buf)
371
388
return err ;
372
389
}
373
390
374
- static void data_packet_process (uint8_t * hci_buf )
391
+ static int data_packet_process (const struct device * dev , uint8_t * hci_buf )
375
392
{
376
- struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_FOREVER );
393
+ struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_NO_WAIT );
377
394
struct bt_hci_acl_hdr * hdr = (void * )hci_buf ;
378
395
uint16_t hf , handle , len ;
379
396
uint8_t flags , pb , bc ;
380
397
381
398
if (!data_buf ) {
382
- LOG_ERR ("No data buffer available" );
383
- return ;
399
+ LOG_DBG ("No data buffer available" );
400
+ return - ENOBUFS ;
384
401
}
385
402
386
403
len = sys_le16_to_cpu (hdr -> len );
@@ -390,23 +407,51 @@ static void data_packet_process(uint8_t *hci_buf)
390
407
pb = bt_acl_flags_pb (flags );
391
408
bc = bt_acl_flags_bc (flags );
392
409
410
+ if (len + sizeof (* hdr ) > HCI_RX_BUF_SIZE ) {
411
+ LOG_ERR ("Event buffer too small. %u > %u" ,
412
+ len + sizeof (* hdr ),
413
+ HCI_RX_BUF_SIZE );
414
+ return - ENOMEM ;
415
+ }
416
+
393
417
LOG_DBG ("Data: handle (0x%02x), PB(%01d), BC(%01d), len(%u)" , handle ,
394
418
pb , bc , len );
395
419
396
420
net_buf_add_mem (data_buf , & hci_buf [0 ], len + sizeof (* hdr ));
397
- bt_recv (data_buf );
421
+
422
+ struct hci_driver_data * driver_data = dev -> data ;
423
+
424
+ (void )driver_data -> recv_func (dev , data_buf );
425
+
426
+ return 0 ;
398
427
}
399
428
400
- static void iso_data_packet_process (uint8_t * hci_buf )
429
+ static int iso_data_packet_process (const struct device * dev , uint8_t * hci_buf )
401
430
{
402
- struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ISO_IN , K_FOREVER );
431
+ struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ISO_IN , K_NO_WAIT );
403
432
struct bt_hci_iso_hdr * hdr = (void * )hci_buf ;
404
433
405
434
uint16_t len = sys_le16_to_cpu (hdr -> len );
406
435
436
+ if (!data_buf ) {
437
+ LOG_DBG ("No data buffer available" );
438
+ return - ENOBUFS ;
439
+ }
440
+
441
+ if (len + sizeof (* hdr ) > HCI_RX_BUF_SIZE ) {
442
+ LOG_ERR ("Event buffer too small. %u > %u" ,
443
+ len + sizeof (* hdr ),
444
+ HCI_RX_BUF_SIZE );
445
+ return - ENOMEM ;
446
+ }
447
+
407
448
net_buf_add_mem (data_buf , & hci_buf [0 ], len + sizeof (* hdr ));
408
449
409
- bt_recv (data_buf );
450
+ struct hci_driver_data * driver_data = dev -> data ;
451
+
452
+ (void )driver_data -> recv_func (dev , data_buf );
453
+
454
+ return 0 ;
410
455
}
411
456
412
457
static bool event_packet_is_discardable (const uint8_t * hci_buf )
@@ -451,12 +496,19 @@ static bool event_packet_is_discardable(const uint8_t *hci_buf)
451
496
}
452
497
}
453
498
454
- static void event_packet_process (uint8_t * hci_buf )
499
+ static int event_packet_process (const struct device * dev , uint8_t * hci_buf )
455
500
{
456
501
bool discardable = event_packet_is_discardable (hci_buf );
457
502
struct bt_hci_evt_hdr * hdr = (void * )hci_buf ;
458
503
struct net_buf * evt_buf ;
459
504
505
+ if (hdr -> len + sizeof (* hdr ) > HCI_RX_BUF_SIZE ) {
506
+ LOG_ERR ("Event buffer too small. %u > %u" ,
507
+ hdr -> len + sizeof (* hdr ),
508
+ HCI_RX_BUF_SIZE );
509
+ return - ENOMEM ;
510
+ }
511
+
460
512
if (hdr -> evt == BT_HCI_EVT_LE_META_EVENT ) {
461
513
struct bt_hci_evt_le_meta_event * me = (void * )& hci_buf [2 ];
462
514
@@ -480,67 +532,85 @@ static void event_packet_process(uint8_t *hci_buf)
480
532
LOG_DBG ("Event (0x%02x) len %u" , hdr -> evt , hdr -> len );
481
533
}
482
534
483
- evt_buf = bt_buf_get_evt (hdr -> evt , discardable ,
484
- discardable ? K_NO_WAIT : K_FOREVER );
535
+ evt_buf = bt_buf_get_evt (hdr -> evt , discardable , K_NO_WAIT );
485
536
486
537
if (!evt_buf ) {
487
538
if (discardable ) {
488
539
LOG_DBG ("Discarding event" );
489
- return ;
540
+ return 0 ;
490
541
}
491
542
492
- LOG_ERR ("No event buffer available" );
493
- return ;
543
+ LOG_DBG ("No event buffer available" );
544
+ return - ENOBUFS ;
494
545
}
495
546
496
547
net_buf_add_mem (evt_buf , & hci_buf [0 ], hdr -> len + sizeof (* hdr ));
497
- bt_recv (evt_buf );
548
+
549
+ struct hci_driver_data * driver_data = dev -> data ;
550
+
551
+ (void )driver_data -> recv_func (dev , evt_buf );
552
+
553
+ return 0 ;
498
554
}
499
555
500
- static bool fetch_and_process_hci_msg (uint8_t * p_hci_buffer )
556
+ static int fetch_hci_msg (uint8_t * p_hci_buffer , sdc_hci_msg_type_t * msg_type )
501
557
{
502
558
int errcode ;
503
- sdc_hci_msg_type_t msg_type ;
504
559
505
560
errcode = MULTITHREADING_LOCK_ACQUIRE ();
506
561
if (!errcode ) {
507
- errcode = hci_internal_msg_get (p_hci_buffer , & msg_type );
562
+ errcode = hci_internal_msg_get (p_hci_buffer , msg_type );
508
563
MULTITHREADING_LOCK_RELEASE ();
509
564
}
510
565
511
- if (errcode ) {
512
- return false;
513
- }
566
+ return errcode ;
567
+ }
568
+
569
+ static int process_hci_msg (const struct device * dev , uint8_t * p_hci_buffer ,
570
+ sdc_hci_msg_type_t msg_type )
571
+ {
572
+ int err ;
514
573
515
574
if (msg_type == SDC_HCI_MSG_TYPE_EVT ) {
516
- event_packet_process (p_hci_buffer );
575
+ err = event_packet_process (dev , p_hci_buffer );
517
576
} else if (msg_type == SDC_HCI_MSG_TYPE_DATA ) {
518
- data_packet_process (p_hci_buffer );
577
+ err = data_packet_process (dev , p_hci_buffer );
519
578
} else if (msg_type == SDC_HCI_MSG_TYPE_ISO ) {
520
- iso_data_packet_process (p_hci_buffer );
579
+ err = iso_data_packet_process (dev , p_hci_buffer );
521
580
} else {
522
581
if (!IS_ENABLED (CONFIG_BT_CTLR_SDC_SILENCE_UNEXPECTED_MSG_TYPE )) {
523
582
LOG_ERR ("Unexpected msg_type: %u. This if-else needs a new branch" ,
524
583
msg_type );
525
584
}
585
+ err = 0 ;
526
586
}
527
587
528
- return true ;
588
+ return err ;
529
589
}
530
590
531
591
void hci_driver_receive_process (void )
532
592
{
533
- #if defined(CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT )
534
- static uint8_t hci_buf [MAX (BT_BUF_RX_SIZE ,
535
- BT_BUF_EVT_SIZE (CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE ))];
536
- #else
537
- static uint8_t hci_buf [BT_BUF_RX_SIZE ];
538
- #endif
593
+ const struct device * dev = DEVICE_DT_GET (DT_DRV_INST (0 ));
594
+ int err ;
539
595
540
- if (fetch_and_process_hci_msg ( & hci_buf [ 0 ])) {
541
- /* Let other threads of same priority run in between. */
542
- receive_signal_raise () ;
596
+ if (rx_hci_msg . type == SDC_HCI_MSG_TYPE_NONE &&
597
+ fetch_hci_msg ( & rx_hci_msg . buf [ 0 ], & rx_hci_msg . type ) != 0 ) {
598
+ return ;
543
599
}
600
+
601
+ err = process_hci_msg (dev , & rx_hci_msg .buf [0 ], rx_hci_msg .type );
602
+ if (err == - ENOBUFS ) {
603
+ /* If we got -ENOBUFS, wait for the signal from the host. */
604
+ return ;
605
+ } else if (err ) {
606
+ LOG_ERR ("Unknown error when processing hci message %d" , err );
607
+ k_panic ();
608
+ }
609
+
610
+ rx_hci_msg .type = SDC_HCI_MSG_TYPE_NONE ;
611
+
612
+ /* Let other threads of same priority run in between. */
613
+ receive_signal_raise ();
544
614
}
545
615
546
616
static void receive_work_handler (struct k_work * work )
@@ -1270,6 +1340,12 @@ static int hci_driver_open(void)
1270
1340
1271
1341
MULTITHREADING_LOCK_RELEASE ();
1272
1342
1343
+ struct hci_driver_data * driver_data = dev -> data ;
1344
+
1345
+ (void )driver_data -> recv_func = recv_func ;
1346
+
1347
+ bt_buf_rx_freed_cb_set (bt_buf_rx_freed_cb );
1348
+
1273
1349
return 0 ;
1274
1350
}
1275
1351
@@ -1302,6 +1378,8 @@ static int hci_driver_close(void)
1302
1378
1303
1379
MULTITHREADING_LOCK_RELEASE ();
1304
1380
1381
+ bt_buf_rx_freed_cb_set (NULL );
1382
+
1305
1383
return err ;
1306
1384
}
1307
1385
0 commit comments