1 /**
2  * Copyright (c) 2017, Realsil Semiconductor Corporation. All rights reserved.
3  *
4  */
5 
6 #include <stdio.h>
7 #include <string.h>
8 
9 #include "os_mem.h"
10 #include "hci_tp.h"
11 #include "hci_process.h"
12 #include "bt_types.h"
13 
14 #include "hci_uart.h"
15 #include "bt_board.h"
16 #include "hci_board.h"
17 
18 #include "trace_app.h"
19 
20 
21 typedef struct
22 {
23     P_HCI_TP_OPEN_CB    open_cb;
24     uint8_t            *tx_buf;
25 } T_HCI_UART;
26 
27 T_HCI_UART hci_rtk;
28 T_HCI_UART *p_hci_rtk = &hci_rtk;
29 
30 uint8_t g_hci_step = 0;
31 extern HCI_PROCESS_TABLE hci_process_table[];
32 extern uint8_t hci_total_step;
33 extern bool hci_board_complete(void);
34 //================================internal===========================
hci_rtk_tx_cb(void)35 bool hci_rtk_tx_cb(void)
36 {
37     if (p_hci_rtk->tx_buf != NULL)
38     {
39         os_mem_free(p_hci_rtk->tx_buf);
40         p_hci_rtk->tx_buf = NULL;
41     }
42     return true;
43 }
44 //=================================external==========================
hci_adapter_send(uint8_t * p_buf,uint16_t len)45 bool hci_adapter_send(uint8_t *p_buf, uint16_t len)
46 {
47     p_hci_rtk->tx_buf  = p_buf;
48     return hci_tp_send(p_buf, len, hci_rtk_tx_cb);
49 }
50 
51 //====================hci_tp.h================
hci_tp_open(P_HCI_TP_OPEN_CB open_cb,P_HCI_TP_RX_IND rx_ind)52 void hci_tp_open(P_HCI_TP_OPEN_CB open_cb, P_HCI_TP_RX_IND rx_ind)
53 {
54     uint8_t ret = 0xff;
55     p_hci_rtk->open_cb = open_cb;
56     if(hci_board_init() == false)
57     {
58         hci_board_debug("%s:hci_board_init fail\n", __FUNCTION__);
59         p_hci_rtk->open_cb(false);
60         return;
61     }
62     bt_reset();
63 
64     if(!hci_uart_init(rx_ind))
65     {
66         hci_board_debug("%s:uart_init fail\n", __FUNCTION__);
67         p_hci_rtk->open_cb(false);
68         return;
69     }
70 
71     g_hci_step = 0;
72 
73     ret = hci_process_table[g_hci_step].start_pro();
74 
75     if(ret == HCI_TP_NOT_SEND)
76     {
77         g_hci_step++;
78         hci_process_table[g_hci_step].start_pro();
79     }
80     else
81     {
82         //NORMAL START
83     }
84 }
85 
hci_tp_close(void)86 void hci_tp_close(void)
87 {
88     HCI_PRINT_INFO0("hci_tp_close");
89     bt_power_off();
90     hci_uart_deinit();
91     return;
92 }
93 
hci_tp_set_rx_ind(void (* ready_to_rx)(void))94 void hci_tp_set_rx_ind(void (*ready_to_rx)(void))
95 {
96 	hci_board_debug("hci_tp_set_rx_ind\r\n");
97     hci_uart_set_rx_ind((P_UART_RX_CB)ready_to_rx);
98     return;
99 }
100 
hci_tp_del(void)101 void hci_tp_del(void)
102 {
103     HCI_PRINT_INFO0("hci_tp_del");
104     bt_power_off();
105     hci_uart_deinit();
106     return;
107 }
108 
hci_tp_send(uint8_t * p_buf,uint16_t len,P_HCI_TP_TX_CB tx_cb)109 bool hci_tp_send(uint8_t *p_buf, uint16_t len, P_HCI_TP_TX_CB tx_cb)
110 {
111     return hci_uart_tx(p_buf, len, tx_cb);
112 }
113 
hci_tp_recv(uint8_t * p_buf,uint16_t size)114 uint16_t hci_tp_recv(uint8_t *p_buf, uint16_t size)
115 {
116     return hci_uart_recv(p_buf, size);
117 }
118 
hci_tp_config(uint8_t * p_buf,uint16_t len)119 void hci_tp_config(uint8_t *p_buf, uint16_t len)
120 {
121     (void)len;
122     uint8_t  pkt_type;
123     uint8_t  evt_code;
124     uint16_t opcode;
125     uint8_t  status;
126     uint8_t  p_buf_len;
127 
128     //hci_board_debug("hci tp config: state %08x\n", hci_hardware.state);
129     //HCI_PRINT_INFO2("hci_tp_config: state %u, %b", hci_rtk.state, TRACE_BINARY(len, p_buf));
130 
131     LE_STREAM_TO_UINT8(pkt_type, p_buf);
132 
133     if (pkt_type != HCI_EVT_PKT)
134     {
135         /* Skip non-hci event pkt. */
136         hci_board_debug("\r\nERROR:%s:packet type is %x\n",__FUNCTION__, pkt_type);
137         return;
138     }
139 
140     LE_STREAM_TO_UINT8(evt_code, p_buf);
141     LE_STREAM_TO_UINT8(p_buf_len, p_buf);
142     //STREAM_SKIP_LEN(p_buf, 1);  /* Skip event len */
143  //   hci_board_debug("\r\n%s:current step  is %x, total step is %x\n",__FUNCTION__,g_hci_step,
144    //         hci_total_step);
145 
146     if (evt_code == HCI_COMMAND_COMPLETE)
147     {
148         STREAM_SKIP_LEN(p_buf, 1);  /* Skip num of hci cmd pkts */
149         LE_STREAM_TO_UINT16(opcode, p_buf);
150         if (opcode == hci_process_table[g_hci_step].opcode)//check the opcode
151         {
152             LE_STREAM_TO_UINT8(status, p_buf);
153             if(status == 0)
154             {
155                 if(hci_process_table[g_hci_step].check_func != NULL)
156                 {
157                     uint8_t ret;
158                     ret = hci_process_table[g_hci_step].check_func(p_buf_len, p_buf);
159                     switch(ret)
160                     {
161                         case HCI_TP_CHECK_OK:
162                             goto hci_tp_config_ok;
163                             break;
164                         case HCI_TP_CHECK_AGAIN:
165                             goto hci_tp_config_again;
166                             break;
167                         case HCI_TP_CONFIG_FAIL:
168                             goto hci_tp_config_fail;
169                             break;
170                         case HCI_TP_CONFIG_END:
171                             goto hci_tp_config_end;
172                             break;
173                         case HCI_TP_CHECK_ERROR:
174                             p_hci_rtk->open_cb(false);
175                             return;
176                             break;
177                         default:
178                             hci_board_debug("\r\n%s:unexpect status is %x\n",__FUNCTION__,ret);
179                             break;
180                     }
181                 }
182                 else
183                 {
184                     if(p_buf_len == 4)
185                     {
186                         //hci_board_debug("\r\n%s:no need check is %x\n",__FUNCTION__, g_hci_step);
187                     }
188                     //hci_board_debug("\r\n%s:no need check is %x\n",__FUNCTION__, g_hci_step);
189                 }
190 hci_tp_config_ok:
191                 //next step
192                 g_hci_step++;
193                 if(g_hci_step == hci_total_step)
194                 {
195                     hci_board_debug("\r\n%s:BT INIT success %x\n",__FUNCTION__,g_hci_step);
196                     if(hci_board_complete() == true)
197                     {
198                          p_hci_rtk->open_cb(true);
199                     }
200                     else
201                     {
202                          p_hci_rtk->open_cb(false);
203                          return;
204                     }
205                 }
206                 else
207                 {
208                     if(hci_process_table[g_hci_step].start_pro != NULL)
209                     {
210                         uint8_t ret;
211                         ret = hci_process_table[g_hci_step].start_pro();
212                             while(ret == HCI_TP_NOT_SEND)
213                             {
214                                 g_hci_step++;
215                                 ret = hci_process_table[g_hci_step].start_pro();
216                             }
217                     }
218                     else
219                     {
220                         hci_board_debug("\r\nERROR:%s:start_pro is null %x\n",__FUNCTION__, g_hci_step);
221 
222                     }
223                 }
224             }
225             else
226             {
227                 hci_board_debug("\r\nERROR:%s:wrong status is %x, opcode is 0x%x\n",__FUNCTION__,
228                         status,opcode);
229             }
230 
231         }
232         else
233         {
234             hci_board_debug("\r\nERROR:%s:wrong type is %x\n",__FUNCTION__, opcode);
235         }
236 
237     }
238     else
239     {
240         hci_board_debug("\r\nERROR:%s:unhandle evt is %x\n", __FUNCTION__ ,evt_code);
241     }
242     return;
243 
244 hci_tp_config_fail:
245     p_hci_rtk->open_cb(false);
246     return;
247 
248 hci_tp_config_end:
249     p_hci_rtk->open_cb(true);
250     return;
251 
252 hci_tp_config_again:
253     hci_process_table[g_hci_step].start_pro();
254     return;
255 }
256 
257