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