@@ -71,6 +71,82 @@ void rail_isr_installer(void)
7171 IRQ_CONNECT (AGC_IRQn , 0 , AGC_IRQHandler , NULL , 0 );
7272}
7373
74+ static bool slz_is_evt_discardable (const struct bt_hci_evt_hdr * hdr , const uint8_t * params ,
75+ int16_t params_len )
76+ {
77+ switch (hdr -> evt ) {
78+ case BT_HCI_EVT_LE_META_EVENT : {
79+ struct bt_hci_evt_le_meta_event * meta_evt = (void * )params ;
80+
81+ if (params_len < sizeof (* meta_evt )) {
82+ return false;
83+ }
84+ params += sizeof (* meta_evt );
85+ params_len -= sizeof (* meta_evt );
86+
87+ switch (meta_evt -> subevent ) {
88+ case BT_HCI_EVT_LE_ADVERTISING_REPORT :
89+ return true;
90+ case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT : {
91+ struct bt_hci_evt_le_ext_advertising_report * evt = (void * )params ;
92+
93+ if (!IS_ENABLED (CONFIG_BT_EXT_ADV )) {
94+ return false;
95+ }
96+
97+ if (params_len < sizeof (* evt ) + sizeof (* evt -> adv_info )) {
98+ return false;
99+ }
100+
101+ /* Never discard if the event could be part of a multi-part report event,
102+ * because the missing part could confuse the BT host.
103+ */
104+ return (evt -> num_reports == 1 ) &&
105+ ((evt -> adv_info [0 ].evt_type & BT_HCI_LE_ADV_EVT_TYPE_LEGACY ) != 0 );
106+ }
107+ default :
108+ return false;
109+ }
110+ }
111+ default :
112+ return false;
113+ }
114+ }
115+
116+ static struct net_buf * slz_bt_recv_evt (const uint8_t * data , const int16_t len )
117+ {
118+ struct net_buf * buf ;
119+ bool discardable ;
120+ const struct bt_hci_evt_hdr * hdr = (void * )data ;
121+ const uint8_t * params = & data [sizeof (* hdr )];
122+ const int16_t params_len = len - sizeof (* hdr );
123+
124+ if (len < sizeof (* hdr )) {
125+ LOG_ERR ("Event header is missing" );
126+ return NULL ;
127+ }
128+
129+ discardable = slz_is_evt_discardable (hdr , params , params_len );
130+ buf = bt_buf_get_evt (hdr -> evt , discardable , discardable ? K_NO_WAIT : K_FOREVER );
131+ if (!buf ) {
132+ LOG_DBG ("Discardable buffer pool full, ignoring event" );
133+ return buf ;
134+ }
135+
136+ net_buf_add_mem (buf , data , len );
137+
138+ return buf ;
139+ }
140+
141+ static struct net_buf * slz_bt_recv_acl (const uint8_t * data , const int16_t len )
142+ {
143+ struct net_buf * buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_FOREVER );
144+
145+ net_buf_add_mem (buf , data , len );
146+
147+ return buf ;
148+ }
149+
74150/**
75151 * @brief Transmit HCI message using the currently used transport layer.
76152 * The HCI calls this function to transmit a full HCI message.
@@ -81,30 +157,35 @@ void rail_isr_installer(void)
81157uint32_t hci_common_transport_transmit (uint8_t * data , int16_t len )
82158{
83159 struct net_buf * buf ;
84- uint8_t packet_type = data [0 ];
85- uint8_t event_code ;
160+ uint8_t packet_type ;
86161
87162 LOG_HEXDUMP_DBG (data , len , "host packet data:" );
88163
164+ if (len < 1 ) {
165+ LOG_ERR ("HCI packet type is missing" );
166+ return - EINVAL ;
167+ }
168+
169+ packet_type = data [0 ];
89170 /* drop packet type from the frame buffer - it is no longer needed */
90- data = & data [ 1 ] ;
171+ data += 1 ;
91172 len -= 1 ;
92173
93174 switch (packet_type ) {
94175 case BT_HCI_H4_EVT :
95- event_code = data [0 ];
96- buf = bt_buf_get_evt (event_code , false, K_FOREVER );
176+ buf = slz_bt_recv_evt (data , len );
97177 break ;
98178 case BT_HCI_H4_ACL :
99- buf = bt_buf_get_rx ( BT_BUF_ACL_IN , K_FOREVER );
179+ buf = slz_bt_recv_acl ( data , len );
100180 break ;
101181 default :
102182 LOG_ERR ("Unknown HCI type: %d" , packet_type );
103183 return - EINVAL ;
104184 }
105185
106- net_buf_add_mem (buf , data , len );
107- k_fifo_put (& slz_rx_fifo , buf );
186+ if (buf ) {
187+ k_fifo_put (& slz_rx_fifo , buf );
188+ }
108189
109190 sl_btctrl_hci_transmit_complete (0 );
110191
0 commit comments