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 "trace.h"
10 //#include "bt_defs.h"
11 //#include "bte_api.h"
12 #include "hci_code.h"
13 #include "hci_if.h"
14 #include "hci_proto.h"
15 #include "bt_flags.h"
16 //#include "otp.h"
17
18 /***** Just for compile, need fix *****/
19 #define HCI_TASK_SIZE 2048
20 #define HCI_TASK_PRIORITY 5 //11-(-5)=16
21 #define HCI_TX_ACL_RSVD_SIZE 8
22 /***** Just for compile, need fix *****/
23
24 T_HCI_IF hci_if;
25
hci_if_tx_req(void)26 void hci_if_tx_req(void)
27 {
28 T_HCI_XMIT_DATA tx_data;
29 uint8_t *p_buf;
30 uint16_t len;
31
32 if (hci_if.tx_buf == NULL)
33 {
34 if (os_msg_recv(hci_if.xmit_q, &tx_data, 0) == true)
35 {
36 hci_if.tx_buf = tx_data.p_buf;
37 hci_if.tx_len = tx_data.len;
38 p_buf = tx_data.p_buf;
39 len = tx_data.len;
40
41 if (*p_buf == HCI_ACL_PKT)
42 {
43 p_buf += HCI_TX_ACL_RSVD_SIZE;
44 len -= HCI_TX_ACL_RSVD_SIZE;
45 }
46
47 hci_if.proto->send(p_buf, len);
48 }
49 }
50 }
51
hci_if_tx_rsp(void)52 void hci_if_tx_rsp(void)
53 {
54 hci_if.callback(HCI_IF_EVT_DATA_XMIT, true, hci_if.tx_buf, hci_if.tx_len);
55 hci_if.tx_buf = NULL;
56 hci_if_tx_req();
57 }
58
hci_if_task(void * p_param)59 void hci_if_task(void *p_param)
60 {
61 uint8_t msg;
62
63 (void)p_param;
64
65 while (true)
66 {
67 if (os_msg_recv(hci_if.msg_q, &msg, 0xFFFFFFFF) == true)
68 {
69 switch (msg)
70 {
71 case HCI_IF_MSG_OPEN:
72 hci_if.state = HCI_IF_STATE_OPEN;
73 hci_if.proto->open();
74 break;
75
76 case HCI_IF_MSG_READY:
77 hci_if.state = HCI_IF_STATE_READY;
78 hci_if.callback(HCI_IF_EVT_OPENED, true, NULL, 0);
79 break;
80
81 case HCI_IF_MSG_FAIL:
82 hci_if.state = HCI_IF_STATE_IDLE;
83 hci_if.callback(HCI_IF_EVT_OPENED, false, NULL, 0);
84 break;
85
86 case HCI_IF_MSG_TX_REQ:
87 hci_if_tx_req();
88 break;
89
90 case HCI_IF_MSG_TX_RSP:
91 hci_if_tx_rsp();
92 break;
93
94 case HCI_IF_MSG_RX_IND:
95 hci_if.proto->recv();
96 break;
97
98 case HCI_IF_MSG_RX_CFM:
99 hci_if.proto->cfm();
100 break;
101
102 case HCI_IF_MSG_CLOSE:
103 hci_if.state = HCI_IF_STATE_IDLE;
104 hci_if.proto->close();
105 hci_if.callback(HCI_IF_EVT_CLOSED, true, NULL, 0);
106 break;
107
108 default:
109 HCI_PRINT_ERROR1("hci_if_task: unknown msg 0x%02x", msg);
110 break;
111 }
112 }
113 }
114 }
115
hci_if_open(P_HCI_IF_CALLBACK p_callback)116 bool hci_if_open(P_HCI_IF_CALLBACK p_callback)
117 {
118 uint8_t msg = HCI_IF_MSG_OPEN;
119
120 if (hci_if.task_handle == NULL)
121 {
122 hci_if.state = HCI_IF_STATE_IDLE;
123 hci_if.callback = p_callback;
124 hci_if.proto = &hci_h4_proto;
125
126 os_msg_queue_create(&(hci_if.msg_q), 32, sizeof(uint8_t));
127 os_msg_queue_create(&(hci_if.xmit_q), 16, sizeof(T_HCI_XMIT_DATA));
128 os_msg_queue_create(&(hci_if.cfm_q), 16, sizeof(uint8_t *));
129
130 os_task_create(&hci_if.task_handle, "HCI I/F", hci_if_task, NULL,
131 HCI_TASK_SIZE, HCI_TASK_PRIORITY);
132 }
133 else
134 {
135 HCI_PRINT_INFO0("hci_if_open: reopen");
136 }
137
138 return os_msg_send(hci_if.msg_q, &msg, 0);
139 }
140
hci_if_close(void)141 bool hci_if_close(void)
142 {
143 uint8_t msg = HCI_IF_MSG_CLOSE;
144 HCI_PRINT_INFO0("hci_if_close");
145
146 return os_msg_send(hci_if.msg_q, &msg, 0);
147 }
148
hci_if_write(uint8_t * p_buf,uint32_t len)149 bool hci_if_write(uint8_t *p_buf, uint32_t len)
150 {
151 T_HCI_XMIT_DATA tx_data;
152 uint8_t msg;
153
154 /* HCI_PRINT_TRACE2("hci_if_write: buf %p, len %d", p_buf, len); */
155
156 tx_data.p_buf = p_buf;
157 tx_data.len = len;
158 msg = HCI_IF_MSG_TX_REQ;
159
160 if (os_msg_send(hci_if.xmit_q, &tx_data, 0) == true)
161 {
162 return os_msg_send(hci_if.msg_q, &msg, 0);
163 }
164 else
165 {
166 return false;
167 }
168 }
169
hci_if_confirm(uint8_t * p_buf)170 bool hci_if_confirm(uint8_t *p_buf)
171 {
172 uint8_t msg = HCI_IF_MSG_RX_CFM;
173
174 /* HCI_PRINT_TRACE1("hci_if_confirm: buf %p", p_buf); */
175
176 if (os_msg_send(hci_if.cfm_q, &p_buf, 0) == true)
177 {
178 return os_msg_send(hci_if.msg_q, &msg, 0);
179 }
180 else
181 {
182 return false;
183 }
184 }
185
186 #if F_BT_DEINIT
187 extern void hci_h4_pre_deinit(void);
188 extern void hci_h4_deinit(void);
hci_if_del_task(void)189 void hci_if_del_task(void)
190 {
191 //hci_h4_pre_deinit();
192 if (hci_if.task_handle != NULL)
193 {
194 os_task_delete(hci_if.task_handle);
195 hci_if.task_handle = NULL;
196 }
197 if (hci_if.msg_q)
198 {
199 os_msg_queue_delete(hci_if.msg_q);
200 hci_if.msg_q = NULL;
201 }
202 if (hci_if.xmit_q)
203 {
204 os_msg_queue_delete(hci_if.xmit_q);
205 hci_if.xmit_q = NULL;
206 }
207 if (hci_if.cfm_q)
208 {
209 os_msg_queue_delete(hci_if.cfm_q);
210 hci_if.cfm_q = NULL;
211 }
212 }
213
hci_if_deinit(void)214 void hci_if_deinit(void)
215 {
216 hci_h4_deinit();
217 memset(&hci_if, 0, offsetof(T_HCI_IF, proto));
218 }
219 #endif
220