@@ -71,6 +71,82 @@ void rail_isr_installer(void)
71
71
IRQ_CONNECT (AGC_IRQn , 0 , AGC_IRQHandler , NULL , 0 );
72
72
}
73
73
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
+
74
150
/**
75
151
* @brief Transmit HCI message using the currently used transport layer.
76
152
* The HCI calls this function to transmit a full HCI message.
@@ -81,30 +157,35 @@ void rail_isr_installer(void)
81
157
uint32_t hci_common_transport_transmit (uint8_t * data , int16_t len )
82
158
{
83
159
struct net_buf * buf ;
84
- uint8_t packet_type = data [0 ];
85
- uint8_t event_code ;
160
+ uint8_t packet_type ;
86
161
87
162
LOG_HEXDUMP_DBG (data , len , "host packet data:" );
88
163
164
+ if (len < 1 ) {
165
+ LOG_ERR ("HCI packet type is missing" );
166
+ return - EINVAL ;
167
+ }
168
+
169
+ packet_type = data [0 ];
89
170
/* drop packet type from the frame buffer - it is no longer needed */
90
- data = & data [ 1 ] ;
171
+ data += 1 ;
91
172
len -= 1 ;
92
173
93
174
switch (packet_type ) {
94
175
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 );
97
177
break ;
98
178
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 );
100
180
break ;
101
181
default :
102
182
LOG_ERR ("Unknown HCI type: %d" , packet_type );
103
183
return - EINVAL ;
104
184
}
105
185
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
+ }
108
189
109
190
sl_btctrl_hci_transmit_complete (0 );
110
191
0 commit comments