1 /******************************************************************************
2 *
3 * Copyright (C) 2014 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <string.h>
19 #include "common/bt_defs.h"
20 #include "common/bt_trace.h"
21 #include "stack/bt_types.h"
22 #include "hci/hci_hal.h"
23 #include "hci/hci_internals.h"
24 #include "hci/hci_layer.h"
25 #include "osi/thread.h"
26 #include "osi/pkt_queue.h"
27 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
28 #include "osi/mutex.h"
29 #include "osi/alarm.h"
30 #endif
31 #include "esp_bt.h"
32 #include "stack/hcimsgs.h"
33
34 #if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
35 #include "l2c_int.h"
36 #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
37 #include "stack/hcimsgs.h"
38 #include "hci_log/bt_hci_log.h"
39
40 #define HCI_BLE_EVENT 0x3e
41 #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
42 #define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
43 #define HCI_UPSTREAM_DATA_QUEUE_IDX (1)
44 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
45 #define HCI_BLE_ADV_MIN_CREDITS_TO_RELEASE (10)
46 #define HCI_ADV_FLOW_MONITOR_PERIOD_MS (500)
47 #else
48 #define HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX (200)
49 #endif
50
51 extern bool BTU_check_queue_is_congest(void);
52
53
54 static const uint8_t preamble_sizes[] = {
55 HCI_COMMAND_PREAMBLE_SIZE,
56 HCI_ACL_PREAMBLE_SIZE,
57 HCI_SCO_PREAMBLE_SIZE,
58 HCI_EVENT_PREAMBLE_SIZE
59 };
60
61 static const uint16_t outbound_event_types[] = {
62 MSG_HC_TO_STACK_HCI_ERR,
63 MSG_HC_TO_STACK_HCI_ACL,
64 MSG_HC_TO_STACK_HCI_SCO,
65 MSG_HC_TO_STACK_HCI_EVT
66 };
67
68 typedef struct {
69 fixed_queue_t *rx_q;
70 struct pkt_queue *adv_rpt_q;
71 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
72 osi_mutex_t adv_flow_lock;
73 osi_alarm_t *adv_flow_monitor;
74 int adv_credits;
75 int adv_credits_to_release;
76 pkt_linked_item_t *adv_fc_cmd_buf;
77 bool cmd_buf_in_use;
78 #endif
79 hci_hal_callbacks_t *callbacks;
80 osi_thread_t *hci_h4_thread;
81 struct osi_event *upstream_data_ready;
82 } hci_hal_env_t;
83
84
85 static hci_hal_env_t hci_hal_env;
86 static const hci_hal_t interface;
87 static const esp_vhci_host_callback_t vhci_host_cb;
88
89 static void host_send_pkt_available_cb(void);
90 static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
91 static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet);
92 static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt);
93 static void hci_upstream_data_handler(void *arg);
94 static bool hci_upstream_data_post(uint32_t timeout);
95
96 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
97 static void hci_adv_flow_monitor(void *context);
98 static void hci_adv_flow_cmd_free_cb(pkt_linked_item_t *linked_pkt);
99 #endif
100
hci_hal_env_init(const hci_hal_callbacks_t * upper_callbacks,osi_thread_t * task_thread)101 static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thread_t *task_thread)
102 {
103 assert(upper_callbacks != NULL);
104 assert(task_thread != NULL);
105
106 hci_hal_env.hci_h4_thread = task_thread;
107 hci_hal_env.callbacks = (hci_hal_callbacks_t *)upper_callbacks;
108
109 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
110 hci_hal_env.adv_fc_cmd_buf = osi_calloc(HCI_CMD_LINKED_BUF_SIZE(HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL));
111 assert(hci_hal_env.adv_fc_cmd_buf != NULL);
112 osi_mutex_new(&hci_hal_env.adv_flow_lock);
113 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
114 hci_hal_env.adv_credits = BLE_ADV_REPORT_FLOW_CONTROL_NUM;
115 hci_hal_env.adv_credits_to_release = 0;
116 hci_hal_env.cmd_buf_in_use = false;
117 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
118 hci_hal_env.adv_flow_monitor = osi_alarm_new("adv_fc_mon", hci_adv_flow_monitor, NULL, HCI_ADV_FLOW_MONITOR_PERIOD_MS);
119 assert (hci_hal_env.adv_flow_monitor != NULL);
120 #endif
121
122 hci_hal_env.rx_q = fixed_queue_new(QUEUE_SIZE_MAX);
123 assert(hci_hal_env.rx_q != NULL);
124
125 hci_hal_env.adv_rpt_q = pkt_queue_create();
126 assert(hci_hal_env.adv_rpt_q != NULL);
127
128 struct osi_event *event = osi_event_create(hci_upstream_data_handler, NULL);
129 assert(event != NULL);
130 hci_hal_env.upstream_data_ready = event;
131 osi_event_bind(hci_hal_env.upstream_data_ready, hci_hal_env.hci_h4_thread, HCI_UPSTREAM_DATA_QUEUE_IDX);
132
133 return true;
134 }
135
hci_hal_env_deinit(void)136 static void hci_hal_env_deinit(void)
137 {
138 fixed_queue_t *rx_q = hci_hal_env.rx_q;
139 struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q;
140 struct osi_event *upstream_data_ready = hci_hal_env.upstream_data_ready;
141
142 hci_hal_env.rx_q = NULL;
143 hci_hal_env.adv_rpt_q = NULL;
144 hci_hal_env.upstream_data_ready = NULL;
145
146 fixed_queue_free(rx_q, osi_free_func);
147
148 pkt_queue_destroy(adv_rpt_q, NULL);
149
150 osi_event_delete(upstream_data_ready);
151
152 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
153 hci_hal_env.cmd_buf_in_use = true;
154 osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
155 osi_alarm_free(hci_hal_env.adv_flow_monitor);
156 hci_hal_env.adv_flow_monitor = NULL;
157 osi_mutex_free(&hci_hal_env.adv_flow_lock);
158 osi_free(hci_hal_env.adv_fc_cmd_buf);
159 hci_hal_env.adv_fc_cmd_buf = NULL;
160 #endif
161
162 hci_hal_env.hci_h4_thread = NULL;
163
164 memset(&hci_hal_env, 0, sizeof(hci_hal_env_t));
165 }
166
hal_open(const hci_hal_callbacks_t * upper_callbacks,void * task_thread)167 static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thread)
168 {
169 hci_hal_env_init(upper_callbacks, (osi_thread_t *)task_thread);
170
171 //register vhci host cb
172 if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
173 return false;
174 }
175
176 return true;
177 }
178
hal_close(void)179 static void hal_close(void)
180 {
181 hci_hal_env_deinit();
182 }
183
184 /**
185 * Function: transmit_data -TX data to low-layer
186 * It is ported from Bluedroid source code, so it is not
187 * needed to use write() to send data.
188 * TODO: Just use firmware API to send data.
189 */
transmit_data(serial_data_type_t type,uint8_t * data,uint16_t length)190 static uint16_t transmit_data(serial_data_type_t type,
191 uint8_t *data, uint16_t length)
192 {
193 uint8_t previous_byte;
194
195 assert(data != NULL);
196 assert(length > 0);
197
198 if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
199 HCI_TRACE_ERROR("%s invalid data type: %d", __func__, type);
200 return 0;
201 }
202
203 // Write the signal byte right before the data
204 --data;
205 previous_byte = *data;
206 *(data) = type;
207 ++length;
208
209 BTTRC_DUMP_BUFFER("Transmit Pkt", data, length);
210
211 #if (BT_HCI_LOG_INCLUDED == TRUE)
212 bt_hci_log_record_hci_data(data[0], &data[1], length - 1);
213 #endif
214 // TX Data to target
215 esp_vhci_host_send_packet(data, length);
216
217 // Be nice and restore the old value of that byte
218 *(data) = previous_byte;
219
220 return length - 1;
221 }
222
223 // Internal functions
hci_upstream_data_handler(void * arg)224 static void hci_upstream_data_handler(void *arg)
225 {
226 fixed_queue_t *rx_q = hci_hal_env.rx_q;
227 struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q;
228 size_t pkts_to_process;
229
230 do {
231 pkts_to_process = fixed_queue_length(rx_q);
232 for (size_t i = 0; i < pkts_to_process; i++) {
233 BT_HDR *packet = fixed_queue_dequeue(rx_q, 0);
234 if (packet != NULL) {
235 hci_hal_h4_hdl_rx_packet(packet);
236 }
237 }
238 } while (0);
239
240 do {
241 pkts_to_process = pkt_queue_length(adv_rpt_q);
242 for (size_t i = 0; i < pkts_to_process; i++) {
243 pkt_linked_item_t *linked_pkt = pkt_queue_dequeue(adv_rpt_q);
244 if (linked_pkt != NULL) {
245 hci_hal_h4_hdl_rx_adv_rpt(linked_pkt);
246 }
247 }
248 } while (0);
249
250 if (!fixed_queue_is_empty(rx_q) || pkt_queue_length(adv_rpt_q) > 0) {
251 hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT);
252 }
253 }
254
hci_upstream_data_post(uint32_t timeout)255 static bool hci_upstream_data_post(uint32_t timeout)
256 {
257 return osi_thread_post_event(hci_hal_env.upstream_data_ready, timeout);
258 }
259
260 #if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
hci_packet_complete(BT_HDR * packet)261 static void hci_packet_complete(BT_HDR *packet){
262 uint8_t type;
263 uint16_t handle;
264 uint16_t num_packets = 1;
265 uint8_t *stream = packet->data + packet->offset;
266
267 STREAM_TO_UINT8(type, stream);
268 if (type == DATA_TYPE_ACL/* || type == DATA_TYPE_SCO*/) {
269 STREAM_TO_UINT16(handle, stream);
270 handle = handle & HCI_DATA_HANDLE_MASK;
271 btsnd_hcic_host_num_xmitted_pkts(1, &handle, &num_packets);
272 }
273 }
274 #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
275
host_recv_adv_packet(uint8_t * packet)276 bool host_recv_adv_packet(uint8_t *packet)
277 {
278 assert(packet);
279 if(packet[0] == DATA_TYPE_EVENT && packet[1] == HCI_BLE_EVENT) {
280 if(packet[3] == HCI_BLE_ADV_PKT_RPT_EVT || packet[3] == HCI_BLE_DIRECT_ADV_EVT
281 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
282 || packet[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT
283 #endif
284 ) {
285 return true;
286 }
287 }
288 return false;
289 }
290
291 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_flow_monitor(void * context)292 static void hci_adv_flow_monitor(void *context)
293 {
294 hci_adv_credits_force_release(0);
295 }
296
hci_adv_credits_consumed(uint16_t num)297 static void hci_adv_credits_consumed(uint16_t num)
298 {
299 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
300 assert(hci_hal_env.adv_credits >= num);
301 hci_hal_env.adv_credits -= num;
302 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
303 }
304
hci_adv_credits_prep_to_release(uint16_t num)305 int hci_adv_credits_prep_to_release(uint16_t num)
306 {
307 if (num == 0) {
308 return hci_hal_env.adv_credits_to_release;
309 }
310
311 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
312 int credits_to_release = hci_hal_env.adv_credits_to_release + num;
313 assert(hci_hal_env.adv_credits_to_release <= BLE_ADV_REPORT_FLOW_CONTROL_NUM);
314 hci_hal_env.adv_credits_to_release = credits_to_release;
315 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
316
317 if (credits_to_release == num && num != 0) {
318 osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
319 osi_alarm_set(hci_hal_env.adv_flow_monitor, HCI_ADV_FLOW_MONITOR_PERIOD_MS);
320 }
321 return credits_to_release;
322 }
323
hci_adv_credits_release(void)324 static int hci_adv_credits_release(void)
325 {
326 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
327 int credits_released = hci_hal_env.adv_credits_to_release;
328 hci_hal_env.adv_credits += credits_released;
329 hci_hal_env.adv_credits_to_release -= credits_released;
330 assert(hci_hal_env.adv_credits <= BLE_ADV_REPORT_FLOW_CONTROL_NUM);
331 assert(hci_hal_env.adv_credits_to_release >= 0);
332 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
333
334 if (hci_hal_env.adv_credits_to_release == 0) {
335 osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
336 }
337 return credits_released;
338 }
339
hci_adv_credits_release_rollback(uint16_t num)340 static int hci_adv_credits_release_rollback(uint16_t num)
341 {
342 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
343 hci_hal_env.adv_credits -= num;
344 hci_hal_env.adv_credits_to_release += num;
345 assert(hci_hal_env.adv_credits >=0);
346 assert(hci_hal_env.adv_credits_to_release <= BLE_ADV_REPORT_FLOW_CONTROL_NUM);
347 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
348
349 return num;
350 }
351
hci_adv_flow_cmd_free_cb(pkt_linked_item_t * linked_pkt)352 static void hci_adv_flow_cmd_free_cb(pkt_linked_item_t *linked_pkt)
353 {
354 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
355 hci_hal_env.cmd_buf_in_use = false;
356 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
357 hci_adv_credits_try_release(0);
358 }
359
hci_adv_flow_try_send_command(uint16_t credits_released)360 bool hci_adv_flow_try_send_command(uint16_t credits_released)
361 {
362 bool sent = false;
363 bool use_static_buffer = false;
364
365 /* first try using static buffer, then dynamic buffer */
366 if (!hci_hal_env.cmd_buf_in_use) {
367 osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
368 if (!hci_hal_env.cmd_buf_in_use) {
369 hci_hal_env.cmd_buf_in_use = true;
370 use_static_buffer = true;
371 }
372 osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
373 }
374
375 if (use_static_buffer) {
376 hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(hci_hal_env.adv_fc_cmd_buf->data);
377 BT_HDR *static_buffer = &metadata->command;
378 metadata->command_free_cb = hci_adv_flow_cmd_free_cb;
379 sent = btsnd_hcic_ble_update_adv_report_flow_control(credits_released, static_buffer);
380 } else {
381 sent = btsnd_hcic_ble_update_adv_report_flow_control(credits_released, NULL);
382 }
383
384 return sent;
385 }
386
hci_adv_credits_try_release(uint16_t num)387 int hci_adv_credits_try_release(uint16_t num)
388 {
389 int credits_released = 0;
390 if (hci_adv_credits_prep_to_release(num) >= HCI_BLE_ADV_MIN_CREDITS_TO_RELEASE) {
391 credits_released = hci_adv_credits_release();
392 if (credits_released > 0) {
393 if (!hci_adv_flow_try_send_command(credits_released)) {
394 hci_adv_credits_release_rollback(credits_released);
395 }
396 } else {
397 assert (credits_released == 0);
398 }
399 }
400 return credits_released;
401 }
402
hci_adv_credits_force_release(uint16_t num)403 int hci_adv_credits_force_release(uint16_t num)
404 {
405 hci_adv_credits_prep_to_release(num);
406 int credits_released = hci_adv_credits_release();
407 if (credits_released > 0) {
408 if (!hci_adv_flow_try_send_command(credits_released)) {
409 hci_adv_credits_release_rollback(credits_released);
410 }
411 }
412
413 return credits_released;
414 }
415 #endif
416
hci_hal_h4_hdl_rx_packet(BT_HDR * packet)417 static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
418 {
419 uint8_t type, hdr_size;
420 uint16_t length;
421 uint8_t *stream = NULL;
422
423 if (!packet) {
424 return;
425 }
426 stream = packet->data + packet->offset;
427
428 #if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
429 hci_packet_complete(packet);
430 #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
431
432 STREAM_TO_UINT8(type, stream);
433 packet->offset++;
434 packet->len--;
435 if (type == HCI_BLE_EVENT) {
436 #if (!CONFIG_BT_STACK_NO_LOG)
437 uint8_t len = 0;
438 STREAM_TO_UINT8(len, stream);
439 #endif
440 HCI_TRACE_ERROR("Workaround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
441 packet->len, len);
442 osi_free(packet);
443 return;
444 }
445 if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
446 HCI_TRACE_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x,"
447 " min %x, max %x\n", __func__, type,
448 DATA_TYPE_ACL, DATA_TYPE_EVENT);
449 osi_free(packet);
450 return;
451 }
452 hdr_size = preamble_sizes[type - 1];
453 if (packet->len < hdr_size) {
454 HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
455 type, packet->len, hdr_size);
456 osi_free(packet);
457 return;
458 }
459 if (type == DATA_TYPE_ACL) {
460 stream += hdr_size - 2;
461 STREAM_TO_UINT16(length, stream);
462 } else {
463 stream += hdr_size - 1;
464 STREAM_TO_UINT8(length, stream);
465 }
466
467 if ((length + hdr_size) != packet->len) {
468 HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
469 "pkt_len=%d", type, hdr_size, length, packet->len);
470 osi_free(packet);
471 return;
472 }
473
474 packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
475 hci_hal_env.callbacks->packet_ready(packet);
476 }
477
hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t * linked_pkt)478 static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt)
479 {
480 uint8_t type;
481 uint8_t hdr_size;
482 uint16_t length;
483 uint8_t *stream = NULL;
484
485 if (!linked_pkt) {
486 return;
487 }
488
489 BT_HDR* packet = (BT_HDR *)linked_pkt->data;
490 stream = packet->data + packet->offset;
491
492 assert(host_recv_adv_packet(stream) == true);
493
494 STREAM_TO_UINT8(type, stream);
495 packet->offset++;
496 packet->len--;
497 hdr_size = preamble_sizes[type - 1];
498
499 if (packet->len < hdr_size) {
500 HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
501 type, packet->len, hdr_size);
502 goto _discard_packet;
503 }
504
505 stream += hdr_size - 1;
506 STREAM_TO_UINT8(length, stream);
507 if ((length + hdr_size) != packet->len) {
508 HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
509 "pkt_len=%d", type, hdr_size, length, packet->len);
510 goto _discard_packet;
511 }
512
513 #if SCAN_QUEUE_CONGEST_CHECK
514 if(BTU_check_queue_is_congest()) {
515 HCI_TRACE_DEBUG("BtuQueue is congested");
516 goto _discard_packet;
517 }
518 #endif
519
520 packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
521 hci_hal_env.callbacks->adv_rpt_ready(linked_pkt);
522
523 return;
524
525 _discard_packet:
526 osi_free(linked_pkt);
527 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
528 hci_adv_credits_prep_to_release(1);
529 #endif
530 }
531
host_send_pkt_available_cb(void)532 static void host_send_pkt_available_cb(void)
533 {
534 //Controller rx cache buffer is ready for receiving new host packet
535 //Just Call Host main thread task to process pending packets.
536 hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT);
537 }
538
539
bt_record_hci_data(uint8_t * data,uint16_t len)540 void bt_record_hci_data(uint8_t *data, uint16_t len)
541 {
542 #if (BT_HCI_LOG_INCLUDED == TRUE)
543 if ((data[0] == DATA_TYPE_EVENT) && (data[1] == HCI_BLE_EVENT) && ((data[3] == HCI_BLE_ADV_PKT_RPT_EVT) || (data[3] == HCI_BLE_DIRECT_ADV_EVT)
544 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
545 || (data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT)
546 #endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
547 #if (BLE_50_FEATURE_SUPPORT == TRUE)
548 || (data[3] == HCI_BLE_EXT_ADV_REPORT_EVT) || (data[3] == HCI_BLE_PERIOD_ADV_REPORT_EVT)
549 #endif // (BLE_50_FEATURE_SUPPORT == TRUE)
550 )) {
551 bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2);
552 } else {
553 uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]);
554 bt_hci_log_record_hci_data(data_type, &data[1], len - 1);
555 }
556 #endif // (BT_HCI_LOG_INCLUDED == TRUE)
557 }
558
host_recv_pkt_cb(uint8_t * data,uint16_t len)559 static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
560 {
561 //Target has packet to host, malloc new buffer for packet
562 BT_HDR *pkt = NULL;
563 pkt_linked_item_t *linked_pkt = NULL;
564 size_t pkt_size;
565
566 if (hci_hal_env.rx_q == NULL) {
567 return 0;
568 }
569
570 bt_record_hci_data(data, len);
571
572 bool is_adv_rpt = host_recv_adv_packet(data);
573
574 if (!is_adv_rpt) {
575 pkt_size = BT_HDR_SIZE + len;
576 pkt = (BT_HDR *) osi_calloc(pkt_size);
577 if (!pkt) {
578 HCI_TRACE_ERROR("%s couldn't acquire memory for inbound data buffer.\n", __func__);
579 assert(0);
580 }
581
582 pkt->offset = 0;
583 pkt->len = len;
584 pkt->layer_specific = 0;
585 memcpy(pkt->data, data, len);
586 fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
587 } else {
588 #if !BLE_ADV_REPORT_FLOW_CONTROL
589 // drop the packets if pkt_queue length goes beyond upper limit
590 if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) {
591 return 0;
592 }
593 #endif
594 pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len;
595 #if HEAP_MEMORY_DEBUG
596 linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size);
597 #else
598 linked_pkt = (pkt_linked_item_t *) osi_calloc_base(pkt_size);
599 #endif
600 if (!linked_pkt) {
601 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
602 hci_adv_credits_consumed(1);
603 hci_adv_credits_prep_to_release(1);
604 #endif
605 return 0;
606 }
607 pkt = (BT_HDR *)linked_pkt->data;
608 pkt->offset = 0;
609 pkt->len = len;
610 pkt->layer_specific = 0;
611 memcpy(pkt->data, data, len);
612 pkt_queue_enqueue(hci_hal_env.adv_rpt_q, linked_pkt);
613 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
614 hci_adv_credits_consumed(1);
615 #endif
616 }
617
618 hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT);
619
620 BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);
621
622 return 0;
623 }
624
625 static const esp_vhci_host_callback_t vhci_host_cb = {
626 .notify_host_send_available = host_send_pkt_available_cb,
627 .notify_host_recv = host_recv_pkt_cb,
628 };
629
630 static const hci_hal_t interface = {
631 hal_open,
632 hal_close,
633 transmit_data,
634 };
635
hci_hal_h4_get_interface(void)636 const hci_hal_t *hci_hal_h4_get_interface(void)
637 {
638 return &interface;
639 }
640