• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "osi/fixed_queue.h"
23 #include "hci/hci_hal.h"
24 #include "hci/hci_internals.h"
25 #include "hci/hci_layer.h"
26 #include "osi/thread.h"
27 #include "esp_bt.h"
28 #include "stack/hcimsgs.h"
29 
30 #if (C2H_FLOW_CONTROL_INCLUDED == 1)
31 #include "l2c_int.h"
32 #endif ///C2H_FLOW_CONTROL_INCLUDED == 1
33 #include "stack/hcimsgs.h"
34 
35 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
36 #define HCI_BLE_EVENT 0x3e
37 #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
38 #define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
39 extern bool BTU_check_queue_is_congest(void);
40 
41 
42 static const uint8_t preamble_sizes[] = {
43     HCI_COMMAND_PREAMBLE_SIZE,
44     HCI_ACL_PREAMBLE_SIZE,
45     HCI_SCO_PREAMBLE_SIZE,
46     HCI_EVENT_PREAMBLE_SIZE
47 };
48 
49 static const uint16_t outbound_event_types[] = {
50     MSG_HC_TO_STACK_HCI_ERR,
51     MSG_HC_TO_STACK_HCI_ACL,
52     MSG_HC_TO_STACK_HCI_SCO,
53     MSG_HC_TO_STACK_HCI_EVT
54 };
55 
56 typedef struct {
57     size_t buffer_size;
58     fixed_queue_t *rx_q;
59     uint16_t adv_free_num;
60 } hci_hal_env_t;
61 
62 
63 static hci_hal_env_t hci_hal_env;
64 static const hci_hal_t interface;
65 static const hci_hal_callbacks_t *callbacks;
66 static const esp_vhci_host_callback_t vhci_host_cb;
67 static osi_thread_t *hci_h4_thread;
68 
69 static void host_send_pkt_available_cb(void);
70 static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
71 
72 static void hci_hal_h4_rx_handler(void *arg);
73 static void event_uart_has_bytes(fixed_queue_t *queue);
74 
75 
hci_hal_env_init(size_t buffer_size,size_t max_buffer_count)76 static void hci_hal_env_init(
77     size_t buffer_size,
78     size_t max_buffer_count)
79 {
80     assert(buffer_size > 0);
81     assert(max_buffer_count > 0);
82 
83     hci_hal_env.buffer_size = buffer_size;
84     hci_hal_env.adv_free_num = 0;
85 
86     hci_hal_env.rx_q = fixed_queue_new(max_buffer_count);
87     if (hci_hal_env.rx_q) {
88         fixed_queue_register_dequeue(hci_hal_env.rx_q, event_uart_has_bytes);
89     } else {
90         HCI_TRACE_ERROR("%s unable to create rx queue.\n", __func__);
91     }
92 
93     return;
94 }
95 
hci_hal_env_deinit(void)96 static void hci_hal_env_deinit(void)
97 {
98     fixed_queue_free(hci_hal_env.rx_q, osi_free_func);
99     hci_hal_env.rx_q = NULL;
100 }
101 
hal_open(const hci_hal_callbacks_t * upper_callbacks,void * task_thread)102 static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thread)
103 {
104     assert(upper_callbacks != NULL);
105     assert(task_thread != NULL);
106 
107     callbacks = upper_callbacks;
108 #if (BLE_ADV_REPORT_FLOW_CONTROL == 1)
109     hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, BLE_ADV_REPORT_FLOW_CONTROL_NUM + L2CAP_HOST_FC_ACL_BUFS + QUEUE_SIZE_MAX); // adv flow control num + ACL flow control num + hci cmd numeber
110 #else
111     hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
112 #endif
113 
114     hci_h4_thread = (osi_thread_t *)task_thread;
115 
116     //register vhci host cb
117     if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
118         return false;
119     }
120 
121     return true;
122 }
123 
hal_close(void)124 static void hal_close(void)
125 {
126     hci_hal_env_deinit();
127 
128     hci_h4_thread = NULL;
129 }
130 
131 /**
132  * Function: transmit_data -TX data to low-layer
133  * It is ported from Bluedroid source code, so it is not
134  * needed to use write() to send data.
135  * TODO: Just use firmware API to send data.
136  */
transmit_data(serial_data_type_t type,uint8_t * data,uint16_t length)137 static uint16_t transmit_data(serial_data_type_t type,
138                               uint8_t *data, uint16_t length)
139 {
140     uint8_t previous_byte;
141 
142     assert(data != NULL);
143     assert(length > 0);
144 
145     if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
146         HCI_TRACE_ERROR("%s invalid data type: %d", __func__, type);
147         return 0;
148     }
149 
150     // Write the signal byte right before the data
151     --data;
152     previous_byte = *data;
153     *(data) = type;
154     ++length;
155 
156     BTTRC_DUMP_BUFFER("Transmit Pkt", data, length);
157 
158     // TX Data to target
159     esp_vhci_host_send_packet(data, length);
160 
161     // Be nice and restore the old value of that byte
162     *(data) = previous_byte;
163 
164     return length - 1;
165 }
166 
167 // Internal functions
hci_hal_h4_rx_handler(void * arg)168 static void hci_hal_h4_rx_handler(void *arg)
169 {
170     fixed_queue_process(hci_hal_env.rx_q);
171 }
172 
hci_hal_h4_task_post(uint32_t timeout)173 bool hci_hal_h4_task_post(uint32_t timeout)
174 {
175     return osi_thread_post(hci_h4_thread, hci_hal_h4_rx_handler, NULL, 1, timeout);
176 }
177 
178 #if (C2H_FLOW_CONTROL_INCLUDED == 1)
hci_packet_complete(BT_HDR * packet)179 static void hci_packet_complete(BT_HDR *packet){
180     uint8_t type;
181     uint16_t handle;
182     uint16_t num_packets = 1;
183     uint8_t *stream = packet->data + packet->offset;
184 
185     STREAM_TO_UINT8(type, stream);
186     if (type == DATA_TYPE_ACL/* || type == DATA_TYPE_SCO*/) {
187         STREAM_TO_UINT16(handle, stream);
188         handle = handle & HCI_DATA_HANDLE_MASK;
189         btsnd_hcic_host_num_xmitted_pkts(1, &handle, &num_packets);
190     }
191 }
192 #endif ///C2H_FLOW_CONTROL_INCLUDED == 1
193 
host_recv_adv_packet(BT_HDR * packet)194 bool host_recv_adv_packet(BT_HDR *packet)
195 {
196     assert(packet);
197     if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT) {
198         if(packet->data[3] ==  HCI_BLE_ADV_PKT_RPT_EVT
199 #if (BLE_ADV_REPORT_FLOW_CONTROL == 1)
200         || packet->data[3] ==  HCI_BLE_ADV_DISCARD_REPORT_EVT
201 #endif
202         ) {
203             return true;
204         }
205     }
206     return false;
207 }
208 
209 #if (BLE_ADV_REPORT_FLOW_CONTROL == 1)
hci_update_adv_report_flow_control(BT_HDR * packet)210 static void hci_update_adv_report_flow_control(BT_HDR *packet)
211 {
212     // this is adv packet
213     if(host_recv_adv_packet(packet)) {
214         // update adv free number
215         hci_hal_env.adv_free_num ++;
216         if (esp_vhci_host_check_send_available()){
217             // send hci cmd
218             btsnd_hcic_ble_update_adv_report_flow_control(hci_hal_env.adv_free_num);
219             hci_hal_env.adv_free_num = 0;
220         } else {
221             //do nothing
222         }
223     }
224 
225 }
226 #endif
227 
hci_hal_h4_hdl_rx_packet(BT_HDR * packet)228 static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
229 {
230     uint8_t type, hdr_size;
231     uint16_t length;
232     uint8_t *stream = packet->data + packet->offset;
233 
234     if (!packet) {
235         return;
236     }
237 
238 #if (C2H_FLOW_CONTROL_INCLUDED == 1)
239     hci_packet_complete(packet);
240 #endif ///C2H_FLOW_CONTROL_INCLUDED == 1
241 
242     STREAM_TO_UINT8(type, stream);
243     packet->offset++;
244     packet->len--;
245     if (type == HCI_BLE_EVENT) {
246 #if (!CONFIG_BT_STACK_NO_LOG)
247         uint8_t len = 0;
248         STREAM_TO_UINT8(len, stream);
249 #endif
250         HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
251                   packet->len, len);
252         osi_free(packet);
253         return;
254     }
255     if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
256         HCI_TRACE_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x,"
257                   " min %x, max %x\n", __func__, type,
258                   DATA_TYPE_ACL, DATA_TYPE_EVENT);
259         osi_free(packet);
260         return;
261     }
262     hdr_size = preamble_sizes[type - 1];
263     if (packet->len < hdr_size) {
264         HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
265                   type, packet->len, hdr_size);
266         osi_free(packet);
267         return;
268     }
269     if (type == DATA_TYPE_ACL) {
270         stream += hdr_size - 2;
271         STREAM_TO_UINT16(length, stream);
272     } else {
273         stream += hdr_size - 1;
274         STREAM_TO_UINT8(length, stream);
275     }
276 
277     if ((length + hdr_size) != packet->len) {
278         HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
279                   "pkt_len=%d", type, hdr_size, length, packet->len);
280         osi_free(packet);
281         return;
282     }
283 
284 #if (BLE_ADV_REPORT_FLOW_CONTROL == 1)
285     hci_update_adv_report_flow_control(packet);
286 #endif
287 
288 #if SCAN_QUEUE_CONGEST_CHECK
289     if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
290         HCI_TRACE_DEBUG("BtuQueue is congested");
291         osi_free(packet);
292         return;
293     }
294 #endif
295     packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
296     callbacks->packet_ready(packet);
297 }
298 
event_uart_has_bytes(fixed_queue_t * queue)299 static void event_uart_has_bytes(fixed_queue_t *queue)
300 {
301     BT_HDR *packet;
302     while (!fixed_queue_is_empty(queue)) {
303         packet = fixed_queue_dequeue(queue, FIXED_QUEUE_MAX_TIMEOUT);
304         hci_hal_h4_hdl_rx_packet(packet);
305     }
306 }
307 
host_send_pkt_available_cb(void)308 static void host_send_pkt_available_cb(void)
309 {
310     //Controller rx cache buffer is ready for receiving new host packet
311     //Just Call Host main thread task to process pending packets.
312     hci_host_task_post(OSI_THREAD_MAX_TIMEOUT);
313 }
314 
host_recv_pkt_cb(uint8_t * data,uint16_t len)315 static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
316 {
317     //Target has packet to host, malloc new buffer for packet
318     BT_HDR *pkt;
319     size_t pkt_size;
320 
321     if (hci_hal_env.rx_q == NULL) {
322         return 0;
323     }
324 
325     pkt_size = BT_HDR_SIZE + len;
326     pkt = (BT_HDR *) osi_calloc(pkt_size);
327 
328     if (!pkt) {
329         HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
330         return -1;
331     }
332     pkt->offset = 0;
333     pkt->len = len;
334     pkt->layer_specific = 0;
335     memcpy(pkt->data, data, len);
336     fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
337     hci_hal_h4_task_post(0);
338 
339 
340     BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);
341 
342     return 0;
343 }
344 
345 static const esp_vhci_host_callback_t vhci_host_cb = {
346     .notify_host_send_available = host_send_pkt_available_cb,
347     .notify_host_recv = host_recv_pkt_cb,
348 };
349 
350 static const hci_hal_t interface = {
351     hal_open,
352     hal_close,
353     transmit_data,
354 };
355 
hci_hal_h4_get_interface(void)356 const hci_hal_t *hci_hal_h4_get_interface(void)
357 {
358     return &interface;
359 }
360