1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2018 Realtek Corporation.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 /******************************************************************************
19 *
20 * Module Name:
21 * hci_h5.c
22 *
23 * Abstract:
24 * Contain HCI transport send/receive functions for UART H5 Interface.
25 *
26 * Major Change History:
27 * When Who What
28 * ---------------------------------------------------------------
29 * 2016-09-23 cc modified
30 *
31 * Notes:
32 * This is designed for UART H5 HCI Interface in Android 8.0
33 *
34 ******************************************************************************/
35 #define LOG_TAG "bt_h5_int"
36 #include <arpa/inet.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <pthread.h>
40 #include <signal.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/prctl.h>
44 #include <sys/syscall.h>
45 #include <sys/types.h>
46 #include <termios.h>
47 #include <time.h>
48 #include <unistd.h>
49 #include <utils/Log.h>
50 #include <linux/wait.h>
51
52 #include "bt_hci_bdroid.h"
53 #include "bt_list.h"
54 #include "bt_skbuff.h"
55 #include "hci_h5_int.h"
56 #include "userial.h"
57 #include "userial_vendor.h"
58
59 typedef void (*tINT_CMD_CBACK)(void *p_mem);
60 /******************************************************************************
61 ** Constants & Macros
62 ******************************************************************************/
63 #define H5_TRACE_DATA_ENABLE 0 // if you want to see data tx and rx, set H5_TRACE_DATA_ENABLE 1
64 #define H5_LOG_VERBOSE 0
65
66 unsigned int h5_log_enable = 1;
67
68 #ifndef H5_LOG_BUF_SIZE
69 #define H5_LOG_BUF_SIZE 1024
70 #endif
71 #define H5_LOG_MAX_SIZE (H5_LOG_BUF_SIZE - 12)
72
73 #ifndef H5_LOG_BUF_SIZE
74 #define H5_LOG_BUF_SIZE 1024
75 #endif
76 #define H5_LOG_MAX_SIZE (H5_LOG_BUF_SIZE - 12)
77
78 #define DATA_RETRANS_COUNT 40 // 40*100 = 4000ms(4s)
79 #define BT_INIT_DATA_RETRANS_COUNT 200 // 200*20 = 4000ms(4s)
80 #define SYNC_RETRANS_COUNT 350 // 350*10 = 3500ms(3.5s)
81 #define CONF_RETRANS_COUNT 350
82
83 #define DATA_RETRANS_TIMEOUT_VALUE 100 // ms
84 #define BT_INIT_DATA_RETRANS_TIMEOUT_VALUE 20 // ms
85 #define SYNC_RETRANS_TIMEOUT_VALUE 10
86 #define CONF_RETRANS_TIMEOUT_VALUE 20
87 #define WAIT_CT_BAUDRATE_READY_TIMEOUT_VALUE 5
88 #define H5_HW_INIT_READY_TIMEOUT_VALUE 4000 // 4
89
90 /* Maximum numbers of allowed internal
91 ** outstanding command packets at any time
92 */
93 #define INT_CMD_PKT_MAX_COUNT 8
94 #define INT_CMD_PKT_IDX_MASK 0x07
95
96 // HCI Event codes
97 #define HCI_CONNECTION_COMP_EVT 0x03
98 #define HCI_DISCONNECTION_COMP_EVT 0x05
99 #define HCI_COMMAND_COMPLETE_EVT 0x0E
100 #define HCI_COMMAND_STATUS_EVT 0x0F
101 #define HCI_NUM_OF_CMP_PKTS_EVT 0x13
102 #define HCI_BLE_EVT 0x3E
103
104 #define PATCH_DATA_FIELD_MAX_SIZE 252
105 #define READ_DATA_SIZE 16
106
107 // HCI data types //
108 #define H5_RELIABLE_PKT 0x01
109 #define H5_UNRELIABLE_PKT 0x00
110
111 #define H5_ACK_PKT 0x00
112 #define HCI_COMMAND_PKT 0x01
113 #define HCI_ACLDATA_PKT 0x02
114 #define HCI_SCODATA_PKT 0x03
115 #define HCI_EVENT_PKT 0x04
116 #define H5_VDRSPEC_PKT 0x0E
117 #define H5_LINK_CTL_PKT 0x0F
118
119 #define H5_HDR_SEQ(hdr) ((hdr)[0] & 0x07)
120 #define H5_HDR_ACK(hdr) (((hdr)[0] >> 3) & 0x07)
121 #define H5_HDR_CRC(hdr) (((hdr)[0] >> 6) & 0x01)
122 #define H5_HDR_RELIABLE(hdr) (((hdr)[0] >> 7) & 0x01)
123 #define H5_HDR_PKT_TYPE(hdr) ((hdr)[1] & 0x0f)
124 #define H5_HDR_LEN(hdr) ((((hdr)[1] >> 4) & 0xff) + ((hdr)[2] << 4))
125 #define H5_HDR_SIZE 4
126
127 #define H5_CFG_SLID_WIN(cfg) ((cfg)&0x07)
128 #define H5_CFG_OOF_CNTRL(cfg) (((cfg) >> 3) & 0x01)
129 #define H5_CFG_DIC_TYPE(cfg) (((cfg) >> 4) & 0x01)
130 #define H5_CFG_VER_NUM(cfg) (((cfg) >> 5) & 0x07)
131 #define H5_CFG_SIZE 1
132
133 /******************************************************************************
134 ** Local type definitions
135 ******************************************************************************/
136 /* Callback function for the returned event of internal issued command */
137 typedef void (*tTIMER_HANDLE_CBACK)(union sigval sigval_value);
138
139 typedef struct {
140 uint16_t opcode; /* OPCODE of outstanding internal commands */
141 tINT_CMD_CBACK cback; /* Callback function when return of internal
142 * command is received */
143 } tINT_CMD_Q;
144
145 typedef RTK_BUFFER sk_buff;
146
147 typedef enum H5_RX_STATE { H5_W4_PKT_DELIMITER, H5_W4_PKT_START, H5_W4_HDR, H5_W4_DATA, H5_W4_CRC } tH5_RX_STATE;
148
149 typedef enum H5_RX_ESC_STATE { H5_ESCSTATE_NOESC, H5_ESCSTATE_ESC } tH5_RX_ESC_STATE;
150
151 typedef enum H5_LINK_STATE { H5_UNINITIALIZED, H5_INITIALIZED, H5_ACTIVE } tH5_LINK_STATE;
152
153 #define H5_EVENT_RX 0x0001
154 #define H5_EVENT_EXIT 0x0200
155
156 static volatile uint8_t h5_retransfer_running = 0;
157 static volatile uint16_t h5_ready_events = 0;
158 static volatile uint8_t h5_data_ready_running = 0;
159 volatile int h5_init_datatrans_flag;
160
set_h5_init_datatrans_flag(int flag)161 void set_h5_init_datatrans_flag(int flag)
162 {
163 h5_init_datatrans_flag = flag;
164 }
165
set_h5_log_enable(unsigned int enable)166 void set_h5_log_enable(unsigned int enable)
167 {
168 h5_log_enable = enable;
169 }
170
171 /* Control block for HCISU_H5 */
172 typedef struct HCI_H5_CB {
173 HC_BT_HDR *p_rcv_msg; /* Buffer to hold current rx HCI message */
174 uint32_t int_cmd_rsp_pending; /* Num of internal cmds pending for ack */
175 uint8_t int_cmd_rd_idx; /* Read index of int_cmd_opcode queue */
176 uint8_t int_cmd_wrt_idx; /* Write index of int_cmd_opcode queue */
177 tINT_CMD_Q int_cmd[INT_CMD_PKT_MAX_COUNT]; /* FIFO queue */
178
179 tINT_CMD_CBACK cback_h5sync; /* Callback function when h5 sync */
180
181 uint8_t sliding_window_size;
182 uint8_t oof_flow_control;
183 uint8_t dic_type;
184
185 RTB_QUEUE_HEAD *unack; // Unack'ed packets queue
186 RTB_QUEUE_HEAD *rel; // Reliable packets queue
187
188 RTB_QUEUE_HEAD *unrel; // Unreliable packets queue
189 RTB_QUEUE_HEAD *recv_data; // Unreliable packets queue
190
191 uint8_t rxseq_txack; // rxseq == txack. // expected rx SeqNumber
192 uint8_t rxack; // Last packet sent by us that the peer ack'ed //
193
194 uint8_t use_crc;
195 uint8_t is_txack_req; // txack required? Do we need to send ack's to the peer? //
196
197 // Reliable packet sequence number - used to assign seq to each rel pkt. */
198 uint8_t msgq_txseq; // next pkt seq
199
200 uint16_t message_crc;
201 uint32_t rx_count; // expected pkts to recv
202
203 tH5_RX_STATE rx_state;
204 tH5_RX_ESC_STATE rx_esc_state;
205 tH5_LINK_STATE link_estab_state;
206
207 sk_buff *rx_skb;
208 sk_buff *data_skb;
209 sk_buff *internal_skb;
210
211 timer_t timer_data_retrans;
212 timer_t timer_sync_retrans;
213 timer_t timer_conf_retrans;
214 timer_t timer_wait_ct_baudrate_ready;
215 timer_t timer_h5_hw_init_ready;
216
217 uint32_t data_retrans_count;
218 uint32_t sync_retrans_count;
219 uint32_t conf_retrans_count;
220
221 pthread_mutex_t mutex;
222 pthread_cond_t cond;
223 pthread_t thread_data_retrans;
224
225 pthread_mutex_t data_mutex;
226 pthread_cond_t data_cond;
227 pthread_t thread_data_ready_cb;
228
229 uint8_t cleanuping;
230 } tHCI_H5_CB;
231
232 static tHCI_H5_CB rtk_h5;
233 static pthread_mutex_t h5_wakeup_mutex = PTHREAD_MUTEX_INITIALIZER;
234
235 /******************************************************************************
236 ** Variables
237 ******************************************************************************/
238
239 /* Num of allowed outstanding HCI CMD packets */
240 volatile int num_hci_cmd_pkts = 1;
241
242 /******************************************************************************
243 ** Static variables
244 ******************************************************************************/
245 struct patch_struct {
246 int nTxIndex; // current sending pkt number
247 int nTotal; // total pkt number
248 int nRxIndex; // ack index from board
249 int nNeedRetry; // if no response from board
250 };
251
252 /******************************************************************************
253 ** Static function
254 ******************************************************************************/
255 static timer_t OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback);
256 static int OsStartTimer(timer_t timerid, int msec, int mode);
257 static int OsStopTimer(timer_t timerid);
258 static uint16_t h5_wake_up(void);
259
260 static hci_h5_callbacks_t *h5_int_hal_callbacks;
261
262 /******************************************************************************
263 ** Externs
264 ******************************************************************************/
265
266 // timer API for retransfer
267 int h5_alloc_data_retrans_timer(void);
268 int h5_free_data_retrans_timer(void);
269 int h5_stop_data_retrans_timer(void);
270 int h5_start_data_retrans_timer(void);
271
272 int h5_alloc_sync_retrans_timer(void);
273 int h5_free_sync_retrans_timer(void);
274 int h5_stop_sync_retrans_timer(void);
275 int h5_start_sync_retrans_timer(void);
276
277 int h5_alloc_conf_retrans_timer(void);
278 int h5_free_conf_retrans_timer(void);
279 int h5_stop_conf_retrans_timer(void);
280 int h5_start_conf_retrans_timer(void);
281
282 int h5_alloc_wait_controller_baudrate_ready_timer(void);
283 int h5_free_wait_controller_baudrate_ready_timer(void);
284 int h5_stop_wait_controller_baudrate_ready_timer(void);
285 int h5_start_wait_controller_baudrate_ready_timer(void);
286
287 int h5_alloc_hw_init_ready_timer(void);
288 int h5_free_hw_init_ready_timer(void);
289 int h5_stop_hw_init_ready_timer(void);
290 int h5_start_hw_init_ready_timer(void);
291
292 int h5_enqueue(IN sk_buff *skb);
293
294 // bite reverse in bytes
295 // 00000001 -> 10000000
296 // 00000100 -> 00100000
297 const uint8_t byte_rev_table[256] = {
298 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48,
299 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4,
300 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c,
301 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2,
302 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a,
303 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e,
304 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21,
305 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
306 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55,
307 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd,
308 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b,
309 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
310 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f,
311 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
312 };
313 #ifndef H5_LOG_BUF_SIZE
314 #define H5_LOG_BUF_SIZE 1024
315 #endif
316 #define H5_LOG_MAX_SIZE (H5_LOG_BUF_SIZE - 12)
317
318 #define LOGI0(t, s)
319
H5LogMsg(const char * fmt_str,...)320 static void H5LogMsg(const char *fmt_str, ...)
321 {
322 static char buffer[H5_LOG_BUF_SIZE];
323 if (h5_log_enable == 1) {
324 va_list ap;
325 va_start(ap, fmt_str);
326 (void)vsnprintf_s(&buffer[0], H5_LOG_MAX_SIZE, H5_LOG_MAX_SIZE, fmt_str, ap);
327 va_end(ap);
328
329 LOGI0("H5: ", buffer);
330 } else {
331 return;
332 }
333 }
334
335 #define P_BUF_2 2
336 #define P_BUF_3 3
337 #define P_BUF_4 4
338
rtkbt_h5_send_hw_error(void)339 static void rtkbt_h5_send_hw_error(void)
340 {
341 unsigned char p_buf[100];
342 const char *str = "host stack: h5 send error";
343 int length = strlen(str) + 1 + P_BUF_4;
344 p_buf[0] = HCIT_TYPE_EVENT; // event
345 p_buf[1] = HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT; // firmwre event log
346 p_buf[P_BUF_2] = strlen(str) + P_BUF_2; // len
347 p_buf[P_BUF_3] = 0x01; // host log opcode
348 (void)strcpy_s((char *)&p_buf[P_BUF_4], length, str);
349 userial_recv_rawdata_hook(p_buf, length);
350
351 length = P_BUF_4;
352 p_buf[0] = HCIT_TYPE_EVENT; // event
353 p_buf[1] = HCI_HARDWARE_ERROR_EVT; // hardware error
354 p_buf[P_BUF_2] = 0x01; // len
355 p_buf[P_BUF_3] = 0xfb; // h5 error code
356 userial_recv_rawdata_hook(p_buf, length);
357 }
358
359 // reverse bit
bit_rev8(uint8_t byte)360 static __inline uint8_t bit_rev8(uint8_t byte)
361 {
362 return byte_rev_table[byte];
363 }
364
365 // reverse bit
bit_rev16(uint16_t x)366 static __inline uint16_t bit_rev16(uint16_t x)
367 {
368 #define REV_8 8
369 return (bit_rev8(x & 0xff) << REV_8) | bit_rev8(x >> REV_8);
370 }
371
372 static const uint16_t crc_table[] = {0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
373 0x8408, 0x9489, 0xa50a, 0xb58b, 0xc60c, 0xd68d, 0xe70e, 0xf78f};
374
375 // Initialise the crc calculator
376 #define H5_CRC_INIT(x) x = 0xffff
377
378 /*******************************************************************************
379 **
380 ** Function ms_delay
381 **
382 ** Description sleep unconditionally for timeout milliseconds
383 **
384 ** Returns None
385 **
386 *******************************************************************************/
ms_delay(uint32_t timeout)387 void ms_delay(uint32_t timeout)
388 {
389 struct timespec delay;
390 int err;
391
392 if (timeout == 0) {
393 return;
394 }
395
396 #define TV_SEC_1000 1000
397 delay.tv_sec = timeout / TV_SEC_1000;
398 delay.tv_nsec = TV_SEC_1000 * TV_SEC_1000 * (timeout % TV_SEC_1000);
399
400 /* [u]sleep can't be used because it uses SIGALRM */
401 do {
402 err = nanosleep(&delay, &delay);
403 } while (err < 0 && errno == EINTR);
404 }
405 /***********************************************
406 //
407 //skb related functions
408 //
409 //
410 //
411 ***********************************************/
skb_get_data(IN sk_buff * skb)412 uint8_t *skb_get_data(IN sk_buff *skb)
413 {
414 return skb->Data;
415 }
416
skb_get_data_length(IN sk_buff * skb)417 uint32_t skb_get_data_length(IN sk_buff *skb)
418 {
419 return skb->Length;
420 }
421
skb_alloc(IN unsigned int len)422 sk_buff *skb_alloc(IN unsigned int len)
423 {
424 sk_buff *skb = (sk_buff *)RtbAllocate(len, 0);
425 return skb;
426 }
427
skb_free(IN OUT sk_buff ** skb)428 void skb_free(IN OUT sk_buff **skb)
429 {
430 RtbFree(*skb);
431 *skb = NULL;
432 return;
433 }
434
skb_unlink(sk_buff * skb,struct _RTB_QUEUE_HEAD * list)435 static void skb_unlink(sk_buff *skb, struct _RTB_QUEUE_HEAD *list)
436 {
437 RtbRemoveNode(list, skb);
438 }
439
440 // increase the date length in sk_buffer by len,
441 // and return the increased header pointer
skb_put(OUT sk_buff * skb,IN uint32_t len)442 uint8_t *skb_put(OUT sk_buff *skb, IN uint32_t len)
443 {
444 RTK_BUFFER *rtb = (RTK_BUFFER *)skb;
445
446 return RtbAddTail(rtb, len);
447 }
448
449 // change skb->len to len
450 // !!! len should less than skb->len
skb_trim(sk_buff * skb,unsigned int len)451 void skb_trim(sk_buff *skb, unsigned int len)
452 {
453 RTK_BUFFER *rtb = (RTK_BUFFER *)skb;
454 uint32_t skb_len = skb_get_data_length(skb);
455
456 RtbRemoveTail(rtb, (skb_len - len));
457 return;
458 }
459
skb_get_pkt_type(sk_buff * skb)460 uint8_t skb_get_pkt_type(sk_buff *skb)
461 {
462 return BT_CONTEXT(skb)->PacketType;
463 }
464
skb_set_pkt_type(sk_buff * skb,uint8_t pkt_type)465 void skb_set_pkt_type(sk_buff *skb, uint8_t pkt_type)
466 {
467 BT_CONTEXT(skb)->PacketType = pkt_type;
468 }
469
470 // decrease the data length in sk_buffer by len,
471 // and move the content forward to the header.
472 // the data in header will be removed.
skb_pull(OUT sk_buff * skb,IN uint32_t len)473 void skb_pull(OUT sk_buff *skb, IN uint32_t len)
474 {
475 RTK_BUFFER *rtb = (RTK_BUFFER *)skb;
476 RtbRemoveHead(rtb, len);
477 return;
478 }
479
skb_alloc_and_init(IN uint8_t PktType,IN uint8_t * Data,IN uint32_t DataLen)480 sk_buff *skb_alloc_and_init(IN uint8_t PktType, IN uint8_t *Data, IN uint32_t DataLen)
481 {
482 sk_buff *skb = skb_alloc(DataLen);
483 if (skb == NULL) {
484 return NULL;
485 }
486 (void)memcpy_s(skb_put(skb, DataLen), DataLen, Data, DataLen);
487 skb_set_pkt_type(skb, PktType);
488
489 return skb;
490 }
491
skb_queue_head(IN RTB_QUEUE_HEAD * skb_head,IN RTK_BUFFER * skb)492 static void skb_queue_head(IN RTB_QUEUE_HEAD *skb_head, IN RTK_BUFFER *skb)
493 {
494 RtbQueueHead(skb_head, skb);
495 }
496
skb_queue_tail(IN RTB_QUEUE_HEAD * skb_head,IN RTK_BUFFER * skb)497 static void skb_queue_tail(IN RTB_QUEUE_HEAD *skb_head, IN RTK_BUFFER *skb)
498 {
499 RtbQueueTail(skb_head, skb);
500 }
501
skb_dequeue_head(IN RTB_QUEUE_HEAD * skb_head)502 static RTK_BUFFER *skb_dequeue_head(IN RTB_QUEUE_HEAD *skb_head)
503 {
504 return RtbDequeueHead(skb_head);
505 }
506
skb_dequeue_tail(IN RTB_QUEUE_HEAD * skb_head)507 static RTK_BUFFER *skb_dequeue_tail(IN RTB_QUEUE_HEAD *skb_head)
508 {
509 return RtbDequeueTail(skb_head);
510 }
511
skb_queue_get_length(IN RTB_QUEUE_HEAD * skb_head)512 static uint32_t skb_queue_get_length(IN RTB_QUEUE_HEAD *skb_head)
513 {
514 return RtbGetQueueLen(skb_head);
515 }
516
517 /**
518 * Add "d" into crc scope, caculate the new crc value
519 *
520 * @param crc crc data
521 * @param d one byte data
522 */
h5_crc_update(uint16_t * crc,uint8_t d)523 static void h5_crc_update(uint16_t *crc, uint8_t d)
524 {
525 uint16_t reg = *crc;
526
527 #define REG_4 4
528 reg = (reg >> REG_4) ^ crc_table[(reg ^ d) & 0x000f];
529 reg = (reg >> REG_4) ^ crc_table[(reg ^ (d >> REG_4)) & 0x000f];
530
531 *crc = reg;
532 }
533
534 struct __una_u16 {
535 uint16_t x;
536 };
537 /**
538 * Get crc data.
539 *
540 * @param h5 realtek h5 struct
541 * @return crc data
542 */
h5_get_crc(tHCI_H5_CB * h5)543 static uint16_t h5_get_crc(tHCI_H5_CB *h5)
544 {
545 uint16_t crc = 0;
546 uint8_t *data = skb_get_data(h5->rx_skb) + skb_get_data_length(h5->rx_skb) - 2L;
547 crc = data[1] + (data[0] << 8L);
548 return crc;
549 }
550
551 /**
552 * Just add 0xc0 at the end of skb,
553 * we can also use this to add 0xc0 at start while there is no data in skb
554 *
555 * @param skb socket buffer
556 */
h5_slip_msgdelim(sk_buff * skb)557 static void h5_slip_msgdelim(sk_buff *skb)
558 {
559 const char pkt_delim = 0xc0;
560 errno_t ret = -1;
561 if (ret == memcpy_s(skb_put(skb, 1), sizeof(char), &pkt_delim, 1)) {
562 return;
563 }
564 }
565
566 /**
567 * Slip ecode one byte in h5 proto, as follows:
568 * 0xc0 -> 0xdb, 0xdc
569 * 0xdb -> 0xdb, 0xdd
570 * 0x11 -> 0xdb, 0xde
571 * 0x13 -> 0xdb, 0xdf
572 * others will not change
573 *
574 * @param skb socket buffer
575 * @c pure data in the one byte
576 */
h5_slip_one_byte(sk_buff * skb,uint8_t unencode_form)577 static void h5_slip_one_byte(sk_buff *skb, uint8_t unencode_form)
578 {
579 const signed char esc_c0[2] = {0xdb, 0xdc};
580 const signed char esc_db[2] = {0xdb, 0xdd};
581 const signed char esc_11[2] = {0xdb, 0xde};
582 const signed char esc_13[2] = {0xdb, 0xdf};
583 errno_t ret = -1;
584
585 #define SKB_PUT_2 2
586 switch (unencode_form) {
587 case 0xc0:
588 if (ret == memcpy_s(skb_put(skb, SKB_PUT_2), SKB_PUT_2, &esc_c0, SKB_PUT_2)) {
589 return;
590 }
591 break;
592 case 0xdb:
593 if (ret == memcpy_s(skb_put(skb, SKB_PUT_2), SKB_PUT_2, &esc_db, SKB_PUT_2)) {
594 return;
595 }
596 break;
597
598 case 0x11: {
599 if (rtk_h5.oof_flow_control) {
600 (void)memcpy_s(skb_put(skb, SKB_PUT_2), SKB_PUT_2, &esc_11, SKB_PUT_2);
601 } else {
602 (void)memcpy_s(skb_put(skb, 1), sizeof(char), &unencode_form, 1);
603 }
604 }
605 break;
606
607 case 0x13: {
608 if (rtk_h5.oof_flow_control) {
609 (void)memcpy_s(skb_put(skb, SKB_PUT_2), SKB_PUT_2, &esc_13, SKB_PUT_2);
610 } else {
611 (void)memcpy_s(skb_put(skb, 1), sizeof(char), &unencode_form, 1);
612 }
613 }
614 break;
615
616 default:
617 (void)memcpy_s(skb_put(skb, 1), sizeof(char), &unencode_form, 1);
618 }
619 }
620
621 /**
622 * Decode one byte in h5 proto, as follows:
623 * 0xdb, 0xdc -> 0xc0
624 * 0xdb, 0xdd -> 0xdb
625 * 0xdb, 0xde -> 0x11
626 * 0xdb, 0xdf -> 0x13
627 * others will not change
628 *
629 * @param h5 realtek h5 struct
630 * @byte pure data in the one byte
631 */
h5_unslip_one_byte(tHCI_H5_CB * h5,unsigned char byte)632 static void h5_unslip_one_byte(tHCI_H5_CB *h5, unsigned char byte)
633 {
634 const uint8_t c0 = 0xc0, db = 0xdb;
635 const uint8_t oof1 = 0x11, oof2 = 0x13;
636 uint8_t *hdr = (uint8_t *)skb_get_data(h5->rx_skb);
637
638 if (H5_ESCSTATE_NOESC == h5->rx_esc_state) {
639 if (byte == 0xdb) {
640 h5->rx_esc_state = H5_ESCSTATE_ESC;
641 } else {
642 (void)memcpy_s(skb_put(h5->rx_skb, 1), sizeof(char), &byte, 1);
643 // Check Pkt Header's CRC enable bit
644 if (H5_HDR_CRC(hdr) && h5->rx_state != H5_W4_CRC) {
645 h5_crc_update(&h5->message_crc, byte);
646 }
647 h5->rx_count--;
648 }
649 } else if (H5_ESCSTATE_ESC == h5->rx_esc_state) {
650 switch (byte) {
651 case 0xdc:
652 (void)memcpy_s(skb_put(h5->rx_skb, 1), sizeof(char), &c0, 1);
653 if (H5_HDR_CRC(hdr) && h5->rx_state != H5_W4_CRC) {
654 h5_crc_update(&h5->message_crc, 0xc0);
655 }
656 h5->rx_esc_state = H5_ESCSTATE_NOESC;
657 h5->rx_count--;
658 break;
659 case 0xdd:
660 (void)memcpy_s(skb_put(h5->rx_skb, 1), sizeof(char), &db, 1);
661 if (H5_HDR_CRC(hdr) && h5->rx_state != H5_W4_CRC) {
662 h5_crc_update(&h5->message_crc, 0xdb);
663 }
664 h5->rx_esc_state = H5_ESCSTATE_NOESC;
665 h5->rx_count--;
666 break;
667 case 0xde:
668 (void)memcpy_s(skb_put(h5->rx_skb, 1), sizeof(char), &oof1, 1);
669 if (H5_HDR_CRC(hdr) && h5->rx_state != H5_W4_CRC) {
670 h5_crc_update(&h5->message_crc, oof1);
671 }
672 h5->rx_esc_state = H5_ESCSTATE_NOESC;
673 h5->rx_count--;
674 break;
675 case 0xdf:
676 (void)memcpy_s(skb_put(h5->rx_skb, 1), sizeof(char), &oof2, 1);
677 if (H5_HDR_CRC(hdr) && h5->rx_state != H5_W4_CRC) {
678 h5_crc_update(&h5->message_crc, oof2);
679 }
680 h5->rx_esc_state = H5_ESCSTATE_NOESC;
681 h5->rx_count--;
682 break;
683 default:
684 HILOGE("Error: Invalid byte %02x after esc byte", byte);
685 skb_free(&h5->rx_skb);
686 h5->rx_skb = NULL;
687 h5->rx_state = H5_W4_PKT_DELIMITER;
688 h5->rx_count = 0;
689 break;
690 }
691 }
692 }
693 /**
694 * Prepare h5 packet, packet format as follow:
695 * | LSB 4 octets | 0 ~4095| 2 MSB
696 * |packet header | payload | data integrity check |
697 *
698 * pakcket header fromat is show below:
699 * | LSB 3 bits | 3 bits | 1 bits | 1 bits |
700 * | 4 bits | 12 bits | 8 bits MSB
701 * |sequence number | acknowledgement number | data integrity check present | reliable packet |
702 * |packet type | payload length | header checksum
703 *
704 * @param h5 realtek h5 struct
705 * @param data pure data
706 * @param len the length of data
707 * @param pkt_type packet type
708 * @return socket buff after prepare in h5 proto
709 */
h5_prepare_pkt(tHCI_H5_CB * h5,uint8_t * data,signed long len,signed long pkt_type)710 static sk_buff *h5_prepare_pkt(tHCI_H5_CB *h5, uint8_t *data, signed long len, signed long pkt_type)
711 {
712 sk_buff *nskb;
713 uint8_t hdr[4];
714 uint16_t H5_CRC_INIT(h5_txmsg_crc);
715 int rel, i;
716
717 switch (pkt_type) {
718 case HCI_ACLDATA_PKT:
719 case HCI_COMMAND_PKT:
720 case HCI_EVENT_PKT:
721 rel = H5_RELIABLE_PKT; // reliable
722 break;
723 case H5_ACK_PKT:
724 case H5_VDRSPEC_PKT:
725 case H5_LINK_CTL_PKT:
726 case HCI_SCODATA_PKT:
727 rel = H5_UNRELIABLE_PKT; // unreliable
728 break;
729 default:
730 HILOGE("Unknown packet type");
731 return NULL;
732 }
733
734 // Max len of packet: (original len +4(h5 hdr) +2(crc))*2
735 // (because bytes 0xc0 and 0xdb are escaped, worst case is
736 // when the packet is all made of 0xc0 and 0xdb :) )
737 // + 2 (0xc0 delimiters at start and end).
738
739 #define SKB_2 2
740 #define SKB_3 3
741 #define SKB_4 4
742 #define SKB_6 6
743 #define SKB_8 8
744 nskb = skb_alloc((len + SKB_6) * SKB_2 + SKB_2);
745 if (!nskb) {
746 H5LogMsg("nskb is NULL");
747 return NULL;
748 }
749
750 // Add SLIP start byte: 0xc0
751 h5_slip_msgdelim(nskb);
752 // set AckNumber in SlipHeader
753 hdr[0] = h5->rxseq_txack << SKB_3;
754 h5->is_txack_req = 0;
755
756 H5LogMsg("We request packet no(%u) to card", h5->rxseq_txack);
757 H5LogMsg("Sending packet with seqno %u and wait %u", h5->msgq_txseq, h5->rxseq_txack);
758 if (rel == H5_RELIABLE_PKT) {
759 // set reliable pkt bit and SeqNumber
760 hdr[0] |= 0x80 + h5->msgq_txseq;
761 ++(h5->msgq_txseq);
762 h5->msgq_txseq = (h5->msgq_txseq) & 0x07;
763 }
764
765 // set DicPresent bit
766 if (h5->use_crc) {
767 hdr[0] |= 0x40;
768 }
769
770 // set packet type and payload length
771 hdr[1] = ((len << SKB_4) & 0xff) | pkt_type;
772 hdr[SKB_2] = (uint8_t)(len >> SKB_4);
773 // set checksum
774 hdr[SKB_3] = ~(hdr[0] + hdr[1] + hdr[SKB_2]);
775
776 // Put h5 header */
777 for (i = 0; i < SKB_4; i++) {
778 h5_slip_one_byte(nskb, hdr[i]);
779
780 if (h5->use_crc) {
781 h5_crc_update(&h5_txmsg_crc, hdr[i]);
782 }
783 }
784
785 // Put payload */
786 for (i = 0; i < len; i++) {
787 h5_slip_one_byte(nskb, data[i]);
788
789 if (h5->use_crc) {
790 h5_crc_update(&h5_txmsg_crc, data[i]);
791 }
792 }
793
794 // Put CRC */
795 if (h5->use_crc) {
796 h5_txmsg_crc = bit_rev16(h5_txmsg_crc);
797 h5_slip_one_byte(nskb, (uint8_t)((h5_txmsg_crc >> SKB_8) & 0x00ff));
798 h5_slip_one_byte(nskb, (uint8_t)(h5_txmsg_crc & 0x00ff));
799 }
800
801 // Add SLIP end byte: 0xc0
802 h5_slip_msgdelim(nskb);
803 return nskb;
804 }
805 /**
806 * Removed controller acked packet from Host's unacked lists
807 *
808 * @param h5 realtek h5 struct
809 */
h5_remove_acked_pkt(tHCI_H5_CB * h5)810 static void h5_remove_acked_pkt(tHCI_H5_CB *h5)
811 {
812 RT_LIST_HEAD *Head = NULL;
813 RT_LIST_ENTRY *Iter = NULL, *Temp = NULL;
814 RTK_BUFFER *skb = NULL;
815
816 int pkts_to_be_removed = 0;
817 int seqno = 0;
818 int i = 0;
819
820 pthread_mutex_lock(&h5_wakeup_mutex);
821
822 seqno = h5->msgq_txseq;
823 pkts_to_be_removed = RtbGetQueueLen(h5->unack);
824
825 while (pkts_to_be_removed) {
826 if (h5->rxack == seqno) {
827 break;
828 }
829
830 pkts_to_be_removed--;
831 seqno = (seqno - 1) & 0x07;
832 }
833
834 if (h5->rxack != seqno) {
835 H5LogMsg("Peer acked invalid packet");
836 }
837
838 // remove ack'ed packet from bcsp->unack queue
839 i = 0; // number of pkts has been removed from un_ack queue.
840 Head = (RT_LIST_HEAD *)(h5->unack);
841 LIST_FOR_EACH_SAFELY(Iter, Temp, Head)
842 {
843 skb = LIST_ENTRY(Iter, sk_buff, List);
844 if (i >= pkts_to_be_removed) {
845 break;
846 }
847
848 skb_unlink(skb, h5->unack);
849 skb_free(&skb);
850 i++;
851 }
852
853 if (skb_queue_get_length(h5->unack) == 0) {
854 h5_stop_data_retrans_timer();
855 rtk_h5.data_retrans_count = 0;
856 }
857
858 if (i != pkts_to_be_removed) {
859 H5LogMsg("Removed only (%u) out of (%u) pkts", i, pkts_to_be_removed);
860 }
861
862 pthread_mutex_unlock(&h5_wakeup_mutex);
863 }
864
hci_h5_send_sync_req(void)865 static void hci_h5_send_sync_req(void)
866 {
867 unsigned char h5sync[2] = {0x01, 0x7E};
868 sk_buff *skb = NULL;
869
870 skb = skb_alloc_and_init(H5_LINK_CTL_PKT, h5sync, sizeof(h5sync));
871 if (!skb) {
872 HILOGE("skb_alloc_and_init fail!");
873 return;
874 }
875 H5LogMsg("H5: --->>>send sync req");
876
877 h5_enqueue(skb);
878 h5_wake_up();
879
880 return;
881 }
882
hci_h5_send_sync_resp(void)883 static void hci_h5_send_sync_resp(void)
884 {
885 unsigned char h5syncresp[2] = {0x02, 0x7D};
886 sk_buff *skb = NULL;
887
888 skb = skb_alloc_and_init(H5_LINK_CTL_PKT, h5syncresp, sizeof(h5syncresp));
889 if (!skb) {
890 HILOGE("skb_alloc_and_init fail!");
891 return;
892 }
893
894 H5LogMsg("H5: --->>>send sync resp");
895 h5_enqueue(skb);
896 h5_wake_up();
897
898 return;
899 }
900
hci_h5_send_conf_req(void)901 static void hci_h5_send_conf_req(void)
902 {
903 unsigned char h5conf[3] = {0x03, 0xFC, 0x14};
904 sk_buff *skb = NULL;
905
906 skb = skb_alloc_and_init(H5_LINK_CTL_PKT, h5conf, sizeof(h5conf));
907 if (!skb) {
908 HILOGE("skb_alloc_and_init fail!");
909 return;
910 }
911
912 H5LogMsg("H5: --->>>send conf req");
913 h5_enqueue(skb);
914 h5_wake_up();
915
916 return;
917 }
918
hci_h5_send_conf_resp(void)919 static void hci_h5_send_conf_resp(void)
920 {
921 unsigned char h5confresp[2] = {0x04, 0x7B};
922 sk_buff *skb = NULL;
923
924 skb = skb_alloc_and_init(H5_LINK_CTL_PKT, h5confresp, sizeof(h5confresp));
925 if (!skb) {
926 HILOGE("skb_alloc_and_init fail!");
927 return;
928 }
929
930 H5LogMsg("H5: --->>>send conf resp");
931 h5_enqueue(skb);
932 h5_wake_up();
933
934 return;
935 }
936
rtk_notify_hw_h5_init_result(uint8_t status)937 static void rtk_notify_hw_h5_init_result(uint8_t status)
938 {
939 H5LogMsg("rtk_notify_hw_h5_init_result %d", status);
940 uint8_t sync_event[6] = {0x0e, 0x04, 0x03, 0xee, 0xfc, status};
941 // we need to make a sync event to bt
942 sk_buff *rx_skb;
943 rx_skb = skb_alloc_and_init(HCI_EVENT_PKT, sync_event, sizeof(sync_event));
944 if (!rx_skb) {
945 HILOGE("%s, rx_skb alloc fail!", __func__);
946 return;
947 }
948 pthread_mutex_lock(&rtk_h5.data_mutex);
949 skb_queue_tail(rtk_h5.recv_data, rx_skb);
950 pthread_cond_signal(&rtk_h5.data_cond);
951 pthread_mutex_unlock(&rtk_h5.data_mutex);
952 }
953
h5_dequeue(void)954 static sk_buff *h5_dequeue(void)
955 {
956 sk_buff *skb = NULL;
957 // First of all, check for unreliable messages in the queue,
958 // since they have higher priority
959 if ((skb = (sk_buff *)skb_dequeue_head(rtk_h5.unrel)) != NULL) {
960 sk_buff *nskb = h5_prepare_pkt(&rtk_h5, skb_get_data(skb), skb_get_data_length(skb), skb_get_pkt_type(skb));
961 if (nskb) {
962 skb_free(&skb);
963 return nskb;
964 } else {
965 skb_queue_head(rtk_h5.unrel, skb);
966 }
967 }
968 // Now, try to send a reliable pkt. We can only send a
969 // reliable packet if the number of packets sent but not yet ack'ed
970 // is < than the winsize
971
972 if (RtbGetQueueLen(rtk_h5.unack) < rtk_h5.sliding_window_size &&
973 (skb = (sk_buff *)skb_dequeue_head(rtk_h5.rel)) != NULL) {
974 sk_buff *nskb = h5_prepare_pkt(&rtk_h5, skb_get_data(skb), skb_get_data_length(skb), skb_get_pkt_type(skb));
975 if (nskb) {
976 skb_queue_tail(rtk_h5.unack, skb);
977 h5_start_data_retrans_timer();
978 return nskb;
979 } else {
980 skb_queue_head(rtk_h5.rel, skb);
981 }
982 }
983 // We could not send a reliable packet, either because there are
984 // none or because there are too many unack'ed packets. Did we receive
985 // any packets we have not acknowledged yet
986 if (rtk_h5.is_txack_req) {
987 // if so, craft an empty ACK pkt and send it on BCSP unreliable
988 // channel
989 sk_buff *nskb = h5_prepare_pkt(&rtk_h5, NULL, 0, H5_ACK_PKT);
990 return nskb;
991 }
992 // We have nothing to send
993 return NULL;
994 }
995
h5_enqueue(IN sk_buff * skb)996 int h5_enqueue(IN sk_buff *skb)
997 {
998 // Pkt length must be less than 4095 bytes
999 if (skb_get_data_length(skb) > 0xFFF) {
1000 HILOGE("skb len > 0xFFF");
1001 skb_free(&skb);
1002 return 0;
1003 }
1004
1005 switch (skb_get_pkt_type(skb)) {
1006 case HCI_ACLDATA_PKT:
1007 case HCI_COMMAND_PKT:
1008 skb_queue_tail(rtk_h5.rel, skb);
1009 break;
1010
1011 case H5_LINK_CTL_PKT:
1012 case H5_ACK_PKT:
1013 case H5_VDRSPEC_PKT:
1014 case HCI_SCODATA_PKT:
1015 skb_queue_tail(rtk_h5.unrel, skb); /* 3-wire LinkEstablishment */
1016 break;
1017 default:
1018 skb_free(&skb);
1019 break;
1020 }
1021 return 0;
1022 }
1023
h5_wake_up(void)1024 static uint16_t h5_wake_up(void)
1025 {
1026 uint16_t bytes_sent = 0;
1027 sk_buff *skb = NULL;
1028 uint8_t *data = NULL;
1029 uint32_t data_len = 0;
1030
1031 pthread_mutex_lock(&h5_wakeup_mutex);
1032 while (NULL != (skb = h5_dequeue())) {
1033 data = skb_get_data(skb);
1034 data_len = skb_get_data_length(skb);
1035 // we adopt the hci_h5 interface to send data
1036 bytes_sent = h5_int_hal_callbacks->h5_int_transmit_data_cb(DATA_TYPE_H5, data, data_len);
1037
1038 H5LogMsg("bytes_sent(%d)", bytes_sent);
1039
1040 #if H5_TRACE_DATA_ENABLE
1041 {
1042 uint32_t iTemp = 0;
1043 uint32_t iTempTotal = 16;
1044 H5LogMsg("H5 TX: length(%d)", data_len);
1045 if (iTempTotal > data_len) {
1046 iTempTotal = data_len;
1047 }
1048 for (iTemp = 0; iTemp < iTempTotal; iTemp++) {
1049 H5LogMsg("0x%x", data[iTemp]);
1050 }
1051 }
1052 #endif
1053 skb_free(&skb);
1054 }
1055
1056 pthread_mutex_unlock(&h5_wakeup_mutex);
1057 return bytes_sent;
1058 }
1059
h5_process_ctl_pkts(void)1060 void h5_process_ctl_pkts(void)
1061 {
1062 // process h5 link establish
1063 uint8_t cfg;
1064
1065 sk_buff *skb = rtk_h5.rx_skb;
1066
1067 unsigned char h5sync[2] = {0x01, 0x7E}, h5syncresp[2] = {0x02, 0x7D}, h5conf[3] = {0x03, 0xFC, 0x14},
1068 h5confresp[2] = {0x04, 0x7B};
1069
1070 #define MEM_2 2
1071 if (rtk_h5.link_estab_state == H5_UNINITIALIZED) { // sync
1072 if (!memcmp(skb_get_data(skb), h5sync, MEM_2)) {
1073 H5LogMsg("H5: <<<---recv sync req");
1074 hci_h5_send_sync_resp();
1075 } else if (!memcmp(skb_get_data(skb), h5syncresp, MEM_2)) {
1076 H5LogMsg("H5: <<<---recv sync resp");
1077 h5_stop_sync_retrans_timer();
1078 rtk_h5.sync_retrans_count = 0;
1079 rtk_h5.link_estab_state = H5_INITIALIZED;
1080
1081 // send config req
1082 hci_h5_send_conf_req();
1083 h5_start_conf_retrans_timer();
1084 }
1085 } else if (rtk_h5.link_estab_state == H5_INITIALIZED) { // config
1086 if (!memcmp(skb_get_data(skb), h5sync, 0x2)) {
1087 H5LogMsg("H5: <<<---recv sync req in H5_INITIALIZED");
1088 hci_h5_send_sync_resp();
1089 } else if (!memcmp(skb_get_data(skb), h5conf, 0x2)) {
1090 H5LogMsg("H5: <<<---recv conf req");
1091 hci_h5_send_conf_resp();
1092 } else if (!memcmp(skb_get_data(skb), h5confresp, 0x2)) {
1093 H5LogMsg("H5: <<<---recv conf resp");
1094 h5_stop_conf_retrans_timer();
1095 rtk_h5.conf_retrans_count = 0;
1096
1097 rtk_h5.link_estab_state = H5_ACTIVE;
1098 // notify hw to download patch
1099
1100 (void)memcpy_s(&cfg, H5_CFG_SIZE, skb_get_data(skb) + MEM_2, H5_CFG_SIZE);
1101 rtk_h5.sliding_window_size = H5_CFG_SLID_WIN(cfg);
1102 rtk_h5.oof_flow_control = H5_CFG_OOF_CNTRL(cfg);
1103 rtk_h5.dic_type = H5_CFG_DIC_TYPE(cfg);
1104 H5LogMsg("rtk_h5.sliding_window_size(%d), oof_flow_control(%d), dic_type(%d)", rtk_h5.sliding_window_size,
1105 rtk_h5.oof_flow_control, rtk_h5.dic_type);
1106 if (rtk_h5.dic_type) {
1107 rtk_h5.use_crc = 1;
1108 }
1109
1110 rtk_notify_hw_h5_init_result(0);
1111 } else {
1112 H5LogMsg("H5_INITIALIZED receive event, ingnore");
1113 }
1114 } else if (rtk_h5.link_estab_state == H5_ACTIVE) {
1115 if (!memcmp(skb_get_data(skb), h5sync, 0x2)) {
1116 H5LogMsg("H5: <<<---recv sync req in H5_ACTIVE");
1117 rtkbt_h5_send_hw_error();
1118 hci_h5_send_sync_resp();
1119 H5LogMsg("H5 : H5_ACTIVE transit to H5_UNINITIALIZED");
1120 rtk_h5.link_estab_state = H5_UNINITIALIZED;
1121 hci_h5_send_sync_req();
1122 h5_start_sync_retrans_timer();
1123 } else if (!memcmp(skb_get_data(skb), h5conf, 0x2)) {
1124 H5LogMsg("H5: <<<---recv conf req in H5_ACTIVE");
1125 hci_h5_send_conf_resp();
1126 } else if (!memcmp(skb_get_data(skb), h5confresp, 0x2)) {
1127 H5LogMsg("H5: <<<---recv conf resp in H5_ACTIVE, discard");
1128 } else {
1129 H5LogMsg("H5_ACTIVE receive unknown link control msg, ingnore");
1130 }
1131 }
1132 }
1133
isRtkInternalCommand(uint16_t opcode)1134 uint8_t isRtkInternalCommand(uint16_t opcode)
1135 {
1136 if (opcode == 0xFC17 || opcode == 0xFC6D || opcode == 0xFC61 || opcode == 0xFC20) {
1137 return 1;
1138 } else {
1139 return 0;
1140 }
1141 }
1142
1143 /*****************************************************************************
1144 * Check if it's a hci frame, if it is, complete it with response or parse the cmd complete event
1145 *
1146 * @param skb socket buffer
1147 *
1148 ******************************************************************************/
hci_recv_frame(sk_buff * skb,uint8_t pkt_type)1149 static uint8_t hci_recv_frame(sk_buff *skb, uint8_t pkt_type)
1150 {
1151 uint8_t intercepted = 0;
1152 #if H5_TRACE_DATA_ENABLE
1153 uint8_t *data = skb_get_data(skb);
1154 #endif
1155 uint32_t data_len = skb_get_data_length(skb);
1156
1157 H5LogMsg("UART H5 RX: length = %d", data_len);
1158
1159 #if H5_TRACE_DATA_ENABLE
1160 {
1161 uint32_t iTemp = 0;
1162 uint32_t iTempTotal = 16;
1163 H5LogMsg("H5 RX: length(%d)", data_len);
1164 if (iTempTotal > data_len) {
1165 iTempTotal = data_len;
1166 }
1167 for (iTemp = 0; iTemp < iTempTotal; iTemp++) {
1168 H5LogMsg("0x%x", data[iTemp]);
1169 }
1170 }
1171 #endif
1172 // we only intercept evt packet here
1173 if (pkt_type == HCI_EVENT_PKT) {
1174 uint8_t *p;
1175 uint8_t event_code;
1176 uint16_t opcode, len;
1177 p = (uint8_t *)skb_get_data(skb);
1178
1179 event_code = *p++;
1180 len = *p++;
1181 H5LogMsg("hci_recv_frame event_code(0x%x), len = %d", event_code, len);
1182 if (event_code == HCI_COMMAND_COMPLETE_EVT) {
1183 num_hci_cmd_pkts = *p++;
1184 STREAM_TO_UINT16(opcode, p);
1185
1186 if (opcode == HCI_VSC_UPDATE_BAUDRATE) {
1187 intercepted = 1;
1188 rtk_h5.internal_skb = skb;
1189 H5LogMsg("CommandCompleteEvent for command h5_start_wait_controller_baudrate_ready_timer (0x%04X)",
1190 opcode);
1191 h5_start_wait_controller_baudrate_ready_timer();
1192 }
1193 }
1194 }
1195
1196 H5LogMsg("hci_recv_frame intercepted = %d", intercepted);
1197 return intercepted;
1198 }
1199
1200 /**
1201 * after rx data is parsed, and we got a rx frame saved in h5->rx_skb,
1202 * this routinue is called.
1203 * things todo in this function:
1204 * 1. check if it's a hci frame, if it is, complete it with response or ack
1205 * 2. see the ack number, free acked frame in queue
1206 * 3. reset h5->rx_state, set rx_skb to null.
1207 *
1208 * @param h5 realtek h5 struct
1209 *
1210 */
h5_complete_rx_pkt(tHCI_H5_CB * h5)1211 static uint8_t h5_complete_rx_pkt(tHCI_H5_CB *h5)
1212 {
1213 int pass_up = 1;
1214 uint16_t eventtype = 0;
1215 uint8_t *h5_hdr = NULL;
1216 uint8_t pkt_type = 0;
1217 uint8_t status = 0;
1218
1219 h5_hdr = (uint8_t *)skb_get_data(h5->rx_skb);
1220 H5LogMsg("SeqNumber(%d), AckNumber(%d)", H5_HDR_SEQ(h5_hdr), H5_HDR_ACK(h5_hdr));
1221
1222 #if H5_TRACE_DATA_ENABLE
1223 {
1224 uint32_t iTemp = 0;
1225 uint32_t iTempTotal = 16;
1226 uint32_t data_len = skb_get_data_length(h5->rx_skb);
1227 uint8_t *data = skb_get_data(h5->rx_skb);
1228 H5LogMsg("H5 RX: length(%d)", data_len);
1229
1230 if (iTempTotal > data_len) {
1231 iTempTotal = data_len;
1232 }
1233 for (iTemp = 0; iTemp < iTempTotal; iTemp++) {
1234 H5LogMsg("0x%x", data[iTemp]);
1235 }
1236 }
1237 #endif
1238
1239 if (H5_HDR_RELIABLE(h5_hdr)) {
1240 H5LogMsg("Received reliable seqno %u from card", h5->rxseq_txack);
1241 pthread_mutex_lock(&h5_wakeup_mutex);
1242 h5->rxseq_txack = H5_HDR_SEQ(h5_hdr) + 1;
1243 #define NUM_8 8
1244 h5->rxseq_txack %= NUM_8;
1245 h5->is_txack_req = 1;
1246 pthread_mutex_unlock(&h5_wakeup_mutex);
1247 // send down an empty ack if needed.
1248 h5_wake_up();
1249 }
1250
1251 h5->rxack = H5_HDR_ACK(h5_hdr);
1252 pkt_type = H5_HDR_PKT_TYPE(h5_hdr);
1253 switch (pkt_type) {
1254 case HCI_ACLDATA_PKT:
1255 pass_up = 1;
1256 eventtype = MSG_HC_TO_STACK_HCI_ACL;
1257 break;
1258
1259 case HCI_EVENT_PKT:
1260 pass_up = 1;
1261 eventtype = MSG_HC_TO_STACK_HCI_EVT;
1262 break;
1263
1264 case HCI_SCODATA_PKT:
1265 pass_up = 1;
1266 eventtype = MSG_HC_TO_STACK_HCI_SCO;
1267 break;
1268 case HCI_COMMAND_PKT:
1269 pass_up = 1;
1270 eventtype = MSG_HC_TO_STACK_HCI_ERR;
1271 break;
1272
1273 case H5_LINK_CTL_PKT:
1274 pass_up = 0;
1275 break;
1276
1277 case H5_ACK_PKT:
1278 pass_up = 0;
1279 break;
1280
1281 default:
1282 HILOGE("Unknown pkt type(%d)", H5_HDR_PKT_TYPE(h5_hdr));
1283 eventtype = MSG_HC_TO_STACK_HCI_ERR;
1284 pass_up = 0;
1285 break;
1286 }
1287
1288 // remove h5 header and send packet to hci
1289 h5_remove_acked_pkt(h5);
1290
1291 if (H5_HDR_PKT_TYPE(h5_hdr) == H5_LINK_CTL_PKT) {
1292 skb_pull(h5->rx_skb, H5_HDR_SIZE);
1293 h5_process_ctl_pkts();
1294 }
1295
1296 // decide if we need to pass up.
1297 if (pass_up) {
1298 skb_pull(h5->rx_skb, H5_HDR_SIZE);
1299 skb_set_pkt_type(h5->rx_skb, pkt_type);
1300
1301 // send command or acl data it to bluedroid stack
1302 uint16_t len = 0;
1303 sk_buff *skb_complete_pkt = h5->rx_skb;
1304
1305 /* Allocate a buffer for message */
1306
1307 len = BT_HC_HDR_SIZE + skb_get_data_length(skb_complete_pkt);
1308 h5->p_rcv_msg = (HC_BT_HDR *)malloc(len);
1309
1310 if (h5->p_rcv_msg) {
1311 /* Initialize buffer with received h5 data */
1312 h5->p_rcv_msg->offset = 0;
1313 h5->p_rcv_msg->layer_specific = 0;
1314 h5->p_rcv_msg->event = eventtype;
1315 h5->p_rcv_msg->len = skb_get_data_length(skb_complete_pkt);
1316 (void)memcpy_s((uint8_t *)(h5->p_rcv_msg + 1), skb_get_data_length(skb_complete_pkt),
1317 skb_get_data(skb_complete_pkt), skb_get_data_length(skb_complete_pkt));
1318 }
1319
1320 status = hci_recv_frame(skb_complete_pkt, pkt_type);
1321
1322 if (h5->p_rcv_msg) {
1323 free(h5->p_rcv_msg);
1324 }
1325
1326 if (!status) {
1327 pthread_mutex_lock(&rtk_h5.data_mutex);
1328 skb_queue_tail(rtk_h5.recv_data, h5->rx_skb);
1329 pthread_cond_signal(&rtk_h5.data_cond);
1330 pthread_mutex_unlock(&rtk_h5.data_mutex);
1331 }
1332 } else {
1333 // free ctl packet
1334 skb_free(&h5->rx_skb);
1335 }
1336 h5->rx_state = H5_W4_PKT_DELIMITER;
1337 rtk_h5.rx_skb = NULL;
1338 return pkt_type;
1339 }
1340
1341 /**
1342 * Parse the receive data in h5 proto.
1343 *
1344 * @param h5 realtek h5 struct
1345 * @param data point to data received before parse
1346 * @param count num of data
1347 * @return reserved count
1348 */
h5_recv(tHCI_H5_CB * h5,uint8_t * data,int count)1349 static bool h5_recv(tHCI_H5_CB *h5, uint8_t *data, int count)
1350 {
1351 uint8_t *ptr;
1352 uint8_t *skb_data = NULL;
1353 uint8_t *hdr = NULL;
1354 int temp = count;
1355 bool complete_packet = false;
1356
1357 ptr = (uint8_t *)data;
1358 while (temp) {
1359 if (h5->rx_count) {
1360 if (*ptr == 0xc0) {
1361 HILOGE("short h5 packet");
1362 skb_free(&h5->rx_skb);
1363 h5->rx_state = H5_W4_PKT_START;
1364 h5->rx_count = 0;
1365 } else {
1366 h5_unslip_one_byte(h5, *ptr);
1367 }
1368
1369 ptr++;
1370 temp--;
1371 continue;
1372 }
1373
1374 switch (h5->rx_state) {
1375 case H5_W4_HDR:
1376 // check header checksum. see Core Spec V4 "3-wire uart" page 67
1377 skb_data = skb_get_data(h5->rx_skb);
1378 hdr = (uint8_t *)skb_data;
1379
1380 #define SKB_DATA_2 2
1381 #define SKB_DATA_3 3
1382 if ((0xff & (uint8_t) ~(skb_data[0] + skb_data[1] + skb_data[SKB_DATA_2])) != skb_data[SKB_DATA_3]) {
1383 HILOGE("h5 hdr checksum error!!!");
1384 skb_free(&h5->rx_skb);
1385 h5->rx_state = H5_W4_PKT_DELIMITER;
1386 h5->rx_count = 0;
1387 continue;
1388 }
1389
1390 if (H5_HDR_RELIABLE(hdr) && (H5_HDR_SEQ(hdr) != h5->rxseq_txack)) {
1391 HILOGE("Out-of-order packet arrived, got(%u)expected(%u)", H5_HDR_SEQ(hdr), h5->rxseq_txack);
1392 h5->is_txack_req = 1;
1393 h5_wake_up();
1394
1395 skb_free(&h5->rx_skb);
1396 h5->rx_state = H5_W4_PKT_DELIMITER;
1397 h5->rx_count = 0;
1398
1399 continue;
1400 }
1401 h5->rx_state = H5_W4_DATA;
1402 // payload length: May be 0
1403 h5->rx_count = H5_HDR_LEN(hdr);
1404 continue;
1405 case H5_W4_DATA:
1406 hdr = (uint8_t *)skb_get_data(h5->rx_skb);
1407 if (H5_HDR_CRC(hdr)) { // pkt with crc /
1408 h5->rx_state = H5_W4_CRC;
1409 #define RX_COUNT_2 2
1410 h5->rx_count = RX_COUNT_2;
1411 } else {
1412 h5_complete_rx_pkt(h5); // Send ACK
1413 complete_packet = true;
1414 H5LogMsg("--------> H5_W4_DATA ACK\n");
1415 }
1416 continue;
1417
1418 case H5_W4_CRC:
1419 if (bit_rev16(h5->message_crc) != h5_get_crc(h5)) {
1420 HILOGE("Checksum failed, computed(%04x)received(%04x)", bit_rev16(h5->message_crc), h5_get_crc(h5));
1421 skb_free(&h5->rx_skb);
1422 h5->rx_state = H5_W4_PKT_DELIMITER;
1423 h5->rx_count = 0;
1424 continue;
1425 }
1426 #define SKB_GET_LENTH_2 2
1427 skb_trim(h5->rx_skb, skb_get_data_length(h5->rx_skb) - SKB_GET_LENTH_2);
1428 h5_complete_rx_pkt(h5);
1429 complete_packet = true;
1430 continue;
1431
1432 case H5_W4_PKT_DELIMITER:
1433 switch (*ptr) {
1434 case 0xc0:
1435 h5->rx_state = H5_W4_PKT_START;
1436 break;
1437 default:
1438 break;
1439 }
1440 ptr++;
1441 temp--;
1442 break;
1443
1444 case H5_W4_PKT_START:
1445 switch (*ptr) {
1446 case 0xc0:
1447 ptr++;
1448 temp--;
1449 break;
1450 default:
1451 h5->rx_state = H5_W4_HDR;
1452 #define RX_COUNT_4 4
1453 h5->rx_count = RX_COUNT_4;
1454 h5->rx_esc_state = H5_ESCSTATE_NOESC;
1455 H5_CRC_INIT(h5->message_crc);
1456
1457 // Do not increment ptr or decrement count
1458 // Allocate packet. Max len of a H5 pkt=
1459 // 0xFFF (payload) +4 (header) +2 (crc)
1460 h5->rx_skb = skb_alloc(0x1005);
1461 if (!h5->rx_skb) {
1462 h5->rx_state = H5_W4_PKT_DELIMITER;
1463 h5->rx_count = 0;
1464 return false;
1465 }
1466 break;
1467 }
1468 break;
1469 }
1470 }
1471 return complete_packet;
1472 }
1473
1474 /******************************************************************************
1475 ** Static functions
1476 ******************************************************************************/
data_ready_cb_thread(void * arg)1477 static void data_ready_cb_thread(void *arg)
1478 {
1479 RTK_UNUSED(arg);
1480 sk_buff *skb;
1481 uint8_t pkt_type = 0;
1482 unsigned int total_length = 0;
1483
1484 H5LogMsg("data_ready_cb_thread started");
1485
1486 prctl(PR_SET_NAME, (unsigned long)"data_ready_cb_thread", 0, 0, 0);
1487
1488 while (h5_data_ready_running) {
1489 pthread_mutex_lock(&rtk_h5.data_mutex);
1490 while (h5_data_ready_running && (skb_queue_get_length(rtk_h5.recv_data) == 0)) {
1491 pthread_cond_wait(&rtk_h5.data_cond, &rtk_h5.data_mutex);
1492 }
1493 pthread_mutex_unlock(&rtk_h5.data_mutex);
1494
1495 if (h5_data_ready_running && (skb = skb_dequeue_head(rtk_h5.recv_data)) != NULL) {
1496 rtk_h5.data_skb = skb;
1497 } else {
1498 continue;
1499 }
1500
1501 pkt_type = skb_get_pkt_type(rtk_h5.data_skb);
1502 total_length = skb_get_data_length(rtk_h5.data_skb);
1503 h5_int_hal_callbacks->h5_data_ready_cb(pkt_type, total_length);
1504 }
1505
1506 H5LogMsg("data_ready_cb_thread exiting");
1507 pthread_exit(NULL);
1508 }
1509
data_retransfer_thread(void * arg)1510 static void data_retransfer_thread(void *arg)
1511 {
1512 RTK_UNUSED(arg);
1513 uint16_t events;
1514 uint16_t data_retrans_counts = DATA_RETRANS_COUNT;
1515
1516 H5LogMsg("data_retransfer_thread started");
1517
1518 prctl(PR_SET_NAME, (unsigned long)"data_retransfer_thread", 0, 0, 0);
1519
1520 while (h5_retransfer_running) {
1521 pthread_mutex_lock(&rtk_h5.mutex);
1522 while (h5_ready_events == 0) {
1523 pthread_cond_wait(&rtk_h5.cond, &rtk_h5.mutex);
1524 }
1525 events = h5_ready_events;
1526 h5_ready_events = 0;
1527 pthread_mutex_unlock(&rtk_h5.mutex);
1528
1529 if (events & H5_EVENT_RX) {
1530 sk_buff *skb;
1531 HILOGE("retransmitting (%u) pkts, retransfer count(%d)", skb_queue_get_length(rtk_h5.unack),
1532 rtk_h5.data_retrans_count);
1533 if (h5_init_datatrans_flag == 0) {
1534 data_retrans_counts = DATA_RETRANS_COUNT;
1535 } else {
1536 data_retrans_counts = BT_INIT_DATA_RETRANS_COUNT;
1537 }
1538
1539 if (rtk_h5.data_retrans_count < data_retrans_counts) {
1540 pthread_mutex_lock(&h5_wakeup_mutex);
1541 while ((skb = skb_dequeue_tail(rtk_h5.unack)) != NULL) {
1542 #if H5_TRACE_DATA_ENABLE
1543 uint32_t data_len = skb_get_data_length(skb);
1544 uint8_t *pdata = skb_get_data(skb);
1545 #define DATA_LEN_16 16
1546 if (data_len > DATA_LEN_16) {
1547 data_len = DATA_LEN_16;
1548 }
1549
1550 for (i = 0; i < data_len; i++) {
1551 HILOGE("0x%02X", pdata[i]);
1552 }
1553 #endif
1554 rtk_h5.msgq_txseq = (rtk_h5.msgq_txseq - 1) & 0x07;
1555 skb_queue_head(rtk_h5.rel, skb);
1556 }
1557 pthread_mutex_unlock(&h5_wakeup_mutex);
1558 rtk_h5.data_retrans_count++;
1559 h5_wake_up();
1560 } else {
1561 // do not put packet to rel queue, and do not send
1562 // Kill bluetooth
1563 rtkbt_h5_send_hw_error();
1564 }
1565 } else if (events & H5_EVENT_EXIT) {
1566 break;
1567 }
1568 }
1569
1570 H5LogMsg("data_retransfer_thread exiting");
1571 pthread_exit(NULL);
1572 }
1573
h5_retransfer_signal_event(uint16_t event)1574 void h5_retransfer_signal_event(uint16_t event)
1575 {
1576 pthread_mutex_lock(&rtk_h5.mutex);
1577 h5_ready_events |= event;
1578 pthread_cond_signal(&rtk_h5.cond);
1579 pthread_mutex_unlock(&rtk_h5.mutex);
1580 }
1581
create_data_retransfer_thread(void)1582 static int create_data_retransfer_thread(void)
1583 {
1584 pthread_attr_t thread_attr;
1585
1586 if (h5_retransfer_running) {
1587 HILOGW("create_data_retransfer_thread has been called repeatedly without calling cleanup ?");
1588 }
1589
1590 h5_retransfer_running = 1;
1591 h5_ready_events = 0;
1592
1593 pthread_attr_init(&thread_attr);
1594 pthread_mutex_init(&rtk_h5.mutex, NULL);
1595 pthread_cond_init(&rtk_h5.cond, NULL);
1596
1597 if (pthread_create(&rtk_h5.thread_data_retrans, &thread_attr, (void *)data_retransfer_thread, NULL) != 0) {
1598 HILOGE("pthread_create thread_data_retrans failed!");
1599 h5_retransfer_running = 0;
1600 return -1;
1601 }
1602 return 0;
1603 }
1604
create_data_ready_cb_thread(void)1605 static int create_data_ready_cb_thread(void)
1606 {
1607 pthread_attr_t thread_attr;
1608
1609 if (h5_data_ready_running) {
1610 HILOGW("create_data_ready_cb_thread has been called repeatedly without calling cleanup ?");
1611 }
1612
1613 h5_data_ready_running = 1;
1614
1615 pthread_attr_init(&thread_attr);
1616 pthread_mutex_init(&rtk_h5.data_mutex, NULL);
1617 pthread_cond_init(&rtk_h5.data_cond, NULL);
1618
1619 if (pthread_create(&rtk_h5.thread_data_ready_cb, &thread_attr, (void *)data_ready_cb_thread, NULL) != 0) {
1620 HILOGE("pthread_create thread_data_ready_cb failed!");
1621 h5_data_ready_running = 0;
1622 return -1;
1623 }
1624 return 0;
1625 }
1626
1627 /*****************************************************************************
1628 ** HCI H5 INTERFACE FUNCTIONS
1629 *****************************************************************************/
1630
1631 /*******************************************************************************
1632 **
1633 ** Function hci_h5_init
1634 **
1635 ** Description Initialize H5 module
1636 **
1637 ** Returns None
1638 **
1639 *******************************************************************************/
hci_h5_int_init(hci_h5_callbacks_t * h5_callbacks)1640 void hci_h5_int_init(hci_h5_callbacks_t *h5_callbacks)
1641 {
1642 H5LogMsg("hci_h5_int_init");
1643
1644 h5_int_hal_callbacks = h5_callbacks;
1645 (void)memset_s(&rtk_h5, sizeof(tHCI_H5_CB), 0, sizeof(tHCI_H5_CB));
1646
1647 /* Per HCI spec., always starts with 1 */
1648 num_hci_cmd_pkts = 1;
1649
1650 h5_alloc_data_retrans_timer();
1651 h5_alloc_sync_retrans_timer();
1652 h5_alloc_conf_retrans_timer();
1653 h5_alloc_wait_controller_baudrate_ready_timer();
1654 h5_alloc_hw_init_ready_timer();
1655
1656 rtk_h5.thread_data_retrans = (pthread_t)-1;
1657
1658 rtk_h5.recv_data = RtbQueueInit();
1659
1660 if (create_data_ready_cb_thread() != 0) {
1661 HILOGE("H5 create_data_ready_cb_thread failed");
1662 }
1663
1664 if (create_data_retransfer_thread() != 0) {
1665 HILOGE("H5 create_data_retransfer_thread failed");
1666 }
1667
1668 rtk_h5.unack = RtbQueueInit();
1669 rtk_h5.rel = RtbQueueInit();
1670 rtk_h5.unrel = RtbQueueInit();
1671
1672 rtk_h5.rx_state = H5_W4_PKT_DELIMITER;
1673 rtk_h5.rx_esc_state = H5_ESCSTATE_NOESC;
1674
1675 h5_init_datatrans_flag = 1;
1676 }
1677
1678 /*******************************************************************************
1679 **
1680 ** Function hci_h5_cleanup
1681 **
1682 ** Description Clean H5 module
1683 **
1684 ** Returns None
1685 **
1686 *******************************************************************************/
hci_h5_cleanup(void)1687 void hci_h5_cleanup(void)
1688 {
1689 H5LogMsg("hci_h5_cleanup");
1690 int result;
1691
1692 rtk_h5.cleanuping = 1;
1693
1694 h5_free_data_retrans_timer();
1695 h5_free_sync_retrans_timer();
1696 h5_free_conf_retrans_timer();
1697 h5_free_wait_controller_baudrate_ready_timer();
1698 h5_free_hw_init_ready_timer();
1699
1700 if (h5_data_ready_running) {
1701 h5_data_ready_running = 0;
1702 pthread_mutex_lock(&rtk_h5.data_mutex);
1703 pthread_cond_signal(&rtk_h5.data_cond);
1704 pthread_mutex_unlock(&rtk_h5.data_mutex);
1705 if ((result = pthread_join(rtk_h5.thread_data_ready_cb, NULL)) < 0) {
1706 HILOGE("H5 thread_data_ready_cb pthread_join() FAILED result:%d", result);
1707 }
1708 }
1709
1710 if (h5_retransfer_running) {
1711 h5_retransfer_running = 0;
1712 h5_retransfer_signal_event(H5_EVENT_EXIT);
1713 if ((result = pthread_join(rtk_h5.thread_data_retrans, NULL)) < 0) {
1714 HILOGE("H5 pthread_join() FAILED result:%d", result);
1715 }
1716 }
1717
1718 pthread_mutex_destroy(&rtk_h5.mutex);
1719 pthread_mutex_destroy(&rtk_h5.data_mutex);
1720 pthread_cond_destroy(&rtk_h5.cond);
1721 pthread_cond_destroy(&rtk_h5.data_cond);
1722
1723 RtbQueueFree(rtk_h5.unack);
1724 RtbQueueFree(rtk_h5.rel);
1725 RtbQueueFree(rtk_h5.unrel);
1726
1727 h5_int_hal_callbacks = NULL;
1728 rtk_h5.internal_skb = NULL;
1729 }
1730
1731 /*******************************************************************************
1732 **
1733 ** Function hci_h5_receive_msg
1734 **
1735 ** Description Construct HCI EVENT/ACL packets and send them to stack once
1736 ** complete packet has been received.
1737 **
1738 ** Returns Number of read bytes
1739 **
1740 *******************************************************************************/
hci_h5_receive_msg(uint8_t * byte,uint16_t length)1741 bool hci_h5_receive_msg(uint8_t *byte, uint16_t length)
1742 {
1743 bool status = false;
1744 status = h5_recv(&rtk_h5, byte, length);
1745 return status;
1746 }
1747
hci_h5_int_read_data(uint8_t * data_buffer,size_t max_size)1748 size_t hci_h5_int_read_data(uint8_t *data_buffer, size_t max_size)
1749 {
1750 H5LogMsg("hci_h5_int_read_data need_size = %d", max_size);
1751 if (!rtk_h5.data_skb) {
1752 HILOGE("hci_h5_int_read_data, there is no data to read for this packet!");
1753 return -1;
1754 }
1755 sk_buff *skb_complete_pkt = rtk_h5.data_skb;
1756 uint8_t *data = skb_get_data(skb_complete_pkt);
1757 uint32_t data_len = skb_get_data_length(skb_complete_pkt);
1758
1759 H5LogMsg("hci_h5_int_read_data length = %d, need_size = %d", data_len, max_size);
1760 if (data_len <= max_size) {
1761 (void)memcpy_s(data_buffer, data_len, data, data_len);
1762 skb_free(&rtk_h5.data_skb);
1763 rtk_h5.data_skb = NULL;
1764 return data_len;
1765 } else {
1766 (void)memcpy_s(data_buffer, max_size, data, max_size);
1767 skb_pull(rtk_h5.data_skb, max_size);
1768 return max_size;
1769 }
1770 }
1771
1772 /*******************************************************************************
1773 **
1774 ** Function hci_h5_send_cmd
1775 **
1776 ** Description get cmd data from hal and send cmd
1777 **
1778 **
1779 ** Returns bytes send
1780 **
1781 *******************************************************************************/
hci_h5_send_cmd(serial_data_type_t type,uint8_t * data,uint16_t length)1782 uint16_t hci_h5_send_cmd(serial_data_type_t type, uint8_t *data, uint16_t length)
1783 {
1784 sk_buff *skb = NULL;
1785 uint16_t bytes_to_send, opcode;
1786
1787 if (type != DATA_TYPE_COMMAND) {
1788 HILOGE("%s Receive wrong type type : %d", __func__, type);
1789 return -1;
1790 }
1791
1792 skb = skb_alloc_and_init(type, data, length);
1793 if (!skb) {
1794 HILOGE("send cmd skb_alloc_and_init fail!");
1795 return -1;
1796 }
1797
1798 h5_enqueue(skb);
1799
1800 num_hci_cmd_pkts--;
1801
1802 /* If this is an internal Cmd packet, the layer_specific field would
1803 * have stored with the opcode of HCI command.
1804 * Retrieve the opcode from the Cmd packet.
1805 */
1806 STREAM_TO_UINT16(opcode, data);
1807 H5LogMsg("HCI Command opcode(0x%04X)", opcode);
1808 if (opcode == 0x0c03) {
1809 H5LogMsg("RX HCI RESET Command, stop hw init timer");
1810 h5_stop_hw_init_ready_timer();
1811 }
1812 bytes_to_send = h5_wake_up();
1813 return length;
1814 }
1815
1816 /*******************************************************************************
1817 **
1818 ** Function hci_h5_send_acl_data
1819 **
1820 ** Description get cmd data from hal and send cmd
1821 **
1822 **
1823 ** Returns bytes send
1824 **
1825 *******************************************************************************/
hci_h5_send_acl_data(serial_data_type_t type,uint8_t * data,uint16_t length)1826 uint16_t hci_h5_send_acl_data(serial_data_type_t type, uint8_t *data, uint16_t length)
1827 {
1828 uint16_t bytes_to_send;
1829 sk_buff *skb = NULL;
1830
1831 skb = skb_alloc_and_init(type, data, length);
1832 if (!skb) {
1833 HILOGE("hci_h5_send_acl_data, alloc skb buffer fail!");
1834 return -1;
1835 }
1836
1837 h5_enqueue(skb);
1838
1839 bytes_to_send = h5_wake_up();
1840 return length;
1841 }
1842
1843 /*******************************************************************************
1844 **
1845 ** Function hci_h5_send_sco_data
1846 **
1847 ** Description get sco data from hal and send sco data
1848 **
1849 **
1850 ** Returns bytes send
1851 **
1852 *******************************************************************************/
hci_h5_send_sco_data(serial_data_type_t type,uint8_t * data,uint16_t length)1853 uint16_t hci_h5_send_sco_data(serial_data_type_t type, uint8_t *data, uint16_t length)
1854 {
1855 sk_buff *skb = NULL;
1856 uint16_t bytes_to_send;
1857
1858 skb = skb_alloc_and_init(type, data, length);
1859 if (!skb) {
1860 HILOGE("send sco data skb_alloc_and_init fail!");
1861 return -1;
1862 }
1863
1864 h5_enqueue(skb);
1865
1866 bytes_to_send = h5_wake_up();
1867 return length;
1868 }
1869
1870 /*******************************************************************************
1871 **
1872 ** Function hci_h5_send_sync_cmd
1873 **
1874 ** Description Place the internal commands (issued internally by vendor lib)
1875 ** in the tx_q.
1876 **
1877 ** Returns TRUE/FALSE
1878 **
1879 *******************************************************************************/
hci_h5_send_sync_cmd(uint16_t opcode,uint8_t * p_buf,uint16_t length)1880 uint8_t hci_h5_send_sync_cmd(uint16_t opcode, uint8_t *p_buf, uint16_t length)
1881 {
1882 if (p_buf != NULL) {
1883 H5LogMsg("hci_h5_send_sync_cmd buf is not null");
1884 }
1885 if (rtk_h5.link_estab_state == H5_UNINITIALIZED) {
1886 if (opcode == HCI_VSC_H5_INIT) {
1887 h5_start_hw_init_ready_timer();
1888 hci_h5_send_sync_req();
1889 h5_start_sync_retrans_timer();
1890 }
1891 } else if (rtk_h5.link_estab_state == H5_ACTIVE) {
1892 H5LogMsg("hci_h5_send_sync_cmd(0x%x), link_estab_state = %d, length = %d", opcode, rtk_h5.link_estab_state,
1893 length);
1894 return false;
1895 }
1896
1897 return true;
1898 }
1899
1900 /***
1901 Timer related functions
1902 */
OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)1903 static timer_t OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)
1904 {
1905 struct sigevent sigev;
1906 timer_t timerid;
1907
1908 (void)memset_s(&sigev, sizeof(struct sigevent), 0, sizeof(struct sigevent));
1909 // Create the POSIX timer to generate signo
1910 sigev.sigev_notify = SIGEV_THREAD;
1911 sigev.sigev_notify_function = timer_callback;
1912 sigev.sigev_value.sival_ptr = &timerid;
1913
1914 HILOGE("OsAllocateTimer rtk_parse sigev.sigev_notify_thread_id = syscall(__NR_gettid)!");
1915 // Create the Timer using timer_create signal
1916
1917 if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0) {
1918 return timerid;
1919 } else {
1920 HILOGE("timer_create error!");
1921 return (timer_t)-1;
1922 }
1923 }
1924
OsFreeTimer(timer_t timerid)1925 static int OsFreeTimer(timer_t timerid)
1926 {
1927 int ret = 0;
1928 ret = timer_delete(timerid);
1929 if (ret != 0) {
1930 HILOGE("timer_delete fail with errno(%d)", errno);
1931 }
1932
1933 return ret;
1934 }
1935
OsStartTimer(timer_t timerid,int msec,int mode)1936 static int OsStartTimer(timer_t timerid, int msec, int mode)
1937 {
1938 struct itimerspec itval;
1939
1940 #define HCI_H5_MSEC_1000 1000
1941 itval.it_value.tv_sec = msec / HCI_H5_MSEC_1000;
1942 itval.it_value.tv_nsec = (long)(msec % HCI_H5_MSEC_1000) * (1000000L);
1943
1944 if (mode == 1) {
1945 itval.it_interval.tv_sec = itval.it_value.tv_sec;
1946 itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
1947 } else {
1948 itval.it_interval.tv_sec = 0;
1949 itval.it_interval.tv_nsec = 0;
1950 }
1951
1952 // Set the Timer when to expire through timer_settime
1953
1954 if (timer_settime(timerid, 0, &itval, NULL) != 0) {
1955 HILOGE("time_settime error!");
1956 return -1;
1957 }
1958
1959 return 0;
1960 }
1961
OsStopTimer(timer_t timerid)1962 static int OsStopTimer(timer_t timerid)
1963 {
1964 return OsStartTimer(timerid, 0, 0);
1965 }
1966
h5_retransfer_timeout_handler(union sigval sigev_value)1967 static void h5_retransfer_timeout_handler(union sigval sigev_value)
1968 {
1969 RTK_UNUSED(sigev_value);
1970 H5LogMsg("h5_retransfer_timeout_handler");
1971 if (rtk_h5.cleanuping) {
1972 HILOGE("h5_retransfer_timeout_handler H5 is cleanuping, EXIT here!");
1973 return;
1974 }
1975 h5_retransfer_signal_event(H5_EVENT_RX);
1976 }
1977
h5_sync_retrans_timeout_handler(union sigval sigev_value)1978 static void h5_sync_retrans_timeout_handler(union sigval sigev_value)
1979 {
1980 RTK_UNUSED(sigev_value);
1981 H5LogMsg("h5_sync_retrans_timeout_handler");
1982 if (rtk_h5.cleanuping) {
1983 HILOGE("h5_sync_retrans_timeout_handler H5 is cleanuping, EXIT here!");
1984 return;
1985 }
1986 if (rtk_h5.sync_retrans_count < SYNC_RETRANS_COUNT) {
1987 hci_h5_send_sync_req();
1988 rtk_h5.sync_retrans_count++;
1989 } else {
1990 if (rtk_h5.link_estab_state == H5_UNINITIALIZED) {
1991 rtk_notify_hw_h5_init_result(0x03);
1992 }
1993 h5_stop_sync_retrans_timer();
1994 }
1995 }
1996
h5_conf_retrans_timeout_handler(union sigval sigev_value)1997 static void h5_conf_retrans_timeout_handler(union sigval sigev_value)
1998 {
1999 RTK_UNUSED(sigev_value);
2000 H5LogMsg("h5_conf_retrans_timeout_handler");
2001 if (rtk_h5.cleanuping) {
2002 HILOGE("h5_conf_retrans_timeout_handler H5 is cleanuping, EXIT here!");
2003 return;
2004 }
2005
2006 H5LogMsg("Wait H5 Conf Resp timeout, %d times", rtk_h5.conf_retrans_count);
2007 if (rtk_h5.conf_retrans_count < CONF_RETRANS_COUNT) {
2008 hci_h5_send_conf_req();
2009 rtk_h5.conf_retrans_count++;
2010 } else {
2011 if (rtk_h5.link_estab_state != H5_ACTIVE) {
2012 rtk_notify_hw_h5_init_result(0x03);
2013 }
2014 h5_stop_conf_retrans_timer();
2015 }
2016 }
2017
h5_wait_controller_baudrate_ready_timeout_handler(union sigval sigev_value)2018 static void h5_wait_controller_baudrate_ready_timeout_handler(union sigval sigev_value)
2019 {
2020 RTK_UNUSED(sigev_value);
2021 H5LogMsg("h5_wait_ct_baundrate_ready_timeout_handler");
2022 if (rtk_h5.cleanuping) {
2023 HILOGE("h5_wait_controller_baudrate_ready_timeout_handler H5 is cleanuping, EXIT here!");
2024 if (rtk_h5.internal_skb) {
2025 skb_free(&rtk_h5.internal_skb);
2026 }
2027 return;
2028 }
2029 H5LogMsg("No Controller retransfer, baudrate of controller ready");
2030 pthread_mutex_lock(&rtk_h5.data_mutex);
2031 skb_queue_tail(rtk_h5.recv_data, rtk_h5.internal_skb);
2032 pthread_cond_signal(&rtk_h5.data_cond);
2033 pthread_mutex_unlock(&rtk_h5.data_mutex);
2034
2035 rtk_h5.internal_skb = NULL;
2036 }
2037
h5_hw_init_ready_timeout_handler(union sigval sigev_value)2038 static void h5_hw_init_ready_timeout_handler(union sigval sigev_value)
2039 {
2040 RTK_UNUSED(sigev_value);
2041 H5LogMsg("h5_hw_init_ready_timeout_handler");
2042 if (rtk_h5.cleanuping) {
2043 HILOGE("H5 is cleanuping, EXIT here!");
2044 return;
2045 }
2046 H5LogMsg("TIMER_H5_HW_INIT_READY timeout, kill restart BT");
2047 }
2048
2049 /*
2050 ** h5 data retrans timer functions
2051 */
h5_alloc_data_retrans_timer(void)2052 int h5_alloc_data_retrans_timer(void)
2053 {
2054 // Create and set the timer when to expire
2055 rtk_h5.timer_data_retrans = OsAllocateTimer(h5_retransfer_timeout_handler);
2056
2057 return 0;
2058 }
2059
h5_free_data_retrans_timer(void)2060 int h5_free_data_retrans_timer(void)
2061 {
2062 return OsFreeTimer(rtk_h5.timer_data_retrans);
2063 }
2064
h5_start_data_retrans_timer(void)2065 int h5_start_data_retrans_timer(void)
2066 {
2067 if (h5_init_datatrans_flag == 0) {
2068 return OsStartTimer(rtk_h5.timer_data_retrans, DATA_RETRANS_TIMEOUT_VALUE, 0);
2069 } else {
2070 return OsStartTimer(rtk_h5.timer_data_retrans, BT_INIT_DATA_RETRANS_TIMEOUT_VALUE, 0);
2071 }
2072 }
2073
h5_stop_data_retrans_timer(void)2074 int h5_stop_data_retrans_timer(void)
2075 {
2076 return OsStopTimer(rtk_h5.timer_data_retrans);
2077 }
2078
2079 /*
2080 ** h5 sync retrans timer functions
2081 */
h5_alloc_sync_retrans_timer(void)2082 int h5_alloc_sync_retrans_timer(void)
2083 {
2084 // Create and set the timer when to expire
2085 rtk_h5.timer_sync_retrans = OsAllocateTimer(h5_sync_retrans_timeout_handler);
2086
2087 return 0;
2088 }
2089
h5_free_sync_retrans_timer(void)2090 int h5_free_sync_retrans_timer(void)
2091 {
2092 return OsFreeTimer(rtk_h5.timer_sync_retrans);
2093 }
2094
h5_start_sync_retrans_timer(void)2095 int h5_start_sync_retrans_timer(void)
2096 {
2097 return OsStartTimer(rtk_h5.timer_sync_retrans, SYNC_RETRANS_TIMEOUT_VALUE, 1);
2098 }
2099
h5_stop_sync_retrans_timer(void)2100 int h5_stop_sync_retrans_timer(void)
2101 {
2102 return OsStopTimer(rtk_h5.timer_sync_retrans);
2103 }
2104
2105 /*
2106 ** h5 config retrans timer functions
2107 */
h5_alloc_conf_retrans_timer(void)2108 int h5_alloc_conf_retrans_timer(void)
2109 {
2110 // Create and set the timer when to expire
2111 rtk_h5.timer_conf_retrans = OsAllocateTimer(h5_conf_retrans_timeout_handler);
2112
2113 return 0;
2114 }
2115
h5_free_conf_retrans_timer(void)2116 int h5_free_conf_retrans_timer(void)
2117 {
2118 return OsFreeTimer(rtk_h5.timer_conf_retrans);
2119 }
2120
h5_start_conf_retrans_timer(void)2121 int h5_start_conf_retrans_timer(void)
2122 {
2123 return OsStartTimer(rtk_h5.timer_conf_retrans, CONF_RETRANS_TIMEOUT_VALUE, 1);
2124 }
2125
h5_stop_conf_retrans_timer(void)2126 int h5_stop_conf_retrans_timer(void)
2127 {
2128 return OsStopTimer(rtk_h5.timer_conf_retrans);
2129 }
2130
2131 /*
2132 ** h5 wait controller baudrate ready timer functions
2133 */
h5_alloc_wait_controller_baudrate_ready_timer(void)2134 int h5_alloc_wait_controller_baudrate_ready_timer(void)
2135 {
2136 // Create and set the timer when to expire
2137 rtk_h5.timer_wait_ct_baudrate_ready = OsAllocateTimer(h5_wait_controller_baudrate_ready_timeout_handler);
2138
2139 return 0;
2140 }
2141
h5_free_wait_controller_baudrate_ready_timer(void)2142 int h5_free_wait_controller_baudrate_ready_timer(void)
2143 {
2144 return OsFreeTimer(rtk_h5.timer_wait_ct_baudrate_ready);
2145 }
2146
h5_start_wait_controller_baudrate_ready_timer(void)2147 int h5_start_wait_controller_baudrate_ready_timer(void)
2148 {
2149 return OsStartTimer(rtk_h5.timer_wait_ct_baudrate_ready, WAIT_CT_BAUDRATE_READY_TIMEOUT_VALUE, 0);
2150 }
2151
h5_stop_wait_controller_baudrate_ready_timer(void)2152 int h5_stop_wait_controller_baudrate_ready_timer(void)
2153 {
2154 return OsStopTimer(rtk_h5.timer_wait_ct_baudrate_ready);
2155 }
2156
2157 /*
2158 ** h5 hw init ready timer functions
2159 */
h5_alloc_hw_init_ready_timer(void)2160 int h5_alloc_hw_init_ready_timer(void)
2161 {
2162 // Create and set the timer when to expire
2163 rtk_h5.timer_h5_hw_init_ready = OsAllocateTimer(h5_hw_init_ready_timeout_handler);
2164
2165 return 0;
2166 }
2167
h5_free_hw_init_ready_timer(void)2168 int h5_free_hw_init_ready_timer(void)
2169 {
2170 return OsFreeTimer(rtk_h5.timer_h5_hw_init_ready);
2171 }
2172
h5_start_hw_init_ready_timer(void)2173 int h5_start_hw_init_ready_timer(void)
2174 {
2175 return OsStartTimer(rtk_h5.timer_h5_hw_init_ready, H5_HW_INIT_READY_TIMEOUT_VALUE, 0);
2176 }
2177
h5_stop_hw_init_ready_timer(void)2178 int h5_stop_hw_init_ready_timer(void)
2179 {
2180 return OsStopTimer(rtk_h5.timer_h5_hw_init_ready);
2181 }
2182
2183 /******************************************************************************
2184 ** HCI H5 Services interface table
2185 ******************************************************************************/
2186 const hci_h5_t hci_h5_int_func_table = {
2187 .h5_int_init = hci_h5_int_init,
2188 .h5_int_cleanup = hci_h5_cleanup,
2189 .h5_send_cmd = hci_h5_send_cmd,
2190 .h5_send_sync_cmd = hci_h5_send_sync_cmd,
2191 .h5_send_acl_data = hci_h5_send_acl_data,
2192 .h5_send_sco_data = hci_h5_send_sco_data,
2193 .h5_recv_msg = hci_h5_receive_msg,
2194 .h5_int_read_data = hci_h5_int_read_data,
2195 };
2196
hci_get_h5_int_interface()2197 const hci_h5_t *hci_get_h5_int_interface()
2198 {
2199 return &hci_h5_int_func_table;
2200 }
2201