@@ -89,16 +89,18 @@ static struct net_buf *get_rx(const uint8_t *buf)
8989}
9090
9191/**
92- * @brief Decode the length of an HCI H4 packet
92+ * @brief Decode the length of an HCI H4 packet and check it's complete
9393 * @details Decodes packet length according to Bluetooth spec v5.4 Vol 4 Part E
9494 * @param buf Pointer to a HCI packet buffer
95- * @return Length of the HCI packet in bytes, zero if no valid packet found.
95+ * @param buf_len Bytes available in the buffer
96+ * @return Length of the complete HCI packet in bytes, -1 if cannot find an HCI
97+ * packet, 0 if more data required.
9698 */
97- static uint16_t packet_len (const uint8_t * buf )
99+ static int32_t hci_packet_complete (const uint8_t * buf , uint16_t buf_len )
98100{
99101 uint16_t payload_len = 0 ;
100- uint8_t header_len = 0 ;
101102 const uint8_t type = buf [0 ];
103+ uint8_t header_len = sizeof (type );
102104 const uint8_t * hdr = & buf [sizeof (type )];
103105
104106 switch (type ) {
@@ -107,48 +109,53 @@ static uint16_t packet_len(const uint8_t *buf)
107109
108110 /* Parameter Total Length */
109111 payload_len = cmd -> param_len ;
110- header_len = BT_HCI_CMD_HDR_SIZE ;
112+ header_len + = BT_HCI_CMD_HDR_SIZE ;
111113 break ;
112114 }
113115 case BT_HCI_H4_ACL : {
114116 const struct bt_hci_acl_hdr * acl = (const struct bt_hci_acl_hdr * )hdr ;
115117
116118 /* Data Total Length */
117119 payload_len = sys_le16_to_cpu (acl -> len );
118- header_len = BT_HCI_ACL_HDR_SIZE ;
120+ header_len + = BT_HCI_ACL_HDR_SIZE ;
119121 break ;
120122 }
121123 case BT_HCI_H4_SCO : {
122124 const struct bt_hci_sco_hdr * sco = (const struct bt_hci_sco_hdr * )hdr ;
123125
124126 /* Data_Total_Length */
125127 payload_len = sco -> len ;
126- header_len = BT_HCI_SCO_HDR_SIZE ;
128+ header_len + = BT_HCI_SCO_HDR_SIZE ;
127129 break ;
128130 }
129131 case BT_HCI_H4_EVT : {
130132 const struct bt_hci_evt_hdr * evt = (const struct bt_hci_evt_hdr * )hdr ;
131133
132134 /* Parameter Total Length */
133135 payload_len = evt -> len ;
134- header_len = BT_HCI_EVT_HDR_SIZE ;
136+ header_len + = BT_HCI_EVT_HDR_SIZE ;
135137 break ;
136138 }
137139 case BT_HCI_H4_ISO : {
138140 const struct bt_hci_iso_hdr * iso = (const struct bt_hci_iso_hdr * )hdr ;
139141
140142 /* ISO_Data_Load_Length parameter */
141143 payload_len = bt_iso_hdr_len (sys_le16_to_cpu (iso -> len ));
142- header_len = BT_HCI_ISO_HDR_SIZE ;
144+ header_len + = BT_HCI_ISO_HDR_SIZE ;
143145 break ;
144146 }
145147 /* If no valid packet type found */
146148 default :
147149 LOG_WRN ("Unknown packet type 0x%02x" , type );
150+ return -1 ;
151+ }
152+
153+ /* Request more data */
154+ if (buf_len < header_len || buf_len - header_len < payload_len ) {
148155 return 0 ;
149156 }
150157
151- return sizeof ( type ) + header_len + payload_len ;
158+ return ( int32_t ) header_len + payload_len ;
152159}
153160
154161static bool uc_ready (void )
@@ -166,6 +173,8 @@ static void rx_thread(void *p1, void *p2, void *p3)
166173
167174 LOG_DBG ("started" );
168175
176+ uint16_t frame_size = 0 ;
177+
169178 while (1 ) {
170179 static uint8_t frame [512 ];
171180 struct net_buf * buf ;
@@ -181,7 +190,7 @@ static void rx_thread(void *p1, void *p2, void *p3)
181190
182191 LOG_DBG ("calling read()" );
183192
184- len = read (uc_fd , frame , sizeof (frame ));
193+ len = read (uc_fd , frame + frame_size , sizeof (frame ) - frame_size );
185194 if (len < 0 ) {
186195 if (errno == EINTR ) {
187196 k_yield ();
@@ -194,46 +203,60 @@ static void rx_thread(void *p1, void *p2, void *p3)
194203 return ;
195204 }
196205
197- while ( len > 0 ) {
206+ frame_size += len ;
198207
208+ while (frame_size > 0 ) {
209+ const uint8_t * buf_add ;
199210 const uint8_t packet_type = frame_start [0 ];
200- const uint16_t decoded_len = packet_len (frame_start );
211+ const int32_t decoded_len = hci_packet_complete (frame_start , frame_size );
201212
202- if (decoded_len == 0 ) {
213+ if (decoded_len == -1 ) {
203214 LOG_ERR ("HCI Packet type is invalid, length could not be decoded" );
215+ frame_size = 0 ; /* Drop buffer */
204216 break ;
205217 }
206218
207- if (decoded_len > len ) {
208- LOG_ERR ("Decoded HCI packet length (%d bytes) is greater "
209- "than buffer length (%d bytes)" , decoded_len , len );
219+ if (decoded_len == 0 ) {
220+ if (frame_size == sizeof (frame )) {
221+ LOG_ERR ("HCI Packet (%d bytes) is too big for frame (%d "
222+ "bytes)" ,
223+ decoded_len , sizeof (frame ));
224+ frame_size = 0 ; /* Drop buffer */
225+ break ;
226+ }
227+ if (frame_start != frame ) {
228+ memmove (frame , frame_start , frame_size );
229+ }
230+ /* Read more */
210231 break ;
211232 }
212233
234+ buf_add = frame_start + sizeof (packet_type );
235+ buf_add_len = decoded_len - sizeof (packet_type );
236+
213237 buf = get_rx (frame_start );
238+
239+ frame_size -= decoded_len ;
240+ frame_start += decoded_len ;
241+
214242 if (!buf ) {
215243 LOG_DBG ("Discard adv report due to insufficient buf" );
216- goto next ;
244+ continue ;
217245 }
218246
219247 buf_tailroom = net_buf_tailroom (buf );
220- buf_add_len = decoded_len - sizeof (packet_type );
221248 if (buf_tailroom < buf_add_len ) {
222249 LOG_ERR ("Not enough space in buffer %zu/%zu" ,
223250 buf_add_len , buf_tailroom );
224251 net_buf_unref (buf );
225- goto next ;
252+ continue ;
226253 }
227254
228- net_buf_add_mem (buf , frame_start + sizeof ( packet_type ) , buf_add_len );
255+ net_buf_add_mem (buf , buf_add , buf_add_len );
229256
230257 LOG_DBG ("Calling bt_recv(%p)" , buf );
231258
232259 bt_recv (buf );
233-
234- next :
235- len -= decoded_len ;
236- frame_start += decoded_len ;
237260 }
238261
239262 k_yield ();
0 commit comments