• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param)==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, &param);
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