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