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