@@ -278,6 +278,23 @@ static inline void receive_signal_raise(void)
278
278
mpsl_work_submit (& receive_work );
279
279
}
280
280
281
+ /** Storage for HCI packets from controller to host */
282
+ static struct {
283
+ /* Buffer for the HCI packet. */
284
+ uint8_t buf [HCI_RX_BUF_SIZE ];
285
+ /* Type of the HCI packet the buffer contains. */
286
+ sdc_hci_msg_type_t type ;
287
+ } rx_hci_msg ;
288
+
289
+ static void bt_buf_rx_freed_cb (enum bt_buf_type type_mask )
290
+ {
291
+ if (((rx_hci_msg .type == SDC_HCI_MSG_TYPE_EVT && (type_mask & BT_BUF_EVT ) != 0u ) ||
292
+ (rx_hci_msg .type == SDC_HCI_MSG_TYPE_DATA && (type_mask & BT_BUF_ACL_IN ) != 0u ) ||
293
+ (rx_hci_msg .type == SDC_HCI_MSG_TYPE_ISO && (type_mask & BT_BUF_ISO_IN ) != 0u ))) {
294
+ receive_signal_raise ();
295
+ }
296
+ }
297
+
281
298
static int cmd_handle (struct net_buf * cmd )
282
299
{
283
300
LOG_DBG ("" );
@@ -379,16 +396,16 @@ static int hci_driver_send(struct net_buf *buf)
379
396
return err ;
380
397
}
381
398
382
- static void data_packet_process (uint8_t * hci_buf )
399
+ static int data_packet_process (uint8_t * hci_buf )
383
400
{
384
- struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_FOREVER );
401
+ struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_NO_WAIT );
385
402
struct bt_hci_acl_hdr * hdr = (void * )hci_buf ;
386
403
uint16_t hf , handle , len ;
387
404
uint8_t flags , pb , bc ;
388
405
389
406
if (!data_buf ) {
390
- LOG_ERR ("No data buffer available" );
391
- return ;
407
+ LOG_DBG ("No data buffer available" );
408
+ return - ENOBUFS ;
392
409
}
393
410
394
411
len = sys_le16_to_cpu (hdr -> len );
@@ -402,35 +419,43 @@ static void data_packet_process(uint8_t *hci_buf)
402
419
LOG_ERR ("Event buffer too small. %u > %u" ,
403
420
len + sizeof (* hdr ),
404
421
HCI_RX_BUF_SIZE );
405
- k_panic ();
406
- return ;
422
+ return - ENOMEM ;
407
423
}
408
424
409
425
LOG_DBG ("Data: handle (0x%02x), PB(%01d), BC(%01d), len(%u)" , handle ,
410
426
pb , bc , len );
411
427
412
428
net_buf_add_mem (data_buf , & hci_buf [0 ], len + sizeof (* hdr ));
429
+
413
430
bt_recv (data_buf );
431
+
432
+ return 0 ;
414
433
}
415
434
416
- static void iso_data_packet_process (uint8_t * hci_buf )
435
+ static int iso_data_packet_process (uint8_t * hci_buf )
417
436
{
418
- struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ISO_IN , K_FOREVER );
437
+ struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ISO_IN , K_NO_WAIT );
419
438
struct bt_hci_iso_hdr * hdr = (void * )hci_buf ;
420
439
421
440
uint16_t len = sys_le16_to_cpu (hdr -> len );
422
441
442
+ if (!data_buf ) {
443
+ LOG_DBG ("No data buffer available" );
444
+ return - ENOBUFS ;
445
+ }
446
+
423
447
if (len + sizeof (* hdr ) > HCI_RX_BUF_SIZE ) {
424
448
LOG_ERR ("Event buffer too small. %u > %u" ,
425
449
len + sizeof (* hdr ),
426
450
HCI_RX_BUF_SIZE );
427
- k_panic ();
428
- return ;
451
+ return - ENOMEM ;
429
452
}
430
453
431
454
net_buf_add_mem (data_buf , & hci_buf [0 ], len + sizeof (* hdr ));
432
455
433
456
bt_recv (data_buf );
457
+
458
+ return 0 ;
434
459
}
435
460
436
461
static bool event_packet_is_discardable (const uint8_t * hci_buf )
@@ -475,7 +500,7 @@ static bool event_packet_is_discardable(const uint8_t *hci_buf)
475
500
}
476
501
}
477
502
478
- static void event_packet_process (uint8_t * hci_buf )
503
+ static int event_packet_process (uint8_t * hci_buf )
479
504
{
480
505
bool discardable = event_packet_is_discardable (hci_buf );
481
506
struct bt_hci_evt_hdr * hdr = (void * )hci_buf ;
@@ -485,8 +510,7 @@ static void event_packet_process(uint8_t *hci_buf)
485
510
LOG_ERR ("Event buffer too small. %u > %u" ,
486
511
hdr -> len + sizeof (* hdr ),
487
512
HCI_RX_BUF_SIZE );
488
- k_panic ();
489
- return ;
513
+ return - ENOMEM ;
490
514
}
491
515
492
516
if (hdr -> evt == BT_HCI_EVT_LE_META_EVENT ) {
@@ -512,62 +536,81 @@ static void event_packet_process(uint8_t *hci_buf)
512
536
LOG_DBG ("Event (0x%02x) len %u" , hdr -> evt , hdr -> len );
513
537
}
514
538
515
- evt_buf = bt_buf_get_evt (hdr -> evt , discardable ,
516
- discardable ? K_NO_WAIT : K_FOREVER );
539
+ evt_buf = bt_buf_get_evt (hdr -> evt , discardable , K_NO_WAIT );
517
540
518
541
if (!evt_buf ) {
519
542
if (discardable ) {
520
543
LOG_DBG ("Discarding event" );
521
- return ;
544
+ return 0 ;
522
545
}
523
546
524
- LOG_ERR ("No event buffer available" );
525
- return ;
547
+ LOG_DBG ("No event buffer available" );
548
+ return - ENOBUFS ;
526
549
}
527
550
528
551
net_buf_add_mem (evt_buf , & hci_buf [0 ], hdr -> len + sizeof (* hdr ));
552
+
529
553
bt_recv (evt_buf );
554
+
555
+ return 0 ;
530
556
}
531
557
532
- static bool fetch_and_process_hci_msg (uint8_t * p_hci_buffer )
558
+ static int fetch_hci_msg (uint8_t * p_hci_buffer , sdc_hci_msg_type_t * msg_type )
533
559
{
534
560
int errcode ;
535
- sdc_hci_msg_type_t msg_type ;
536
561
537
562
errcode = MULTITHREADING_LOCK_ACQUIRE ();
538
563
if (!errcode ) {
539
- errcode = hci_internal_msg_get (p_hci_buffer , & msg_type );
564
+ errcode = hci_internal_msg_get (p_hci_buffer , msg_type );
540
565
MULTITHREADING_LOCK_RELEASE ();
541
566
}
542
567
543
- if (errcode ) {
544
- return false;
545
- }
568
+ return errcode ;
569
+ }
570
+
571
+ static int process_hci_msg (uint8_t * p_hci_buffer , sdc_hci_msg_type_t msg_type )
572
+ {
573
+ int err ;
546
574
547
575
if (msg_type == SDC_HCI_MSG_TYPE_EVT ) {
548
- event_packet_process (p_hci_buffer );
576
+ err = event_packet_process (p_hci_buffer );
549
577
} else if (msg_type == SDC_HCI_MSG_TYPE_DATA ) {
550
- data_packet_process (p_hci_buffer );
578
+ err = data_packet_process (p_hci_buffer );
551
579
} else if (msg_type == SDC_HCI_MSG_TYPE_ISO ) {
552
- iso_data_packet_process (p_hci_buffer );
580
+ err = iso_data_packet_process (p_hci_buffer );
553
581
} else {
554
582
if (!IS_ENABLED (CONFIG_BT_CTLR_SDC_SILENCE_UNEXPECTED_MSG_TYPE )) {
555
583
LOG_ERR ("Unexpected msg_type: %u. This if-else needs a new branch" ,
556
584
msg_type );
557
585
}
586
+ err = 0 ;
558
587
}
559
588
560
- return true ;
589
+ return err ;
561
590
}
562
591
563
592
void hci_driver_receive_process (void )
564
593
{
565
- static uint8_t hci_buf [ HCI_RX_BUF_SIZE ] ;
594
+ int err ;
566
595
567
- if (fetch_and_process_hci_msg (& hci_buf [0 ])) {
568
- /* Let other threads of same priority run in between. */
569
- 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 ;
599
+ }
600
+
601
+ err = process_hci_msg (& 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 ();
570
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 ();
571
614
}
572
615
573
616
static void receive_work_handler (struct k_work * work )
@@ -1297,6 +1340,8 @@ static int hci_driver_open(void)
1297
1340
1298
1341
MULTITHREADING_LOCK_RELEASE ();
1299
1342
1343
+ bt_buf_rx_freed_cb_set (bt_buf_rx_freed_cb );
1344
+
1300
1345
return 0 ;
1301
1346
}
1302
1347
@@ -1329,6 +1374,8 @@ static int hci_driver_close(void)
1329
1374
1330
1375
MULTITHREADING_LOCK_RELEASE ();
1331
1376
1377
+ bt_buf_rx_freed_cb_set (NULL );
1378
+
1332
1379
return err ;
1333
1380
}
1334
1381
0 commit comments