1 /**
2 * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
3 */
4
5 #include <string.h>
6 #include "os_task.h"
7 #include "os_mem.h"
8 #include "os_msg.h"
9 #include "os_sched.h"
10 #include "trace.h"
11 //#include "bte_api.h"
12 #include "hci_if.h"
13 #include "hci_tp.h"
14 //#include "bt_defs.h"
15 #include "bt_types.h"
16 #include "hci_code.h"
17 #include "hci_proto.h"
18
19 /***** Just for compile, need fix *****/
20 #define HCI_ACL_HDR_LEN 5 /* packet type (1), handle (2), length (2) */
21 #define HCI_EVT_HDR_LEN 3 /* packet type (1), event type (1), length (1) */
22 #define HCI_RX_ACL_BUF_OFFSET 0
23 #define br_rx_frag_pool 0
24 #define le_rx_frag_pool 0
25 #define bt_sys_pool 0
26 /***** Just for compile, need fix *****/
27
28 typedef struct
29 {
30 uint8_t hdr_buf[HCI_ACL_HDR_LEN];
31 uint8_t hdr_offset;
32 uint8_t hdr_len;
33 uint16_t payload_len;
34 uint8_t *rx_buf;
35 uint16_t rx_len;
36 uint16_t rx_offset;
37 } T_HCI_H4;
38
39 T_HCI_H4 hci_h4;
40
41 void hci_h4_recv(void);
42
hci_h4_tp_open_cb(bool status)43 bool hci_h4_tp_open_cb(bool status)
44 {
45 uint8_t msg;
46
47 if (status == true)
48 {
49 msg = HCI_IF_MSG_READY;
50 }
51 else
52 {
53 msg = HCI_IF_MSG_FAIL;
54 }
55
56 return os_msg_send(hci_if.msg_q, &msg, 0);
57 }
58
hci_h4_tp_tx_cb(void)59 bool hci_h4_tp_tx_cb(void)
60 {
61 uint8_t msg = HCI_IF_MSG_TX_RSP;
62
63 return os_msg_send(hci_if.msg_q, &msg, 0);
64 }
65
hci_h4_tp_rx_ind(void)66 bool hci_h4_tp_rx_ind(void)
67 {
68 uint8_t msg = HCI_IF_MSG_RX_IND;
69
70 return os_msg_send(hci_if.msg_q, &msg, 0);
71 }
72
hci_h4_alloc_buf(void)73 uint8_t *hci_h4_alloc_buf(void)
74 {
75 uint16_t len;
76 uint16_t offset;
77 uint8_t pool_id;
78
79 switch (hci_h4.hdr_buf[0])
80 {
81 case HCI_ACL_PKT:
82 offset = HCI_RX_ACL_BUF_OFFSET;
83 #if F_BT_BREDR_SUPPORT
84 pool_id = br_rx_frag_pool;
85 #else
86 pool_id = le_rx_frag_pool;
87 #endif
88 break;
89
90 case HCI_EVT_PKT:
91 offset = 0;
92 pool_id = bt_sys_pool;
93 break;
94
95 default:
96 return NULL;
97 }
98
99 len = offset + hci_h4.hdr_len + hci_h4.payload_len;
100
101 hci_h4.rx_buf = os_mem_zalloc(0, len);//bte_buffer_get(pool_id, len);
102 if (hci_h4.rx_buf != NULL)
103 {
104 memcpy(hci_h4.rx_buf + offset, hci_h4.hdr_buf, hci_h4.hdr_len);
105 hci_h4.rx_offset = offset + hci_h4.hdr_len;
106 hci_h4.rx_len = len;
107
108 /* put pkt type at the first byte for ACL data */
109 hci_h4.rx_buf[0] = hci_h4.hdr_buf[0];
110 }
111
112 return hci_h4.rx_buf;
113 }
114
hci_h4_open(void)115 void hci_h4_open(void)
116 {
117 memset(&hci_h4, 0, sizeof(T_HCI_H4));
118
119 hci_tp_open(hci_h4_tp_open_cb, hci_h4_tp_rx_ind);
120 }
121
hci_h4_close(void)122 void hci_h4_close(void)
123 {
124 #if F_BT_CONTROLLER_POWER_CONTROL
125 if (hci_h4.rx_buf != NULL)
126 {
127 os_mem_free(hci_h4.rx_buf);//bte_buffer_put(hci_h4.rx_buf);
128 hci_h4.rx_buf = NULL;
129 HCI_PRINT_ERROR0("hci_h4_close: rx_buf != NULL");
130 }
131 #endif
132 hci_tp_close();
133 }
134
hci_h4_send(uint8_t * p_buf,uint16_t len)135 bool hci_h4_send(uint8_t *p_buf, uint16_t len)
136 {
137 return hci_tp_send(p_buf, len, hci_h4_tp_tx_cb);
138 }
139
hci_h4_recv(void)140 void hci_h4_recv(void)
141 {
142 uint16_t rx_len;
143
144 while (hci_h4.hdr_offset == 0 || hci_h4.hdr_offset < hci_h4.hdr_len)
145 {
146 rx_len = hci_tp_recv(&hci_h4.hdr_buf[hci_h4.hdr_offset], 1);
147
148 /* No available rx data for HCI header */
149 if (rx_len == 0)
150 {
151 return;
152 }
153
154 hci_h4.hdr_offset++;
155
156 if (hci_h4.hdr_offset == 1)
157 {
158 switch (hci_h4.hdr_buf[0])
159 {
160 case HCI_ACL_PKT:
161 hci_h4.hdr_len = HCI_ACL_HDR_LEN;
162 break;
163
164 case HCI_EVT_PKT:
165 hci_h4.hdr_len = HCI_EVT_HDR_LEN;
166 break;
167
168 default:
169 HCI_PRINT_ERROR1("hci_h4_recv: invalid pkt type %u", hci_h4.hdr_buf[0]);
170 hci_h4.hdr_offset = 0;
171 hci_h4.payload_len = 0;
172 hci_if.callback(HCI_IF_EVT_ERROR, false, NULL, 0);
173 break;
174 }
175 }
176 else if (hci_h4.hdr_offset == hci_h4.hdr_len)
177 {
178 switch (hci_h4.hdr_buf[0])
179 {
180 case HCI_ACL_PKT:
181 LE_ARRAY_TO_UINT16(hci_h4.payload_len, &hci_h4.hdr_buf[3]);
182 if (hci_h4.payload_len == 0)
183 {
184 hci_h4.hdr_offset = 0;
185 }
186 break;
187
188 case HCI_EVT_PKT:
189 hci_h4.payload_len = (uint16_t)hci_h4.hdr_buf[2];
190 break;
191
192 default:
193 break;
194 }
195 }
196 }
197
198 if (hci_h4.payload_len && hci_h4.rx_buf == NULL)
199 {
200 hci_h4.rx_buf = hci_h4_alloc_buf();
201 if (hci_h4.rx_buf == NULL)
202 {
203 return;
204 }
205 }
206
207 while (hci_h4.rx_buf && hci_h4.rx_offset < hci_h4.rx_len)
208 {
209 rx_len = hci_tp_recv(hci_h4.rx_buf + hci_h4.rx_offset,
210 hci_h4.rx_len - hci_h4.rx_offset);
211
212 /* No available rx data for HCI payload */
213 if (rx_len == 0)
214 {
215 return;
216 }
217
218 hci_h4.rx_offset += rx_len;
219
220 if (hci_h4.rx_offset == hci_h4.rx_len)
221 {
222 hci_h4.hdr_offset = 0;
223
224 if (hci_if.state == HCI_IF_STATE_READY)
225 {
226 hci_if.callback(HCI_IF_EVT_DATA_IND, true, hci_h4.rx_buf, hci_h4.rx_len);
227 os_mem_free(hci_h4.rx_buf);
228 hci_h4.rx_buf = NULL;
229 hci_h4_recv();
230 }
231 else if (hci_if.state == HCI_IF_STATE_OPEN)
232 {
233 hci_tp_config(hci_h4.rx_buf, hci_h4.rx_len);
234 os_mem_free(hci_h4.rx_buf);//bte_buffer_put(hci_h4.rx_buf);
235 hci_h4.rx_buf = NULL;
236 }
237 else if (hci_if.state == HCI_IF_STATE_IDLE)
238 {
239 os_mem_free(hci_h4.rx_buf);//bte_buffer_put(hci_h4.rx_buf);
240 hci_h4.rx_buf = NULL;
241 }
242 }
243 }
244 }
245
hci_h4_cfm(void)246 void hci_h4_cfm(void)
247 {
248 uint8_t *p_buf;
249
250 if (os_msg_recv(hci_if.cfm_q, &p_buf, 0) == true)
251 {
252 os_mem_free(hci_h4.rx_buf);//bte_buffer_put(p_buf);
253 }
254
255 hci_h4_recv();
256 }
257
258 const T_HCI_PROTO hci_h4_proto =
259 {
260 .open = hci_h4_open,
261 .close = hci_h4_close,
262 .send = hci_h4_send,
263 .recv = hci_h4_recv,
264 .cfm = hci_h4_cfm,
265 };
266
267 #if F_BT_DEINIT
hci_h4_pre_deinit(void)268 void hci_h4_pre_deinit(void)
269 {
270 hci_tp_del();
271 }
272
hci_h4_deinit(void)273 void hci_h4_deinit(void)
274 {
275 memset(&hci_h4, 0, sizeof(hci_h4));
276 }
277 #endif
278