• 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  *
21  *	Module Name:
22  *		rtk_parse.c
23  *
24  *	Abstract:
25  *		Contains wifi-bt coex functions implemented by bluedroid stack
26  *
27  *	Major Change History:
28  *	      When             Who       What
29  *	 	---------------------------------------------------------------
30  *	    2015-12-15      lamparten   modified
31  *	    2014-10-23       kyle_xu    modified
32  *	Notes:
33  *		  This is designed for wifi-bt Coex in Android 6.0.
34  *
35  ******************************************************************************/
36 #define LOG_TAG "rtk_parse"
37 #define RTKBT_RELEASE_NAME "20190717_BT_ANDROID_9.0"
38 
39 #include <utils/Log.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <fcntl.h>
43 #include <termios.h>
44 #include <errno.h>
45 #include <signal.h>
46 #include <time.h>
47 #include <unistd.h>
48 #include <string.h>
49 #include <ctype.h>
50 #include <sys/un.h>
51 #include <sys/ioctl.h>
52 #include <sys/socket.h>
53 #include <sys/prctl.h>
54 #include <linux/types.h>
55 #include <linux/netlink.h>
56 #include <arpa/inet.h>
57 #include <netinet/in.h>
58 #include <dirent.h>
59 #include <signal.h>
60 #include <poll.h>
61 
62 #include "bt_list.h"
63 #include "bt_hci_bdroid.h"
64 #include "rtk_parse.h"
65 #include <sys/syscall.h>
66 
67 #define RTK_COEX_VERSION "3.0"
68 #define HCI_EVT_CMD_CMPL_OPCODE 3
69 #define HCI_CMD_VNDR_HEARTBEAT 0xFC94
70 
71 char invite_req[] = "INVITE_REQ";
72 char invite_rsp[] = "INVITE_RSP";
73 char attend_req[] = "ATTEND_REQ";
74 char attend_ack[] = "ATTEND_ACK";
75 char wifi_leave[] = "WIFI_LEAVE";
76 char leave_ack[] = "LEAVE_ACK";
77 char bt_leave[] = "BT_LEAVE";
78 
79 #define CONNECT_PORT 30001
80 #define CONNECT_PORT_WIFI 30000
81 //#define NETLINK_USER        31
82 #define MAX_PAYLOAD 255 /* maximum payload size*/
83 
84 // L2CAP TYPE
85 #define L2CAP_CONNECTION_REQ 0x02
86 #define L2CAP_CONNECTION_RSP 0x03
87 #define L2CAP_DISCONNECTION_REQ 0x06
88 #define L2CAP_DISCONNECTION_RSP 0x07
89 
90 #define TIMER_A2DP_PACKET_COUNT (SIGRTMAX - 5)
91 #define TIMER_PAN_PACKET_COUNT (SIGRTMAX - 6)
92 #define TIMER_HOGP_PACKET_COUNT (SIGRTMAX - 7)
93 #define TIMER_POLLING (SIGRTMAX - 8)
94 
95 #define PAN_PACKET_COUNT 5
96 #define PACKET_COUNT_TIOMEOUT_VALUE 1000 // ms
97 
98 // vendor cmd to fw
99 #define HCI_VENDOR_ENABLE_PROFILE_REPORT_COMMAND (0x0018 | HCI_GRP_VENDOR_SPECIFIC)
100 #define HCI_VENDOR_SET_PROFILE_REPORT_COMMAND (0x0019 | HCI_GRP_VENDOR_SPECIFIC)
101 #define HCI_VENDOR_MAILBOX_CMD (0x008F | HCI_GRP_VENDOR_SPECIFIC)
102 
103 #define HCI_VENDOR_ADD_BITPOOL_FW (0x0051 | HCI_GRP_VENDOR_SPECIFIC)
104 
105 // subcmd to fw for HCI_VENDOR_MAILBOX_CMD
106 #define HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD 0x11
107 #define HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD 0x17
108 #define HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD 0x1B
109 #define HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO 0x23
110 #define HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_STATUS_INFO 0x27
111 #define HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE 0x28
112 #define HCI_VENDOR_SUB_CMD_BT_SET_TXRETRY_REPORT_PARAM 0x29
113 #define HCI_VENDOR_SUB_CMD_BT_SET_PTATABLE 0x2A
114 #define HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE 0x31
115 #define HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT 0x32
116 #define HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L 0x40
117 #define HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M 0x41
118 #define HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H 0x42
119 #define HCI_VENDOR_SUB_CMD_RD_REG_REQ 0x43
120 #define HCI_VENDOR_SUB_CMD_WR_REG_REQ 0x44
121 
122 // sub event from fw
123 #define HCI_VENDOR_PTA_REPORT_EVENT 0x24
124 #define HCI_VENDOR_PTA_AUTO_REPORT_EVENT 0x25
125 
126 // vendor cmd to wifi driver
127 #define HCI_OP_HCI_EXTENSION_VERSION_NOTIFY (0x0100 | HCI_GRP_VENDOR_SPECIFIC)
128 #define HCI_OP_BT_OPERATION_NOTIFY (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
129 #define HCI_OP_HCI_BT_INFO_NOTIFY (0x0106 | HCI_GRP_VENDOR_SPECIFIC)
130 #define HCI_OP_HCI_BT_COEX_NOTIFY (0x0107 | HCI_GRP_VENDOR_SPECIFIC)
131 #define HCI_OP_HCI_BT_PATCH_VER_NOTIFY (0x0108 | HCI_GRP_VENDOR_SPECIFIC)
132 #define HCI_OP_HCI_BT_AFH_MAP_NOTIFY (0x0109 | HCI_GRP_VENDOR_SPECIFIC)
133 #define HCI_OP_HCI_BT_REGISTER_VALUE_NOTIFY (0x010a | HCI_GRP_VENDOR_SPECIFIC)
134 
135 // bt operation to notify for HCI_OP_BT_OPERATION_NOTIFY
136 #define BT_OPCODE_NONE 0
137 #define BT_OPCODE_INQUIRY_START 1
138 #define BT_OPCODE_INQUIRY_END 2
139 #define BT_OPCODE_PAGE_START 3
140 #define BT_OPCODE_PAGE_SUCCESS_END 4
141 #define BT_OPCODE_PAGE_UNSUCCESS_END 5
142 #define BT_OPCODE_PAIR_START 6
143 #define BT_OPCODE_PAIR_END 7
144 #define BT_OPCODE_ENABLE_BT 8
145 #define BT_OPCODE_DISABLE_BT 9
146 
147 // bt info reason to wifi for HCI_OP_HCI_BT_INFO_NOTIFY
148 #define HOST_RESPONSE 0                // Host response when receive the BT Info Control Event
149 #define POLLING_RESPONSE 1             // The BT Info response for polling by BT firmware.
150 #define AUTO_REPORT 2                  // BT auto report by BT firmware.
151 #define STACK_REPORT_WHILE_DEVICE_D2 3 // Stack report when BT firmware is under power save state(ex:D2)
152 
153 // vendor event from wifi
154 #define RTK_HS_EXTENSION_EVENT_WIFI_SCAN 0x01
155 #define RTK_HS_EXTENSION_EVENT_RADIO_STATUS_NOTIFY 0x02
156 #define RTK_HS_EXTENSION_EVENT_HCI_BT_INFO_CONTROL 0x03
157 #define RTK_HS_EXTENSION_EVENT_HCI_BT_COEX_CONTROL 0x04
158 
159 // op code from wifi for RTK_HS_EXTENSION_EVENT_HCI_BT_COEX_CONTROL
160 #define BT_PATCH_VERSION_QUERY 0x00
161 #define IGNORE_WLAN_ACTIVE_CONTROL 0x01
162 #define LNA_CONSTRAIN_CONTROL 0x02
163 #define BT_POWER_DECREASE_CONTROL 0x03
164 #define BT_PSD_MODE_CONTROL 0x04
165 #define WIFI_BW_CHNL_NOTIFY 0x05
166 #define QUERY_BT_AFH_MAP 0x06
167 #define BT_REGISTER_ACCESS 0x07
168 
169 #define HCI_EXTENSION_VERSION 0x0004
170 
171 //#define HCI_CMD_PREAMBLE_SIZE 3
172 
173 #define PSM_SDP 0x0001
174 #define PSM_RFCOMM 0x0003
175 #define PSM_PAN 0x000F
176 #define PSM_HID 0x0011
177 #define PSM_HID_INT 0x0013
178 #define PSM_AVCTP 0x0017
179 #define PSM_AVDTP 0x0019
180 #define PSM_FTP 0x1001
181 #define PSM_BIP 0x1003
182 #define PSM_OPP 0x1015
183 //--Add more if needed--//
184 
185 enum
186 {
187     profile_sco = 0,
188     profile_hid = 1,
189     profile_a2dp = 2,
190     profile_pan = 3,
191     profile_hid_interval = 4,
192     profile_hogp = 5,
193     profile_voice = 6,
194     profile_sink = 7,
195     profile_max = 8
196 };
197 typedef void (*tINT_CMD_CBACK)(void *p_mem);
198 typedef struct RTK_COEX_INFO
199 {
200     RT_LIST_ENTRY list;
201     HC_BT_HDR *p_buf;
202     uint16_t opcode;
203     tINT_CMD_CBACK p_cback;
204 } tRTK_COEX_INFO;
205 
206 // profile info data
207 typedef struct RTK_PROF_INFO
208 {
209     RT_LIST_ENTRY list;
210     uint16_t handle;
211     uint16_t psm;
212     uint16_t dcid;
213     uint16_t scid;
214     uint8_t profile_index;
215 } tRTK_PROF_INFO;
216 
217 // profile info for each connection
218 typedef struct RTK_CONN_PROF
219 {
220     RT_LIST_ENTRY list;
221     uint16_t handle;
222     uint8_t type;               // 0:l2cap, 1:sco/esco, 2:le
223     uint8_t profile_bitmap;     // 0:SCO, 1:HID, 2:A2DP, 3:FTP/PAN/OPP, 4: HID_interval, 5:HOGP, 6:VOICE
224     int8_t profile_refcount[8]; // 0:SCO, 1:HID, 2:A2DP, 3:FTP/PAN/OPP, 4:TBD, 5:HOGP, 6:VOICE
225 } tRTK_CONN_PROF;
226 
227 // profile info for all
228 typedef struct RTK_PROF
229 {
230     RT_LIST_HEAD conn_hash;    // hash for connections
231     RT_LIST_HEAD profile_list; // hash for profile info
232     RT_LIST_HEAD coex_list;
233     tINT_CMD_CBACK current_cback;
234     pthread_mutex_t profile_mutex;
235     pthread_mutex_t coex_mutex;
236     pthread_mutex_t btwifi_mutex;
237     pthread_t thread_monitor;
238     pthread_t thread_data;
239     timer_t timer_a2dp_packet_count;
240     timer_t timer_pan_packet_count;
241     timer_t timer_hogp_packet_count;
242     timer_t timer_polling;
243     // struct sockaddr_nl src_addr;    //for netlink
244     struct sockaddr_in server_addr; // server addr for kernel socket
245     struct sockaddr_in client_addr; // client addr  for kernel socket
246     uint32_t a2dp_packet_count;
247     uint32_t pan_packet_count;
248     uint32_t hogp_packet_count;
249     uint32_t voice_packet_count;
250     uint8_t profile_bitmap;
251     uint8_t profile_status;
252     int8_t profile_refcount[8];
253     uint8_t ispairing;
254     uint8_t isinquirying;
255     uint8_t ispaging;
256     uint8_t wifi_state;
257     uint8_t autoreport;
258     uint8_t polling_enable;
259     uint8_t polling_interval;
260     volatile uint8_t coex_recv_thread_running;
261     // int32_t   nlsocket;
262     int32_t btcoex_chr;
263     int32_t udpsocket;
264     uint8_t piconet_id;
265     uint8_t mode;
266     uint8_t afh_map[10];
267     uint16_t hci_reversion;
268     uint16_t lmp_subversion;
269     uint8_t wifi_on;
270     uint8_t bt_on;
271     // uint8_t  le_profile_index;
272 } tRTK_PROF;
273 
274 typedef struct HCI_RETURN_PARAMETER_MAILBOX_REGISTER
275 {
276     uint8_t type;
277     uint32_t offset;
278     uint32_t value;
279 } tHCI_RETURN_PARAMETER_MAILBOX_REGISTER;
280 
281 typedef struct HCI_EVENT_BT_INFO_CONTROL
282 {
283     uint8_t polling_enable;
284     uint8_t polling_time;
285     uint8_t autoreport_enable;
286 } tHCI_EVENT_BT_INFO_CONTROL;
287 
288 tRTK_PROF rtk_prof;
289 volatile int poweroff_allowed = 0;
290 uint8_t coex_log_enable = 0;
291 static volatile bool coex_cmd_send = false;
292 
293 #define BIT(_I) (uint16_t)(1 << (_I))
294 #define is_profile_connected(profile) ((rtk_prof.profile_bitmap & BIT(profile)) > 0)
295 #define is_profile_busy(profile) ((rtk_prof.profile_status & BIT(profile)) > 0)
296 
297 static void timeout_handler(int signo, siginfo_t *info, void *context);
298 static void notify_func(union sigval sig);
299 
300 static int coex_msg_send(char *tx_msg, int msg_size);
301 static int coex_msg_recv(uint8_t *recv_msg, uint8_t *msg_size);
302 
303 #ifndef RTK_PARSE_LOG_BUF_SIZE
304 #define RTK_PARSE_LOG_BUF_SIZE 1024
305 #endif
306 #define RTK_PARSE_LOG_MAX_SIZE (RTK_PARSE_LOG_BUF_SIZE - 12)
307 
308 #define LOGI0(t, s)
RtkLogMsg(const char * fmt_str,...)309 static void RtkLogMsg(const char *fmt_str, ...)
310 {
311     static char buffer[RTK_PARSE_LOG_BUF_SIZE];
312     if (coex_log_enable)
313     {
314         va_list ap;
315         va_start(ap, fmt_str);
316         vsnprintf(&buffer[0], RTK_PARSE_LOG_MAX_SIZE, fmt_str, ap);
317         va_end(ap);
318 
319         LOGI0("rtk_parse: ", buffer);
320     }
321     else
322     {
323         return;
324     }
325 }
326 
327 static const char sample_freqs[4][8] = {
328     "16", "32", "44.1", "48"};
329 
330 static const uint8_t sbc_blocks[4] = {4, 8, 12, 16};
331 
332 static const char chan_modes[4][16] = {
333     "MONO", "DUAL_CHANNEL", "STEREO", "JOINT_STEREO"};
334 
335 static const char alloc_methods[2][12] = {
336     "LOUDNESS", "SNR"};
337 
338 static const uint8_t subbands[2] = {4, 8};
339 
print_sbc_header(struct sbc_frame_hdr * hdr)340 void print_sbc_header(struct sbc_frame_hdr *hdr)
341 {
342     RtkLogMsg("syncword: %02x", hdr->syncword);
343     RtkLogMsg("freq %skHz", sample_freqs[hdr->sampling_frequency]);
344     RtkLogMsg("blocks %u", sbc_blocks[hdr->blocks]);
345     RtkLogMsg("channel mode %s", chan_modes[hdr->channel_mode]);
346     RtkLogMsg("allocation method %s", alloc_methods[hdr->allocation_method]);
347     RtkLogMsg("subbands %u", subbands[hdr->subbands]);
348 }
349 
OsAllocateTimer(int signo)350 static timer_t OsAllocateTimer(int signo)
351 {
352     struct sigevent sigev;
353     timer_t timerid = (timer_t)-1;
354 
355     // Create the POSIX timer to generate signo
356     // sigev.sigev_notify = SIGEV_THREAD_ID;
357     // sigev.sigev_notify_thread_id = syscall(__NR_gettid);
358     // sigev.sigev_signo = signo;
359     // sigev.sigev_value.sival_ptr = &timerid;
360 
361     memset(&sigev, 0, sizeof(sigev));
362     sigev.sigev_notify = SIGEV_THREAD;
363     sigev.sigev_notify_function = notify_func;
364     sigev.sigev_value.sival_int = signo;
365 
366     // HILOGE("OsAllocateTimer rtk_parse sigev.sigev_notify_thread_id = syscall(__NR_gettid)!");
367 
368     // Create the Timer using timer_create signal
369     if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0)
370     {
371         return timerid;
372     }
373     else
374     {
375         HILOGE("timer_create error!");
376         return (timer_t)-1;
377     }
378 }
379 
OsFreeTimer(timer_t timerid)380 static int OsFreeTimer(timer_t timerid)
381 {
382     int ret = 0;
383     ret = timer_delete(timerid);
384     if (ret != 0)
385         HILOGE("timer_delete fail with errno(%d)", errno);
386 
387     return ret;
388 }
389 
OsStartTimer(timer_t timerid,int msec,int mode)390 static int OsStartTimer(timer_t timerid, int msec, int mode)
391 {
392     struct itimerspec itval;
393 
394     itval.it_value.tv_sec = msec / 1000;
395     itval.it_value.tv_nsec = (long)(msec % 1000) * (1000000L);
396 
397     if (mode == 1)
398     {
399         itval.it_interval.tv_sec = itval.it_value.tv_sec;
400         itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
401     }
402     else
403     {
404         itval.it_interval.tv_sec = 0;
405         itval.it_interval.tv_nsec = 0;
406     }
407 
408     // Set the Timer when to expire through timer_settime
409     if (timer_settime(timerid, 0, &itval, NULL) != 0)
410     {
411         HILOGE("time_settime error!");
412         return -1;
413     }
414 
415     return 0;
416 }
417 
OsStopTimer(timer_t timerid)418 static int OsStopTimer(timer_t timerid)
419 {
420     return OsStartTimer(timerid, 0, 0);
421 }
422 
alloc_polling_timer()423 int alloc_polling_timer()
424 {
425     /*
426         struct sigaction sigact;
427 
428         sigemptyset(&sigact.sa_mask);
429         sigact.sa_flags = SA_SIGINFO;
430 
431         //register the Signal Handler
432         sigact.sa_sigaction = timeout_handler;
433 
434         // Set up sigaction to catch signal first timer
435         if (sigaction(TIMER_POLLING, &sigact, NULL) == -1)
436         {
437             HILOGE("alloc_polling_timer, sigaction failed");
438             return -1;
439         }
440     */
441     // Create and set the timer when to expire
442     rtk_prof.timer_polling = OsAllocateTimer(TIMER_POLLING);
443     RtkLogMsg("alloc polling timer");
444 
445     return 0;
446 }
447 
free_polling_timer()448 int free_polling_timer()
449 {
450     return OsFreeTimer(rtk_prof.timer_polling);
451 }
452 
stop_polling_timer()453 int stop_polling_timer()
454 {
455     RtkLogMsg("stop polling timer");
456     return OsStopTimer(rtk_prof.timer_polling);
457 }
458 
start_polling_timer(int value)459 int start_polling_timer(int value)
460 {
461     RtkLogMsg("start polling timer");
462     return OsStartTimer(rtk_prof.timer_polling, value, 1);
463 }
464 
alloc_hogp_packet_count_timer()465 int alloc_hogp_packet_count_timer()
466 {
467     /*
468         struct sigaction sigact;
469 
470         sigemptyset(&sigact.sa_mask);
471         sigact.sa_flags = SA_SIGINFO;
472 
473         //register the Signal Handler
474         sigact.sa_sigaction = timeout_handler;
475 
476         // Set up sigaction to catch signal first timer
477         if (sigaction(TIMER_HOGP_PACKET_COUNT, &sigact, NULL) == -1)
478         {
479             HILOGE("alloc_hogp_packet_count_timer, sigaction failed");
480             return -1;
481         }
482     */
483     // Create and set the timer when to expire
484     rtk_prof.timer_hogp_packet_count = OsAllocateTimer(TIMER_HOGP_PACKET_COUNT);
485     RtkLogMsg("alloc hogp packet");
486 
487     return 0;
488 }
489 
free_hogp_packet_count_timer()490 int free_hogp_packet_count_timer()
491 {
492     return OsFreeTimer(rtk_prof.timer_hogp_packet_count);
493 }
494 
stop_hogp_packet_count_timer()495 int stop_hogp_packet_count_timer()
496 {
497     RtkLogMsg("stop hogp packet");
498     return OsStopTimer(rtk_prof.timer_hogp_packet_count);
499 }
500 
start_hogp_packet_count_timer()501 int start_hogp_packet_count_timer()
502 {
503     RtkLogMsg("start hogp packet");
504     return OsStartTimer(rtk_prof.timer_hogp_packet_count, PACKET_COUNT_TIOMEOUT_VALUE, 1);
505 }
506 
alloc_a2dp_packet_count_timer()507 int alloc_a2dp_packet_count_timer()
508 {
509     /*
510         struct sigaction sigact;
511 
512         sigemptyset(&sigact.sa_mask);
513         sigact.sa_flags = SA_SIGINFO;
514 
515         //register the Signal Handler
516         sigact.sa_sigaction = timeout_handler;
517 
518         // Set up sigaction to catch signal first timer
519         if (sigaction(TIMER_A2DP_PACKET_COUNT, &sigact, NULL) == -1)
520         {
521             HILOGE("alloc_a2dp_packet_count_timer, sigaction failed");
522             return -1;
523         }
524     */
525     // Create and set the timer when to expire
526     rtk_prof.timer_a2dp_packet_count = OsAllocateTimer(TIMER_A2DP_PACKET_COUNT);
527     RtkLogMsg("alloc a2dp packet");
528 
529     return 0;
530 }
531 
free_a2dp_packet_count_timer()532 int free_a2dp_packet_count_timer()
533 {
534     return OsFreeTimer(rtk_prof.timer_a2dp_packet_count);
535 }
536 
stop_a2dp_packet_count_timer()537 int stop_a2dp_packet_count_timer()
538 {
539     RtkLogMsg("stop a2dp packet");
540     return OsStopTimer(rtk_prof.timer_a2dp_packet_count);
541 }
542 
start_a2dp_packet_count_timer()543 int start_a2dp_packet_count_timer()
544 {
545     RtkLogMsg("start a2dp packet");
546     return OsStartTimer(rtk_prof.timer_a2dp_packet_count, PACKET_COUNT_TIOMEOUT_VALUE, 1);
547 }
548 
alloc_pan_packet_count_timer()549 int alloc_pan_packet_count_timer()
550 {
551     /*
552         struct sigaction sigact;
553 
554         sigemptyset(&sigact.sa_mask);
555         sigact.sa_flags = SA_SIGINFO;
556 
557         //register the Signal Handler
558         sigact.sa_sigaction = timeout_handler;
559 
560         // Set up sigaction to catch signal first timer
561         if (sigaction(TIMER_PAN_PACKET_COUNT, &sigact, NULL) == -1)
562         {
563             HILOGE("alloc_pan_packet_count_timer, sigaction failed");
564             return -1;
565         }
566     */
567     // Create and set the timer when to expire
568     rtk_prof.timer_pan_packet_count = OsAllocateTimer(TIMER_PAN_PACKET_COUNT);
569 
570     RtkLogMsg("alloc pan packet");
571     return 0;
572 }
573 
free_pan_packet_count_timer()574 int free_pan_packet_count_timer()
575 {
576     return OsFreeTimer(rtk_prof.timer_pan_packet_count);
577 }
578 
stop_pan_packet_count_timer()579 int stop_pan_packet_count_timer()
580 {
581     RtkLogMsg("stop pan packet");
582     return OsStopTimer(rtk_prof.timer_pan_packet_count);
583 }
584 
start_pan_packet_count_timer()585 int start_pan_packet_count_timer()
586 {
587     RtkLogMsg("start pan packet");
588     return OsStartTimer(rtk_prof.timer_pan_packet_count, PACKET_COUNT_TIOMEOUT_VALUE, 1);
589 }
590 
psm_to_profile_index(uint16_t psm)591 static int8_t psm_to_profile_index(uint16_t psm)
592 {
593     switch (psm)
594     {
595     case PSM_AVCTP:
596     case PSM_SDP:
597         return -1; // ignore
598 
599     case PSM_HID:
600     case PSM_HID_INT:
601         return profile_hid;
602 
603     case PSM_AVDTP:
604         return profile_a2dp;
605 
606     case PSM_PAN:
607     case PSM_OPP:
608     case PSM_FTP:
609     case PSM_BIP:
610     case PSM_RFCOMM:
611         return profile_pan;
612 
613     default:
614         return profile_pan;
615     }
616 }
617 
find_connection_by_handle(tRTK_PROF * h5,uint16_t handle)618 tRTK_CONN_PROF *find_connection_by_handle(tRTK_PROF *h5, uint16_t handle)
619 {
620     RT_LIST_HEAD *head = &h5->conn_hash;
621     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
622     tRTK_CONN_PROF *desc = NULL;
623 
624     LIST_FOR_EACH_SAFELY(iter, temp, head)
625     {
626         desc = LIST_ENTRY(iter, tRTK_CONN_PROF, list);
627         if ((handle & 0xEFF) == desc->handle) // only last 12 bit are meanful for hci handle
628         {
629             return desc;
630         }
631     }
632     return NULL;
633 }
634 
allocate_connection_by_handle(uint16_t handle)635 tRTK_CONN_PROF *allocate_connection_by_handle(uint16_t handle)
636 {
637     tRTK_CONN_PROF *phci_conn = NULL;
638     phci_conn = malloc(sizeof(tRTK_CONN_PROF));
639     if (phci_conn)
640         phci_conn->handle = handle;
641 
642     return phci_conn;
643 }
644 
init_connection_hash(tRTK_PROF * h5)645 void init_connection_hash(tRTK_PROF *h5)
646 {
647     RT_LIST_HEAD *head = &h5->conn_hash;
648     ListInitializeHeader(head);
649 }
650 
add_connection_to_hash(tRTK_PROF * h5,tRTK_CONN_PROF * desc)651 void add_connection_to_hash(tRTK_PROF *h5, tRTK_CONN_PROF *desc)
652 {
653     RT_LIST_HEAD *head = &h5->conn_hash;
654     ListAddToTail(&desc->list, head);
655 }
656 
delete_connection_from_hash(tRTK_CONN_PROF * desc)657 void delete_connection_from_hash(tRTK_CONN_PROF *desc)
658 {
659     if (desc)
660     {
661         ListDeleteNode(&desc->list);
662         free(desc);
663     }
664 }
665 
flush_connection_hash(tRTK_PROF * h5)666 void flush_connection_hash(tRTK_PROF *h5)
667 {
668     RT_LIST_HEAD *head = &h5->conn_hash;
669     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
670     tRTK_CONN_PROF *desc = NULL;
671 
672     LIST_FOR_EACH_SAFELY(iter, temp, head)
673     {
674         desc = LIST_ENTRY(iter, tRTK_CONN_PROF, list);
675         if (desc)
676         {
677             ListDeleteNode(&desc->list);
678             free(desc);
679         }
680     }
681     // ListInitializeHeader(head);
682 }
683 
init_profile_hash(tRTK_PROF * h5)684 void init_profile_hash(tRTK_PROF *h5)
685 {
686     RT_LIST_HEAD *head = &h5->profile_list;
687     ListInitializeHeader(head);
688 }
689 
list_allocate_add(uint16_t handle,uint16_t psm,int8_t profile_index,uint16_t dcid,uint16_t scid)690 uint8_t list_allocate_add(uint16_t handle, uint16_t psm, int8_t profile_index, uint16_t dcid, uint16_t scid)
691 {
692     tRTK_PROF_INFO *pprof_info = NULL;
693 
694     if (profile_index < 0)
695     {
696         HILOGE("PSM(0x%x) do not need parse", psm);
697         return FALSE;
698     }
699 
700     pprof_info = malloc(sizeof(tRTK_PROF_INFO));
701     if (NULL == pprof_info)
702     {
703         HILOGE("list_allocate_add: allocate error");
704         return FALSE;
705     }
706 
707     pprof_info->handle = handle;
708     pprof_info->psm = psm;
709     pprof_info->scid = scid;
710     pprof_info->dcid = dcid;
711     pprof_info->profile_index = profile_index;
712 
713     ListAddToTail(&(pprof_info->list), &(rtk_prof.profile_list));
714 
715     return TRUE;
716 }
717 
delete_profile_from_hash(tRTK_PROF_INFO * desc)718 void delete_profile_from_hash(tRTK_PROF_INFO *desc)
719 {
720     // RtkLogMsg("delete profile for handle: %x, psm:%x, dcid:%x, scid:%x", desc->handle, desc->psm, desc->dcid, desc->scid);
721     if (desc)
722     {
723         ListDeleteNode(&desc->list);
724         free(desc);
725         desc = NULL;
726     }
727 }
728 
flush_profile_hash(tRTK_PROF * h5)729 void flush_profile_hash(tRTK_PROF *h5)
730 {
731     RT_LIST_HEAD *head = &h5->profile_list;
732     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
733     tRTK_PROF_INFO *desc = NULL;
734 
735     pthread_mutex_lock(&rtk_prof.profile_mutex);
736     LIST_FOR_EACH_SAFELY(iter, temp, head)
737     {
738         desc = LIST_ENTRY(iter, tRTK_PROF_INFO, list);
739         delete_profile_from_hash(desc);
740     }
741     // ListInitializeHeader(head);
742     pthread_mutex_unlock(&rtk_prof.profile_mutex);
743 }
744 
find_profile_by_handle_scid(tRTK_PROF * h5,uint16_t handle,uint16_t scid)745 tRTK_PROF_INFO *find_profile_by_handle_scid(tRTK_PROF *h5, uint16_t handle, uint16_t scid)
746 {
747     RT_LIST_HEAD *head = &h5->profile_list;
748     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
749     tRTK_PROF_INFO *desc = NULL;
750 
751     LIST_FOR_EACH_SAFELY(iter, temp, head)
752     {
753         desc = LIST_ENTRY(iter, tRTK_PROF_INFO, list);
754         if (((handle & 0xFFF) == desc->handle) && (scid == desc->scid))
755         {
756             return desc;
757         }
758     }
759     return NULL;
760 }
761 
find_profile_by_handle_dcid(tRTK_PROF * h5,uint16_t handle,uint16_t dcid)762 tRTK_PROF_INFO *find_profile_by_handle_dcid(tRTK_PROF *h5, uint16_t handle, uint16_t dcid)
763 {
764     RT_LIST_HEAD *head = &h5->profile_list;
765     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
766     tRTK_PROF_INFO *desc = NULL;
767 
768     LIST_FOR_EACH_SAFELY(iter, temp, head)
769     {
770         desc = LIST_ENTRY(iter, tRTK_PROF_INFO, list);
771         if (((handle & 0xFFF) == desc->handle) && (dcid == desc->dcid))
772         {
773             return desc;
774         }
775     }
776     return NULL;
777 }
778 
find_profile_by_handle_dcid_scid(tRTK_PROF * h5,uint16_t handle,uint16_t dcid,uint16_t scid)779 tRTK_PROF_INFO *find_profile_by_handle_dcid_scid(tRTK_PROF *h5, uint16_t handle, uint16_t dcid, uint16_t scid)
780 {
781     RT_LIST_HEAD *head = &h5->profile_list;
782     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
783     tRTK_PROF_INFO *desc = NULL;
784 
785     LIST_FOR_EACH_SAFELY(iter, temp, head)
786     {
787         desc = LIST_ENTRY(iter, tRTK_PROF_INFO, list);
788         if (((handle & 0xFFF) == desc->handle) && (dcid == desc->dcid) && (scid == desc->scid))
789         {
790             return desc;
791         }
792     }
793     return NULL;
794 }
795 
init_coex_hash(tRTK_PROF * h5)796 void init_coex_hash(tRTK_PROF *h5)
797 {
798     RT_LIST_HEAD *head = &h5->coex_list;
799     ListInitializeHeader(head);
800 }
801 
delete_coex_from_hash(tRTK_COEX_INFO * desc)802 void delete_coex_from_hash(tRTK_COEX_INFO *desc)
803 {
804     if (desc)
805     {
806         ListDeleteNode(&desc->list);
807         free(desc);
808         desc = NULL;
809     }
810 }
811 
flush_coex_hash(tRTK_PROF * h5)812 void flush_coex_hash(tRTK_PROF *h5)
813 {
814     RT_LIST_HEAD *head = &h5->coex_list;
815     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
816     tRTK_COEX_INFO *desc = NULL;
817 
818     pthread_mutex_lock(&rtk_prof.coex_mutex);
819     LIST_FOR_EACH_SAFELY(iter, temp, head)
820     {
821         desc = LIST_ENTRY(iter, tRTK_COEX_INFO, list);
822         delete_coex_from_hash(desc);
823     }
824     // ListInitializeHeader(head);
825     pthread_mutex_unlock(&rtk_prof.coex_mutex);
826 }
827 
rtk_cmd_complete_cback(void * p_mem)828 static void rtk_cmd_complete_cback(void *p_mem)
829 {
830     pthread_mutex_lock(&rtk_prof.coex_mutex);
831     RT_LIST_ENTRY *iter = ListGetTop(&(rtk_prof.coex_list));
832     tRTK_COEX_INFO *desc = NULL;
833     if (iter)
834     {
835         desc = LIST_ENTRY(iter, tRTK_COEX_INFO, list);
836         if (desc)
837         {
838             ListDeleteNode(&desc->list);
839         }
840     }
841     else
842     {
843         coex_cmd_send = false;
844     }
845     pthread_mutex_unlock(&rtk_prof.coex_mutex);
846 
847     if (rtk_prof.current_cback)
848     {
849         rtk_prof.current_cback(p_mem);
850         rtk_prof.current_cback = NULL;
851     }
852 
853     if (desc)
854     {
855         HILOGE("%s, transmit_command Opcode:%x", __func__, desc->opcode);
856         rtk_prof.current_cback = desc->p_cback;
857         bt_vendor_cbacks->xmit_cb(desc->opcode, desc->p_buf);
858     }
859 
860     free(desc);
861     return;
862 }
863 
rtk_vendor_cmd_to_fw(uint16_t opcode,uint8_t parameter_len,uint8_t * parameter,tINT_CMD_CBACK p_cback)864 void rtk_vendor_cmd_to_fw(uint16_t opcode, uint8_t parameter_len, uint8_t *parameter, tINT_CMD_CBACK p_cback)
865 {
866     HC_BT_HDR *p_buf = NULL;
867 
868     if (!rtk_prof.bt_on)
869         return;
870 
871     if (bt_vendor_cbacks)
872         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + parameter_len);
873 
874     if (NULL == p_buf)
875     {
876         HILOGE("rtk_vendor_cmd_to_fw: HC_BT_HDR alloc error");
877         return;
878     }
879     memset(p_buf, 0, (BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + parameter_len));
880     p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
881     p_buf->offset = 0;
882     p_buf->len = HCI_CMD_PREAMBLE_SIZE + parameter_len;
883     p_buf->layer_specific = 0;
884 
885     uint8_t *p = (uint8_t *)(p_buf + 1);
886     UINT16_TO_STREAM(p, opcode);
887     *p++ = parameter_len;
888     RtkLogMsg("rtk_vendor_cmd_to_fw: Opcode:%x, parameter_len = %d", opcode, parameter_len);
889 
890     if (parameter_len > 0)
891     {
892         memcpy(p, parameter, parameter_len);
893     }
894     if (bt_vendor_cbacks)
895     {
896         pthread_mutex_lock(&rtk_prof.coex_mutex);
897         if (!coex_cmd_send)
898         {
899             coex_cmd_send = true;
900             RtkLogMsg("begin transmit_command Opcode:%x", opcode);
901             pthread_mutex_unlock(&rtk_prof.coex_mutex);
902             rtk_prof.current_cback = p_cback;
903             bt_vendor_cbacks->xmit_cb(opcode, p_buf);
904         }
905         else
906         {
907             tRTK_COEX_INFO *pcoex_info = NULL;
908             pcoex_info = malloc(sizeof(tRTK_COEX_INFO));
909             if (NULL == pcoex_info)
910             {
911                 HILOGE("rtk_vendor_cmd_to_fw: allocate error");
912                 pthread_mutex_unlock(&rtk_prof.coex_mutex);
913                 return;
914             }
915 
916             pcoex_info->p_buf = p_buf;
917             pcoex_info->opcode = opcode;
918             pcoex_info->p_cback = p_cback;
919 
920             ListAddToTail(&(pcoex_info->list), &(rtk_prof.coex_list));
921             pthread_mutex_unlock(&rtk_prof.coex_mutex);
922         }
923     }
924     return;
925 }
926 
rtk_notify_profileinfo_to_fw()927 void rtk_notify_profileinfo_to_fw()
928 {
929     RT_LIST_HEAD *head = NULL;
930     RT_LIST_ENTRY *iter = NULL, *temp = NULL;
931     tRTK_CONN_PROF *hci_conn = NULL;
932     uint8_t handle_number = 0;
933     uint32_t buffer_size = 0;
934     uint8_t *p_buf = NULL;
935 
936     head = &rtk_prof.conn_hash;
937     LIST_FOR_EACH_SAFELY(iter, temp, head)
938     {
939         hci_conn = LIST_ENTRY(iter, tRTK_CONN_PROF, list);
940         if (hci_conn && hci_conn->profile_bitmap)
941             handle_number++;
942     }
943 
944     buffer_size = 1 + handle_number * 3 + 1;
945 
946     p_buf = (uint8_t *)malloc(buffer_size);
947 
948     if (NULL == p_buf)
949     {
950         HILOGE("rtk_notify_profileinfo_to_fw: alloc error");
951         return;
952     }
953     uint8_t *p = (uint8_t *)p_buf;
954 
955     RtkLogMsg("rtk_notify_profileinfo_to_fw, BufferSize is %x", buffer_size);
956     *p++ = handle_number;
957     RtkLogMsg("rtk_notify_profileinfo_to_fw, NumberOfHandles is %x", handle_number);
958     head = &rtk_prof.conn_hash;
959     LIST_FOR_EACH_SAFELY(iter, temp, head)
960     {
961         hci_conn = LIST_ENTRY(iter, tRTK_CONN_PROF, list);
962         if (hci_conn && hci_conn->profile_bitmap)
963         {
964             UINT16_TO_STREAM(p, hci_conn->handle);
965             RtkLogMsg("rtk_notify_profileinfo_to_fw, handle is %x", hci_conn->handle);
966             *p++ = hci_conn->profile_bitmap;
967             RtkLogMsg("rtk_notify_profileinfo_to_fw, profile_bitmap is %x", hci_conn->profile_bitmap);
968             handle_number--;
969         }
970         if (0 == handle_number)
971             break;
972     }
973 
974     *p++ = rtk_prof.profile_status;
975     RtkLogMsg("rtk_notify_profileinfo_to_fw, profile_status is %x", rtk_prof.profile_status);
976 
977     rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_COMMAND, buffer_size, p_buf, NULL);
978 
979     free(p_buf);
980 
981     return;
982 }
983 
update_profile_state(uint8_t profile_index,uint8_t is_busy)984 void update_profile_state(uint8_t profile_index, uint8_t is_busy)
985 {
986     uint8_t need_update = FALSE;
987 
988     if ((rtk_prof.profile_bitmap & BIT(profile_index)) == 0)
989     {
990         HILOGE("update_profile_state: ERROR!!! profile(Index: %x) does not exist", profile_index);
991         return;
992     }
993 
994     if (is_busy)
995     {
996         if ((rtk_prof.profile_status & BIT(profile_index)) == 0)
997         {
998             need_update = TRUE;
999             rtk_prof.profile_status |= BIT(profile_index);
1000         }
1001     }
1002     else
1003     {
1004         if ((rtk_prof.profile_status & BIT(profile_index)) > 0)
1005         {
1006             need_update = TRUE;
1007             rtk_prof.profile_status &= ~(BIT(profile_index));
1008         }
1009     }
1010 
1011     if (need_update)
1012     {
1013         RtkLogMsg("update_profile_state, rtk_prof.profie_bitmap = %x", rtk_prof.profile_bitmap);
1014         RtkLogMsg("update_profile_state, rtk_prof.profile_status = %x", rtk_prof.profile_status);
1015         rtk_notify_profileinfo_to_fw();
1016     }
1017 }
1018 
rtk_check_setup_timer(int8_t profile_index)1019 void rtk_check_setup_timer(int8_t profile_index)
1020 {
1021     if (profile_index == profile_a2dp)
1022     {
1023         rtk_prof.a2dp_packet_count = 0;
1024         start_a2dp_packet_count_timer();
1025     }
1026     if (profile_index == profile_pan)
1027     {
1028         rtk_prof.pan_packet_count = 0;
1029         start_pan_packet_count_timer();
1030     }
1031     // hogp & voice share one timer now
1032     if ((profile_index == profile_hogp) || (profile_index == profile_voice))
1033     {
1034         if ((0 == rtk_prof.profile_refcount[profile_hogp]) && (0 == rtk_prof.profile_refcount[profile_voice]))
1035         {
1036             rtk_prof.hogp_packet_count = 0;
1037             rtk_prof.voice_packet_count = 0;
1038             start_hogp_packet_count_timer();
1039         }
1040     }
1041 }
1042 
rtk_check_del_timer(int8_t profile_index)1043 void rtk_check_del_timer(int8_t profile_index)
1044 {
1045     if (profile_a2dp == profile_index)
1046     {
1047         rtk_prof.a2dp_packet_count = 0;
1048         stop_a2dp_packet_count_timer();
1049     }
1050     if (profile_pan == profile_index)
1051     {
1052         rtk_prof.pan_packet_count = 0;
1053         stop_pan_packet_count_timer();
1054     }
1055     if (profile_hogp == profile_index)
1056     {
1057         rtk_prof.hogp_packet_count = 0;
1058         if (rtk_prof.profile_refcount[profile_voice] == 0)
1059             stop_hogp_packet_count_timer();
1060     }
1061     if (profile_voice == profile_index)
1062     {
1063         rtk_prof.voice_packet_count = 0;
1064         if (rtk_prof.profile_refcount[profile_hogp] == 0)
1065             stop_hogp_packet_count_timer();
1066     }
1067 }
update_profile_connection(tRTK_CONN_PROF * phci_conn,int8_t profile_index,uint8_t is_add)1068 void update_profile_connection(tRTK_CONN_PROF *phci_conn, int8_t profile_index, uint8_t is_add)
1069 {
1070     uint8_t need_update = FALSE;
1071     int kk = 0;
1072 
1073     RtkLogMsg("update_profile_connection: is_add=%d, psm_index=%d", is_add, profile_index);
1074     if (profile_index < 0)
1075         return;
1076 
1077     if (is_add)
1078     {
1079         if (rtk_prof.profile_refcount[profile_index] == 0)
1080         {
1081             need_update = TRUE;
1082             rtk_prof.profile_bitmap |= BIT(profile_index);
1083 
1084             // SCO is always busy
1085             if (profile_index == profile_sco)
1086                 rtk_prof.profile_status |= BIT(profile_index);
1087 
1088             rtk_check_setup_timer(profile_index);
1089         }
1090         rtk_prof.profile_refcount[profile_index]++;
1091 
1092         if (0 == phci_conn->profile_refcount[profile_index])
1093         {
1094             need_update = TRUE;
1095             phci_conn->profile_bitmap |= BIT(profile_index);
1096         }
1097         phci_conn->profile_refcount[profile_index]++;
1098     }
1099     else
1100     {
1101         rtk_prof.profile_refcount[profile_index]--;
1102         RtkLogMsg("for test: --, rtk_prof.profile_refcount[%x] = %x", profile_index, rtk_prof.profile_refcount[profile_index]);
1103         if (rtk_prof.profile_refcount[profile_index] == 0)
1104         {
1105             need_update = TRUE;
1106             rtk_prof.profile_bitmap &= ~(BIT(profile_index));
1107 
1108             // If profile does not exist, Status is meaningless
1109             rtk_prof.profile_status &= ~(BIT(profile_index));
1110             rtk_check_del_timer(profile_index);
1111         }
1112 
1113         phci_conn->profile_refcount[profile_index]--;
1114         if (0 == phci_conn->profile_refcount[profile_index])
1115         {
1116             need_update = TRUE;
1117             phci_conn->profile_bitmap &= ~(BIT(profile_index));
1118 
1119             // clear profile_hid_interval if need
1120             if (profile_hid == profile_index)
1121             {
1122                 if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval))))
1123                 {
1124                     phci_conn->profile_bitmap &= ~(BIT(profile_hid_interval));
1125                     rtk_prof.profile_refcount[profile_hid_interval]--;
1126                 }
1127             }
1128         }
1129     }
1130 
1131     if (need_update)
1132     {
1133         RtkLogMsg("update_profile_connection: rtk_h5.profile_bitmap = %x", rtk_prof.profile_bitmap);
1134         for (kk = 0; kk < 8; kk++)
1135             RtkLogMsg("update_profile_connection: rtk_h5.profile_refcount[%d] = %d", kk, rtk_prof.profile_refcount[kk]);
1136         rtk_notify_profileinfo_to_fw();
1137     }
1138 }
1139 
update_hid_active_state(uint16_t handle,uint16_t interval)1140 void update_hid_active_state(uint16_t handle, uint16_t interval)
1141 {
1142     uint8_t need_update = 0;
1143     RtkLogMsg("update_hid_active_state: handle = %x, interval = 0x%x", handle, interval);
1144     tRTK_CONN_PROF *phci_conn = find_connection_by_handle(&rtk_prof, handle);
1145 
1146     if (phci_conn == NULL)
1147         return;
1148 
1149     if (((phci_conn->profile_bitmap) & (BIT(profile_hid))) == 0)
1150     {
1151         RtkLogMsg("hid not connected in the handle, nothing to be down");
1152         return;
1153     }
1154 
1155     if (interval < 60)
1156     {
1157         if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval))) == 0)
1158         {
1159             need_update = 1;
1160             phci_conn->profile_bitmap |= BIT(profile_hid_interval);
1161 
1162             rtk_prof.profile_refcount[profile_hid_interval]++;
1163             if (rtk_prof.profile_refcount[profile_hid_interval] == 1)
1164                 rtk_prof.profile_status |= BIT(profile_hid);
1165         }
1166     }
1167     else
1168     {
1169         if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval))))
1170         {
1171             need_update = 1;
1172             phci_conn->profile_bitmap &= ~(BIT(profile_hid_interval));
1173 
1174             rtk_prof.profile_refcount[profile_hid_interval]--;
1175             if (rtk_prof.profile_refcount[profile_hid_interval] == 0)
1176                 rtk_prof.profile_status &= ~(BIT(profile_hid));
1177         }
1178     }
1179 
1180     if (need_update)
1181         rtk_notify_profileinfo_to_fw();
1182 }
handle_l2cap_con_req(uint16_t handle,uint16_t psm,uint16_t scid,uint8_t direction)1183 uint8_t handle_l2cap_con_req(uint16_t handle, uint16_t psm, uint16_t scid, uint8_t direction)
1184 {
1185     uint8_t status = FALSE;
1186     tRTK_PROF_INFO *prof_info = NULL;
1187 
1188     int8_t profile_index = psm_to_profile_index(psm);
1189 
1190     if (profile_index < 0)
1191     {
1192         RtkLogMsg("PSM(0x%x) do not need parse", psm);
1193         return status;
1194     }
1195 
1196     pthread_mutex_lock(&rtk_prof.profile_mutex);
1197     if (direction) // 1: out
1198         prof_info = find_profile_by_handle_scid(&rtk_prof, handle, scid);
1199     else // 0:in
1200         prof_info = find_profile_by_handle_dcid(&rtk_prof, handle, scid);
1201 
1202     if (prof_info)
1203     {
1204         RtkLogMsg("handle_l2cap_con_req: This profile is already exist!!!");
1205         pthread_mutex_unlock(&rtk_prof.profile_mutex);
1206         return status;
1207     }
1208 
1209     if (direction) // 1: out
1210         status = list_allocate_add(handle, psm, profile_index, 0, scid);
1211     else // 0:in
1212         status = list_allocate_add(handle, psm, profile_index, scid, 0);
1213 
1214     pthread_mutex_unlock(&rtk_prof.profile_mutex);
1215 
1216     if (!status)
1217         HILOGE("handle_l2cap_con_req: list_allocate_add failed!");
1218 
1219     return status;
1220 }
1221 
handle_l2cap_con_rsp(uint16_t handle,uint16_t dcid,uint16_t scid,uint8_t direction,uint8_t result)1222 uint8_t handle_l2cap_con_rsp(uint16_t handle, uint16_t dcid, uint16_t scid, uint8_t direction, uint8_t result)
1223 {
1224     tRTK_PROF_INFO *prof_info = NULL;
1225 
1226     pthread_mutex_lock(&rtk_prof.profile_mutex);
1227     if (!direction) // 0, in
1228         prof_info = find_profile_by_handle_scid(&rtk_prof, handle, scid);
1229     else // 1, out
1230         prof_info = find_profile_by_handle_dcid(&rtk_prof, handle, scid);
1231 
1232     if (!prof_info)
1233     {
1234         // RtkLogMsg("handle_l2cap_con_rsp: prof_info Not Find!!");
1235         pthread_mutex_unlock(&rtk_prof.profile_mutex);
1236         return 0;
1237     }
1238 
1239     if (!result) // success
1240     {
1241         RtkLogMsg("l2cap connection success, update connection");
1242         if (!direction) // 0, in
1243             prof_info->dcid = dcid;
1244         else // 1, out
1245             prof_info->scid = dcid;
1246 
1247         tRTK_CONN_PROF *phci_conn = find_connection_by_handle(&rtk_prof, handle);
1248         if (phci_conn)
1249             update_profile_connection(phci_conn, prof_info->profile_index, TRUE);
1250     }
1251 
1252     pthread_mutex_unlock(&rtk_prof.profile_mutex);
1253     return 1;
1254 }
1255 
handle_l2cap_discon_req(uint16_t handle,uint16_t dcid,uint16_t scid,uint8_t direction)1256 uint8_t handle_l2cap_discon_req(uint16_t handle, uint16_t dcid, uint16_t scid, uint8_t direction)
1257 {
1258     tRTK_PROF_INFO *prof_info = NULL;
1259     RtkLogMsg("l2cap_discon_req, handle = %x, dcid = %x, scid = %x, direction = %x", handle, dcid, scid, direction);
1260     pthread_mutex_lock(&rtk_prof.profile_mutex);
1261     if (!direction) // 0: in
1262         prof_info = find_profile_by_handle_dcid_scid(&rtk_prof, handle, scid, dcid);
1263     else // 1: out
1264         prof_info = find_profile_by_handle_dcid_scid(&rtk_prof, handle, dcid, scid);
1265 
1266     if (!prof_info)
1267     {
1268         // RtkLogMsg("handle_l2cap_discon_req: prof_info Not Find!");
1269         pthread_mutex_unlock(&rtk_prof.profile_mutex);
1270         return 0;
1271     }
1272 
1273     tRTK_CONN_PROF *phci_conn = find_connection_by_handle(&rtk_prof, handle);
1274     if (NULL == phci_conn)
1275     {
1276         pthread_mutex_unlock(&rtk_prof.profile_mutex);
1277         return 0;
1278     }
1279 
1280     update_profile_connection(phci_conn, prof_info->profile_index, FALSE);
1281     if (prof_info->profile_index == profile_a2dp && (phci_conn->profile_bitmap & BIT(profile_sink)))
1282         update_profile_connection(phci_conn, profile_sink, FALSE);
1283     delete_profile_from_hash(prof_info);
1284     pthread_mutex_unlock(&rtk_prof.profile_mutex);
1285 
1286     return 1;
1287 }
1288 
packets_count(uint16_t handle,uint16_t scid,uint16_t length,uint8_t direction,uint8_t * user_data)1289 void packets_count(uint16_t handle, uint16_t scid, uint16_t length, uint8_t direction, uint8_t *user_data)
1290 {
1291     tRTK_PROF_INFO *prof_info = NULL;
1292     // uint8_t profile_type;
1293 
1294     tRTK_CONN_PROF *hci_conn = find_connection_by_handle(&rtk_prof, handle);
1295     if (NULL == hci_conn)
1296         return;
1297 
1298     if (0 == hci_conn->type) // l2cap
1299     {
1300         if (!direction) // 0: in
1301             prof_info = find_profile_by_handle_scid(&rtk_prof, handle, scid);
1302         else // 1: out
1303             prof_info = find_profile_by_handle_dcid(&rtk_prof, handle, scid);
1304 
1305         if (!prof_info)
1306         {
1307             return;
1308         }
1309 
1310         if ((prof_info->profile_index == profile_a2dp) && (length > 100)) // avdtp media data
1311         {
1312             if (!is_profile_busy(profile_a2dp))
1313             {
1314                 struct sbc_frame_hdr *sbc_header;
1315                 struct rtp_header *rtph;
1316                 uint8_t bitpool;
1317                 update_profile_state(profile_a2dp, TRUE);
1318                 if (!direction)
1319                 {
1320                     update_profile_connection(hci_conn, profile_sink, true);
1321                     update_profile_state(profile_sink, TRUE);
1322                 }
1323                 rtph = (struct rtp_header *)user_data;
1324                 RtkLogMsg("rtp: v %u, cc %u, pt %u", rtph->v, rtph->cc, rtph->pt);
1325                 /* move forward */
1326                 user_data += sizeof(struct rtp_header) + rtph->cc * 4 + 1;
1327                 /* point to the sbc frame header */
1328                 sbc_header = (struct sbc_frame_hdr *)user_data;
1329                 bitpool = sbc_header->bitpool;
1330                 print_sbc_header(sbc_header);
1331                 RtkLogMsg("rtp: v %u, cc %u, pt %u", rtph->v, rtph->cc, rtph->pt);
1332                 rtk_vendor_cmd_to_fw(HCI_VENDOR_ADD_BITPOOL_FW, 1, &bitpool, NULL);
1333             }
1334             rtk_prof.a2dp_packet_count++;
1335         }
1336 
1337         if (prof_info->profile_index == profile_pan)
1338             rtk_prof.pan_packet_count++;
1339     }
1340 }
1341 
timeout_handler(int signo,siginfo_t * info,void * context)1342 static void timeout_handler(int signo, siginfo_t *info, void *context)
1343 {
1344     RTK_UNUSED(info);
1345     RTK_UNUSED(context);
1346     if (signo == TIMER_POLLING)
1347     {
1348         RtkLogMsg("polling timeout");
1349         if (rtk_prof.polling_enable)
1350         {
1351             uint8_t temp_cmd[1];
1352             temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO;
1353             rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 1, temp_cmd, NULL);
1354         }
1355     }
1356     else if (signo == TIMER_A2DP_PACKET_COUNT)
1357     {
1358         RtkLogMsg("count a2dp packet timeout, a2dp_packet_count = %d", rtk_prof.a2dp_packet_count);
1359         if (rtk_prof.a2dp_packet_count == 0)
1360         {
1361             if (is_profile_busy(profile_a2dp))
1362             {
1363                 RtkLogMsg("timeout_handler: a2dp busy->idle!");
1364                 update_profile_state(profile_a2dp, FALSE);
1365                 if (is_profile_busy(profile_sink))
1366                 {
1367                     RtkLogMsg("timeout_handler: sink busy->idle!");
1368                     update_profile_state(profile_sink, FALSE);
1369                 }
1370             }
1371         }
1372         rtk_prof.a2dp_packet_count = 0;
1373     }
1374     else if (signo == TIMER_HOGP_PACKET_COUNT)
1375     {
1376         RtkLogMsg("count hogp packet timeout, hogp_packet_count = %d", rtk_prof.hogp_packet_count);
1377         if (rtk_prof.hogp_packet_count == 0)
1378         {
1379             if (is_profile_busy(profile_hogp))
1380             {
1381                 RtkLogMsg("timeout_handler: hogp busy->idle!");
1382                 update_profile_state(profile_hogp, FALSE);
1383             }
1384         }
1385         rtk_prof.hogp_packet_count = 0;
1386 
1387         RtkLogMsg("count hogp packet timeout, voice_packet_count = %d", rtk_prof.voice_packet_count);
1388         if (rtk_prof.voice_packet_count == 0)
1389         {
1390             if (is_profile_busy(profile_voice))
1391             {
1392                 RtkLogMsg("timeout_handler: voice busy->idle!");
1393                 update_profile_state(profile_voice, FALSE);
1394             }
1395         }
1396         rtk_prof.voice_packet_count = 0;
1397     }
1398     else if (signo == TIMER_PAN_PACKET_COUNT)
1399     {
1400         RtkLogMsg("count pan packet timeout, pan_packet_count = %d", rtk_prof.pan_packet_count);
1401         if (rtk_prof.pan_packet_count < PAN_PACKET_COUNT)
1402         {
1403             if (is_profile_busy(profile_pan))
1404             {
1405                 RtkLogMsg("timeout_handler: pan busy->idle!");
1406                 update_profile_state(profile_pan, FALSE);
1407             }
1408         }
1409         else
1410         {
1411             if (!is_profile_busy(profile_pan))
1412             {
1413                 RtkLogMsg("timeout_handler: pan idle->busy!");
1414                 update_profile_state(profile_pan, TRUE);
1415             }
1416         }
1417         rtk_prof.pan_packet_count = 0;
1418     }
1419     else
1420     {
1421         HILOGE("rtk_parse_data timer unspported signo(%d)", signo);
1422     }
1423 }
1424 
notify_func(union sigval sig)1425 static void notify_func(union sigval sig)
1426 {
1427     int signo = sig.sival_int;
1428     timeout_handler(signo, NULL, NULL);
1429 }
1430 
1431 #if 0
1432 int netlink_send(int nlsk, char *buffer)
1433 {
1434     struct nlmsghdr* nlhdr;
1435     struct iovec iov;
1436     struct msghdr msg;
1437     struct sockaddr_nl nladdr;
1438 
1439     if(nlsk <= 0)
1440         return -1;
1441 
1442     memset(&msg, 0 ,sizeof(struct msghdr));
1443     memset(&nladdr, 0 ,sizeof(struct sockaddr_nl));
1444 
1445     nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(strlen(buffer) + 1));
1446     strcpy(NLMSG_DATA(nlhdr),buffer);
1447 
1448     nlhdr->nlmsg_len = NLMSG_LENGTH(strlen(buffer) + 1);
1449     nlhdr->nlmsg_pid = getpid(); //sender pid
1450     nlhdr->nlmsg_flags = NLM_F_REQUEST;
1451     nlhdr->nlmsg_type = NLMSG_MIN_TYPE;
1452 
1453     nladdr.nl_family = AF_NETLINK;
1454     nladdr.nl_pid = 0; //send to kernel
1455     nladdr.nl_groups = 0;
1456 
1457     iov.iov_base = (void *)nlhdr;
1458     iov.iov_len = nlhdr->nlmsg_len;
1459 
1460     msg.msg_iov = &iov;
1461     msg.msg_iovlen = 1;
1462     msg.msg_name = (void *)&(nladdr);
1463     msg.msg_namelen = sizeof(nladdr);
1464 
1465     return sendmsg(nlsk, &msg, 0);
1466 }
1467 #endif
1468 
udpsocket_send(char * tx_msg,int msg_size)1469 int udpsocket_send(char *tx_msg, int msg_size)
1470 {
1471     int n; /* message byte size */
1472 
1473     RtkLogMsg("udpsocket_send tx_msg:%s", tx_msg);
1474     n = sendto(rtk_prof.udpsocket, tx_msg, msg_size, 0, (struct sockaddr *)&rtk_prof.client_addr, sizeof(rtk_prof.client_addr));
1475     if (n < 0)
1476     {
1477         HILOGE("ERROR in sendto");
1478         return -1;
1479     }
1480     return 0;
1481 }
1482 
udpsocket_recv(uint8_t * recv_msg,uint8_t * msg_size)1483 int udpsocket_recv(uint8_t *recv_msg, uint8_t *msg_size)
1484 {
1485     // struct hostent *hostp;  /* client host info */
1486     char buf[MAX_PAYLOAD]; /* message buf */
1487     // char *hostaddrp;        /* dotted decimal host addr string */
1488     int n; /* message byte size */
1489     struct sockaddr_in recv_addr;
1490     socklen_t clientlen = sizeof(recv_addr);
1491     struct pollfd pfd = {
1492         .events = POLLPRI | POLLIN,
1493         .revents = 0,
1494         .fd = rtk_prof.udpsocket};
1495 
1496     bzero(buf, MAX_PAYLOAD);
1497 
1498     while (poll(&pfd, 1, 1000) <= 0)
1499     {
1500         if (rtk_prof.coex_recv_thread_running == 0)
1501         {
1502             RtkLogMsg("%s, SIGUSR2 should have caught us before this", __func__);
1503             return -1;
1504         }
1505     }
1506 
1507     n = recvfrom(rtk_prof.udpsocket, buf, MAX_PAYLOAD, 0, (struct sockaddr *)&recv_addr, &clientlen);
1508     if (n < 0)
1509     {
1510         HILOGE("ERROR in recvfrom");
1511         return -1;
1512     }
1513     else
1514     {
1515         *msg_size = n;
1516         memcpy(recv_msg, buf, n);
1517     }
1518     return 0;
1519 }
1520 
btcoex_chr_send(char * tx_msg,int msg_size)1521 int btcoex_chr_send(char *tx_msg, int msg_size)
1522 {
1523     int n; /* message byte size */
1524 
1525     RtkLogMsg("btcoex_chr_send tx_msg:%s", tx_msg);
1526     RTK_NO_INTR(n = write(rtk_prof.btcoex_chr, tx_msg, msg_size));
1527     if (n < 0)
1528     {
1529         HILOGE("ERROR in write");
1530         return -1;
1531     }
1532     return n;
1533 }
1534 
btcoex_chr_recv(uint8_t * recv_msg,uint8_t * msg_size)1535 int btcoex_chr_recv(uint8_t *recv_msg, uint8_t *msg_size)
1536 {
1537     char buf[MAX_PAYLOAD]; /* message buf */
1538     int n = -1;            /* message byte size */
1539     struct pollfd pfd = {
1540         .events = POLLPRI | POLLIN | POLLHUP | POLLERR | POLLRDHUP,
1541         .revents = 0,
1542         .fd = rtk_prof.btcoex_chr};
1543 
1544     bzero(buf, MAX_PAYLOAD);
1545 
1546     while (poll(&pfd, 1, 1000) <= 0)
1547     {
1548         if (rtk_prof.coex_recv_thread_running == 0)
1549         {
1550             RtkLogMsg("%s, SIGUSR2 should have caught us before this", __func__);
1551             return -1;
1552         }
1553     }
1554 
1555     if (pfd.revents & POLLIN)
1556     {
1557         RTK_NO_INTR(n = read(rtk_prof.btcoex_chr, buf, MAX_PAYLOAD));
1558         if (n < 0)
1559         {
1560             HILOGE("ERROR in recvfrom");
1561             return -1;
1562         }
1563         else
1564         {
1565             *msg_size = n;
1566             memcpy(recv_msg, buf, n);
1567         }
1568     }
1569     else
1570     {
1571         HILOGE("rtk_btcoex is wrong");
1572         return -1;
1573     }
1574     return 0;
1575 }
1576 
rtk_notify_extension_version_to_wifi()1577 void rtk_notify_extension_version_to_wifi()
1578 {
1579     uint8_t para_length = 2;
1580     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1581 
1582     if (!rtk_prof.wifi_on)
1583         return;
1584 
1585     char *p = p_buf;
1586     UINT16_TO_STREAM(p, HCI_OP_HCI_EXTENSION_VERSION_NOTIFY);
1587     *p++ = para_length;
1588     UINT16_TO_STREAM(p, HCI_EXTENSION_VERSION);
1589     RtkLogMsg("extension version is 0x%x", HCI_EXTENSION_VERSION);
1590     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1591         HILOGE("rtk_notify_extension_version_to_wifi: udpsocket send error");
1592 }
1593 
rtk_notify_btpatch_version_to_wifi()1594 void rtk_notify_btpatch_version_to_wifi()
1595 {
1596     uint8_t para_length = 4;
1597     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1598 
1599     if (!rtk_prof.wifi_on)
1600         return;
1601 
1602     char *p = p_buf;
1603     UINT16_TO_STREAM(p, HCI_OP_HCI_BT_PATCH_VER_NOTIFY);
1604     *p++ = para_length;
1605     UINT16_TO_STREAM(p, rtk_prof.hci_reversion);
1606     UINT16_TO_STREAM(p, rtk_prof.lmp_subversion);
1607     RtkLogMsg("btpatch_version, length is 0x%x, hci_reversion is 0x%x, lmp_subversion is %x", para_length, rtk_prof.hci_reversion, rtk_prof.lmp_subversion);
1608 
1609     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1610         HILOGE("rtk_notify_btpatch_version_to_wifi: udpsocket send error");
1611 }
1612 
rtk_notify_afhmap_to_wifi()1613 void rtk_notify_afhmap_to_wifi()
1614 {
1615     uint8_t para_length = 13;
1616     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1617 
1618     if (!rtk_prof.wifi_on)
1619         return;
1620 
1621     char *p = p_buf;
1622     UINT16_TO_STREAM(p, HCI_OP_HCI_BT_AFH_MAP_NOTIFY);
1623     *p++ = para_length;
1624     *p++ = rtk_prof.piconet_id;
1625     *p++ = rtk_prof.mode;
1626     *p++ = 10;
1627     memcpy(p, rtk_prof.afh_map, 10);
1628 
1629     RtkLogMsg("afhmap, piconet_id is 0x%x, map type is 0x%x", rtk_prof.piconet_id, rtk_prof.mode);
1630     uint8_t kk = 0;
1631     for (kk = 0; kk < 10; kk++)
1632         RtkLogMsg("afhmap data[%d] is 0x%x", kk, rtk_prof.afh_map[kk]);
1633 
1634     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1635         HILOGE("rtk_notify_afhmap_to_wifi: udpsocket send error");
1636 }
1637 
rtk_notify_btcoex_to_wifi(uint8_t opcode,uint8_t status)1638 void rtk_notify_btcoex_to_wifi(uint8_t opcode, uint8_t status)
1639 {
1640     uint8_t para_length = 2;
1641     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1642 
1643     if (!rtk_prof.wifi_on)
1644         return;
1645 
1646     char *p = p_buf;
1647     UINT16_TO_STREAM(p, HCI_OP_HCI_BT_COEX_NOTIFY);
1648     *p++ = para_length;
1649     *p++ = opcode;
1650     if (!status)
1651         *p++ = 0;
1652     else
1653         *p++ = 1;
1654 
1655     RtkLogMsg("btcoex, opcode is 0x%x, status is 0x%x", opcode, status);
1656 
1657     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1658         HILOGE("rtk_notify_btcoex_to_wifi: udpsocket send error");
1659 }
1660 
rtk_notify_btoperation_to_wifi(uint8_t operation,uint8_t append_data_length,uint8_t * append_data)1661 void rtk_notify_btoperation_to_wifi(uint8_t operation, uint8_t append_data_length, uint8_t *append_data)
1662 {
1663     uint8_t para_length = 3 + append_data_length;
1664     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1665 
1666     if (!rtk_prof.wifi_on)
1667         return;
1668 
1669     char *p = p_buf;
1670     UINT16_TO_STREAM(p, HCI_OP_BT_OPERATION_NOTIFY);
1671     *p++ = para_length;
1672     *p++ = operation;
1673     *p++ = append_data_length;
1674     if (append_data_length)
1675         memcpy(p, append_data, append_data_length);
1676 
1677     RtkLogMsg("btoperation, opration is 0x%x, append_data_length is 0x%x", operation, append_data_length);
1678     uint8_t kk = 0;
1679     if (append_data_length)
1680     {
1681         for (kk = 0; kk < append_data_length; kk++)
1682             RtkLogMsg("append data is 0x%x", *(append_data + kk));
1683     }
1684 
1685     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1686         HILOGE("rtk_notify_btoperation_to_wifi: udpsocket send error");
1687 }
1688 
rtk_notify_info_to_wifi(uint8_t reason,uint8_t length,uint8_t * report_info)1689 void rtk_notify_info_to_wifi(uint8_t reason, uint8_t length, uint8_t *report_info)
1690 {
1691     uint8_t para_length = 4 + length;
1692     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1693     int i;
1694 
1695     if (!rtk_prof.wifi_on)
1696         return;
1697 
1698     char *p = p_buf;
1699     UINT16_TO_STREAM(p, HCI_OP_HCI_BT_INFO_NOTIFY);
1700     *p++ = para_length;
1701     *p++ = rtk_prof.polling_enable;
1702     *p++ = rtk_prof.polling_interval;
1703     *p++ = reason;
1704     *p++ = length;
1705 
1706     if (length)
1707         memcpy(p, report_info, length);
1708 
1709     RtkLogMsg("bt info, length is 0x%x, polling_enable is 0x%x, poiiling_interval is %x", para_length, rtk_prof.polling_enable, rtk_prof.polling_interval);
1710     RtkLogMsg("bt info, reason is 0x%x, info length is 0x%x", reason, length);
1711     if (length)
1712     {
1713         for (i = 0; i < length; i++)
1714             RtkLogMsg("bt info[%d]: %02x", i, report_info[i]);
1715     }
1716 
1717     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1718         HILOGE("rtk_notify_info_to_wifi: udpsocket send error");
1719 }
1720 
rtk_notify_regester_to_wifi(uint8_t * reg_value)1721 void rtk_notify_regester_to_wifi(uint8_t *reg_value)
1722 {
1723     uint8_t para_length = 9;
1724     char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
1725 
1726     if (!rtk_prof.wifi_on)
1727         return;
1728 
1729     char *p = p_buf;
1730     UINT16_TO_STREAM(p, HCI_OP_HCI_BT_REGISTER_VALUE_NOTIFY);
1731     *p++ = para_length;
1732     memcpy(p, reg_value, para_length);
1733 
1734     tHCI_RETURN_PARAMETER_MAILBOX_REGISTER *reg = (tHCI_RETURN_PARAMETER_MAILBOX_REGISTER *)reg_value;
1735     RtkLogMsg("bt register, register type is %x", reg->type);
1736     RtkLogMsg("bt register, register offset is %x", reg->offset);
1737     RtkLogMsg("bt register, register value is %x", reg->value);
1738 
1739     if (coex_msg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
1740         HILOGE("rtk_notify_regester_to_wifi: udpsocket send error");
1741 }
1742 
rtk_handle_bt_info_control(uint8_t * p)1743 static void rtk_handle_bt_info_control(uint8_t *p)
1744 {
1745     tHCI_EVENT_BT_INFO_CONTROL *info = (tHCI_EVENT_BT_INFO_CONTROL *)p;
1746     uint8_t temp_cmd[3];
1747 
1748     RtkLogMsg("rtk_prof.polling_enable is %x", rtk_prof.polling_enable);
1749     RtkLogMsg("receive bt info control event from wifi, polling enable is 0x%x, polling time is 0x%x, auto report is 0x%x",
1750               info->polling_enable, info->polling_time, info->autoreport_enable);
1751 
1752     if (info->polling_enable && !rtk_prof.polling_enable)
1753         start_polling_timer(info->polling_time * 1000);
1754 
1755     if (!info->polling_enable && rtk_prof.polling_enable)
1756         stop_polling_timer();
1757 
1758     rtk_prof.polling_enable = info->polling_enable;
1759     rtk_prof.polling_interval = info->polling_time;
1760     rtk_prof.autoreport = info->autoreport_enable;
1761 
1762     temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE;
1763     temp_cmd[1] = 1;
1764     temp_cmd[2] = info->autoreport_enable;
1765     rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd, NULL);
1766 
1767     rtk_notify_info_to_wifi(HOST_RESPONSE, 0, NULL);
1768 }
1769 
rtk_handle_bt_coex_control(uint8_t * p)1770 static void rtk_handle_bt_coex_control(uint8_t *p)
1771 {
1772     uint8_t opcode = *p++;
1773     uint8_t op_len = 0;
1774     RtkLogMsg("receive bt coex control event from wifi, opration is 0x%x", opcode);
1775     switch (opcode)
1776     {
1777     case BT_PATCH_VERSION_QUERY:
1778     {
1779         rtk_notify_btpatch_version_to_wifi();
1780         break;
1781     }
1782 
1783     case IGNORE_WLAN_ACTIVE_CONTROL:
1784     {
1785         uint8_t opcode_len = *p++;
1786         uint8_t value = *p++;
1787         uint8_t temp_cmd[3];
1788         op_len = opcode_len;
1789         temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD;
1790         temp_cmd[1] = 1;
1791         temp_cmd[2] = value;
1792         rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd, NULL);
1793         break;
1794     }
1795 
1796     case LNA_CONSTRAIN_CONTROL:
1797     {
1798         uint8_t opcode_len = *p++;
1799         uint8_t value = *p++;
1800         uint8_t temp_cmd[3];
1801         op_len = opcode_len;
1802         temp_cmd[0] = HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT;
1803         temp_cmd[1] = 1;
1804         temp_cmd[2] = value;
1805         rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd, NULL);
1806         break;
1807     }
1808 
1809     case BT_POWER_DECREASE_CONTROL:
1810     {
1811         uint8_t opcode_len = *p++;
1812         uint8_t power_decrease = *p++;
1813         uint8_t temp_cmd[3];
1814         op_len = opcode_len;
1815         temp_cmd[0] = HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD;
1816         temp_cmd[1] = 1;
1817         temp_cmd[2] = power_decrease;
1818         rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd, NULL);
1819         break;
1820     }
1821 
1822     case BT_PSD_MODE_CONTROL:
1823     {
1824         uint8_t opcode_len = *p++;
1825         uint8_t psd_mode = *p++;
1826         uint8_t temp_cmd[3];
1827         op_len = opcode_len;
1828         temp_cmd[0] = HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE;
1829         temp_cmd[1] = 1;
1830         temp_cmd[2] = psd_mode;
1831         rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd, NULL);
1832         break;
1833     }
1834 
1835     case WIFI_BW_CHNL_NOTIFY:
1836     {
1837         uint8_t opcode_len = *p++;
1838         uint8_t temp_cmd[5];
1839         op_len = opcode_len;
1840         temp_cmd[0] = HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD;
1841         temp_cmd[1] = 3;
1842         memcpy(temp_cmd + 2, p, 3); // wifi_state, wifi_centralchannel, chnnels_btnotuse
1843         rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 5, temp_cmd, NULL);
1844         break;
1845     }
1846 
1847     case QUERY_BT_AFH_MAP:
1848     {
1849         uint8_t opcode_len = *p++;
1850         rtk_prof.piconet_id = *p++;
1851         rtk_prof.mode = *p++;
1852         uint8_t temp_cmd[4];
1853         op_len = opcode_len;
1854         temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L;
1855         temp_cmd[1] = 2;
1856         temp_cmd[2] = rtk_prof.piconet_id;
1857         temp_cmd[3] = rtk_prof.mode;
1858         rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4, temp_cmd, NULL);
1859         break;
1860     }
1861 
1862     case BT_REGISTER_ACCESS:
1863     {
1864         uint8_t opcode_len = *p++;
1865         uint8_t access_type = *p++;
1866         op_len = opcode_len;
1867         if (access_type == 0) // read
1868         {
1869             uint8_t temp_cmd[7];
1870             temp_cmd[0] = HCI_VENDOR_SUB_CMD_RD_REG_REQ;
1871             temp_cmd[1] = 5;
1872             temp_cmd[2] = *p++;
1873             memcpy(temp_cmd + 3, p, 4);
1874             rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 7, temp_cmd, NULL);
1875         }
1876         else // write
1877         {
1878             uint8_t temp_cmd[11];
1879             temp_cmd[0] = HCI_VENDOR_SUB_CMD_RD_REG_REQ;
1880             temp_cmd[1] = 5;
1881             temp_cmd[2] = *p++;
1882             memcpy(temp_cmd + 3, p, 8);
1883             rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 11, temp_cmd, NULL);
1884         }
1885         break;
1886     }
1887 
1888     default:
1889         break;
1890     }
1891 }
1892 
rtk_handle_event_from_wifi(uint8_t * msg)1893 void rtk_handle_event_from_wifi(uint8_t *msg)
1894 {
1895     uint8_t *p = msg;
1896     uint8_t event_code = *p++;
1897     uint8_t total_length = 0;
1898 
1899     RtkLogMsg("receive invite rsp from wifi msg : %s", msg);
1900     if (memcmp(msg, invite_rsp, sizeof(invite_rsp)) == 0)
1901     {
1902 #if 0
1903         RtkLogMsg("receive invite rsp from wifi, close netlink socket if needed");
1904         if(rtk_prof.nlsocket > 0)
1905         {
1906             close(rtk_prof.nlsocket);
1907             RtkLogMsg("close netlink socket %d", rtk_prof.nlsocket);
1908         }
1909 #endif
1910         RtkLogMsg("receive invite rsp from wifi, wifi is already on");
1911         rtk_prof.wifi_on = 1;
1912         rtk_notify_extension_version_to_wifi();
1913     }
1914 
1915     if (memcmp(msg, attend_req, sizeof(attend_req)) == 0)
1916     {
1917         RtkLogMsg("receive attend req from wifi, wifi turn on");
1918         rtk_prof.wifi_on = 1;
1919         coex_msg_send(attend_ack, sizeof(attend_ack));
1920         rtk_notify_extension_version_to_wifi();
1921     }
1922 
1923     if (memcmp(msg, wifi_leave, sizeof(wifi_leave)) == 0)
1924     {
1925         RtkLogMsg("receive wifi leave from wifi, wifi turn off");
1926         rtk_prof.wifi_on = 0;
1927         coex_msg_send(leave_ack, sizeof(leave_ack));
1928         if (rtk_prof.polling_enable)
1929         {
1930             rtk_prof.polling_enable = 0;
1931             stop_polling_timer();
1932         }
1933     }
1934 
1935     if (memcmp(msg, leave_ack, sizeof(leave_ack)) == 0)
1936     {
1937         RtkLogMsg("receive leave ack from wifi");
1938     }
1939 
1940     if (event_code == 0xFE)
1941     {
1942         total_length = *p++;
1943         uint8_t extension_event = *p++;
1944         switch (extension_event)
1945         {
1946         case RTK_HS_EXTENSION_EVENT_WIFI_SCAN:
1947         {
1948             uint8_t operation = *p;
1949             RtkLogMsg("receive wifi scan notify evnet from wifi, operation is 0x%x", operation);
1950             break;
1951         }
1952 
1953         case RTK_HS_EXTENSION_EVENT_HCI_BT_INFO_CONTROL:
1954         {
1955             rtk_handle_bt_info_control(p);
1956             break;
1957         }
1958 
1959         case RTK_HS_EXTENSION_EVENT_HCI_BT_COEX_CONTROL:
1960         {
1961             rtk_handle_bt_coex_control(p);
1962             break;
1963         }
1964 
1965         default:
1966             break;
1967         }
1968     }
1969 
1970     if (event_code == 0x0E)
1971     {
1972         uint16_t wifi_opcode;
1973         uint8_t op_status;
1974         p += 2; // length, number of complete packets
1975         STREAM_TO_UINT16(wifi_opcode, p);
1976         op_status = *p;
1977         RtkLogMsg("receive command complete event from wifi, op code is 0x%x, status is 0x%x", wifi_opcode, op_status);
1978     }
1979 }
1980 
coex_receive_thread_exit_handler(int sig)1981 static void coex_receive_thread_exit_handler(int sig)
1982 {
1983     RtkLogMsg("USR2, this signal is %d \n", sig);
1984     usleep(100);
1985     pthread_exit(0);
1986 }
1987 
btwifi_coex_receive_thread(void * arg)1988 static void btwifi_coex_receive_thread(void *arg)
1989 {
1990     RTK_UNUSED(arg);
1991     uint8_t msg_recv[MAX_PAYLOAD];
1992     uint8_t recv_length;
1993     struct sigaction actions;
1994 
1995     memset(&actions, 0, sizeof(actions));
1996     sigemptyset(&actions.sa_mask);
1997     actions.sa_flags = 0;
1998     actions.sa_handler = coex_receive_thread_exit_handler;
1999 
2000     sigaction(SIGUSR2, &actions, NULL); // int rc = sigaction(SIGUSR2,&actions,NULL);
2001 
2002     RtkLogMsg("btwifi_coex_receive_thread started");
2003     prctl(PR_SET_NAME, (unsigned long)"btwifi_coex_receive_thread", 0, 0, 0);
2004 
2005     while (rtk_prof.coex_recv_thread_running)
2006     {
2007         memset(msg_recv, 0, MAX_PAYLOAD);
2008         if (coex_msg_recv(msg_recv, &recv_length) == 0)
2009             rtk_handle_event_from_wifi(msg_recv);
2010     }
2011 
2012     RtkLogMsg("btwifi_coex_receive_thread exiting");
2013     pthread_exit(NULL);
2014 }
2015 
create_udpsocket_socket()2016 int create_udpsocket_socket()
2017 {
2018     int portno = CONNECT_PORT;
2019     int optval; /* flag value for setsockopt */
2020 
2021     RtkLogMsg("create udpsocket port: %d\n", portno);
2022 
2023     pthread_mutex_lock(&rtk_prof.btwifi_mutex);
2024 
2025     pthread_attr_t thread_attr_data;
2026     if (rtk_prof.coex_recv_thread_running)
2027     {
2028         HILOGE("udp_receive_thread already exit");
2029         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2030         return -1;
2031     }
2032 
2033     rtk_prof.coex_recv_thread_running = 1;
2034     rtk_prof.udpsocket = socket(AF_INET, SOCK_DGRAM, 0);
2035     RtkLogMsg("create socket %d", rtk_prof.udpsocket);
2036 
2037     if (rtk_prof.udpsocket < 0)
2038     {
2039         HILOGE("create udpsocket error...%s\n", strerror(errno));
2040         rtk_prof.coex_recv_thread_running = 0;
2041         RtkLogMsg("close socket %d", rtk_prof.udpsocket);
2042         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2043         return -1;
2044     }
2045 
2046     bzero((char *)&rtk_prof.server_addr, sizeof(rtk_prof.server_addr));
2047     rtk_prof.server_addr.sin_family = AF_INET;
2048     rtk_prof.server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2049     rtk_prof.server_addr.sin_port = htons(CONNECT_PORT);
2050 
2051     bzero((char *)&rtk_prof.client_addr, sizeof(rtk_prof.client_addr));
2052     rtk_prof.client_addr.sin_family = AF_INET;
2053     rtk_prof.client_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2054     rtk_prof.client_addr.sin_port = htons(CONNECT_PORT_WIFI);
2055 
2056     optval = 1;
2057     int ret = setsockopt(rtk_prof.udpsocket, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof(int));
2058     if (ret == -1)
2059     {
2060         HILOGE("%s, setsockopt error: %s", __func__, strerror(errno));
2061     }
2062 
2063     if (bind(rtk_prof.udpsocket, (struct sockaddr *)&rtk_prof.server_addr, sizeof(rtk_prof.server_addr)) < 0)
2064     {
2065         HILOGE("bind udpsocket error...%s\n", strerror(errno));
2066         rtk_prof.coex_recv_thread_running = 0;
2067         close(rtk_prof.udpsocket);
2068         RtkLogMsg("close socket %d", rtk_prof.udpsocket);
2069         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2070         return -1;
2071     }
2072 
2073     pthread_attr_init(&thread_attr_data);
2074     if (pthread_create(&rtk_prof.thread_data, &thread_attr_data, (void *)btwifi_coex_receive_thread, NULL) != 0)
2075     {
2076         HILOGE("pthread_create failed!");
2077         pthread_attr_destroy(&thread_attr_data);
2078         rtk_prof.coex_recv_thread_running = 0;
2079         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2080         return -1;
2081     }
2082     pthread_attr_destroy(&thread_attr_data);
2083     pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2084     return 0;
2085 }
2086 
stop_btwifi_coex_receive_thread()2087 int stop_btwifi_coex_receive_thread()
2088 {
2089     pthread_mutex_lock(&rtk_prof.btwifi_mutex);
2090     int result = 0;
2091 
2092     RtkLogMsg("notify wifi bt turn off");
2093     if (rtk_prof.wifi_on)
2094         coex_msg_send(bt_leave, sizeof(bt_leave));
2095 
2096     if (rtk_prof.coex_recv_thread_running)
2097     {
2098         RtkLogMsg("data thread is running, stop it");
2099 
2100         // add for pthread_cancel
2101         if ((result = pthread_kill(rtk_prof.thread_data, SIGUSR2)) != 0)
2102         {
2103             HILOGE("error cancelling data thread");
2104         }
2105         rtk_prof.coex_recv_thread_running = 0;
2106 
2107         if ((result = pthread_join(rtk_prof.thread_data, NULL)) < 0)
2108         {
2109             HILOGE("data thread pthread_join() failed result:%d", result);
2110         }
2111 
2112         if (rtk_prof.udpsocket > 0)
2113         {
2114             RtkLogMsg("close socket %d", rtk_prof.udpsocket);
2115             if ((result = close(rtk_prof.udpsocket)) != 0)
2116             {
2117                 HILOGE("close socket error!");
2118             }
2119         }
2120         else if (rtk_prof.btcoex_chr > 0)
2121         {
2122             RtkLogMsg("close char device  %d", rtk_prof.btcoex_chr);
2123             if ((result = close(rtk_prof.btcoex_chr)) != 0)
2124             {
2125                 HILOGE("close char device  error!");
2126             }
2127         }
2128     }
2129     pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2130     return 0;
2131 }
2132 
2133 #if 0
2134 int create_netlink_socket()
2135 {
2136     RtkLogMsg("in creat netlink socket");
2137     rtk_prof.nlsocket = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
2138 
2139     if (rtk_prof.nlsocket < 0)
2140     {
2141         HILOGE("create netlink socket error...%s\n", strerror(errno));
2142         close(rtk_prof.nlsocket);
2143         RtkLogMsg("close netlink socket %d", rtk_prof.nlsocket);
2144         return -1 ;
2145     }
2146     RtkLogMsg("create netlink socket %d", rtk_prof.nlsocket);
2147     memset(&rtk_prof.src_addr, 0, sizeof(rtk_prof.src_addr));
2148     rtk_prof.src_addr.nl_family = AF_NETLINK;
2149     rtk_prof.src_addr.nl_pid = getpid(); /* self pid */
2150     rtk_prof.src_addr.nl_groups    = 0 ;    /* not in mcast groups */
2151     int ret = bind(rtk_prof.nlsocket, (struct sockaddr *)&rtk_prof.src_addr, sizeof(rtk_prof.src_addr));
2152     if(ret < 0)
2153     {
2154         HILOGE("bind netlink socket error...%s\n", strerror(errno));
2155         close(rtk_prof.nlsocket);
2156         RtkLogMsg("close netlink socket %d", rtk_prof.nlsocket);
2157         return -1 ;
2158     }
2159 
2160     return 0;
2161 }
2162 #endif
2163 
open_btcoex_chrdev()2164 int open_btcoex_chrdev()
2165 {
2166     RtkLogMsg("open_btcoex_chrdev\n");
2167 
2168     pthread_mutex_lock(&rtk_prof.btwifi_mutex);
2169 
2170     pthread_attr_t thread_attr_data;
2171     if (rtk_prof.coex_recv_thread_running)
2172     {
2173         HILOGE("udp_receive_thread already exit");
2174         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2175         return -1;
2176     }
2177 
2178     rtk_prof.coex_recv_thread_running = 1;
2179     if ((rtk_prof.btcoex_chr = open("/dev/rtk_btcoex", O_RDWR)) < 0)
2180     {
2181         HILOGE("open rtk_btcoex error...%s\n", strerror(errno));
2182         rtk_prof.coex_recv_thread_running = 0;
2183         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2184         return -1;
2185     }
2186 
2187     pthread_attr_init(&thread_attr_data);
2188     if (pthread_create(&rtk_prof.thread_data, &thread_attr_data, (void *)btwifi_coex_receive_thread, NULL) != 0)
2189     {
2190         HILOGE("create coexchr_receive_thread failed!");
2191         pthread_attr_destroy(&thread_attr_data);
2192         rtk_prof.coex_recv_thread_running = 0;
2193         pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2194         return -1;
2195     }
2196     pthread_attr_destroy(&thread_attr_data);
2197     pthread_mutex_unlock(&rtk_prof.btwifi_mutex);
2198     return 0;
2199 }
2200 
rtk_parse_init(void)2201 void rtk_parse_init(void)
2202 {
2203     HILOGI("RTKBT_RELEASE_NAME: %s", RTKBT_RELEASE_NAME);
2204     RtkLogMsg("rtk_profile_init, version: %s", RTK_COEX_VERSION);
2205 
2206     memset(&rtk_prof, 0, sizeof(rtk_prof));
2207     pthread_mutex_init(&rtk_prof.profile_mutex, NULL);
2208     pthread_mutex_init(&rtk_prof.coex_mutex, NULL);
2209     pthread_mutex_init(&rtk_prof.btwifi_mutex, NULL);
2210     alloc_a2dp_packet_count_timer();
2211     alloc_pan_packet_count_timer();
2212     alloc_hogp_packet_count_timer();
2213     alloc_polling_timer();
2214 
2215     init_profile_hash(&rtk_prof);
2216     init_connection_hash(&rtk_prof);
2217     init_coex_hash(&rtk_prof);
2218 
2219     if (create_udpsocket_socket() < 0)
2220     {
2221         HILOGE("UDP socket fail, try to use rtk_btcoex chrdev");
2222         open_btcoex_chrdev();
2223     }
2224 }
2225 
rtk_parse_cleanup()2226 void rtk_parse_cleanup()
2227 {
2228     RtkLogMsg("rtk_profile_cleanup");
2229     free_a2dp_packet_count_timer();
2230     free_pan_packet_count_timer();
2231     free_hogp_packet_count_timer();
2232     free_polling_timer();
2233 
2234     flush_connection_hash(&rtk_prof);
2235     flush_profile_hash(&rtk_prof);
2236     pthread_mutex_destroy(&rtk_prof.profile_mutex);
2237     flush_coex_hash(&rtk_prof);
2238     pthread_mutex_destroy(&rtk_prof.coex_mutex);
2239 
2240     stop_btwifi_coex_receive_thread();
2241     pthread_mutex_destroy(&rtk_prof.btwifi_mutex);
2242 
2243     memset(&rtk_prof, 0, sizeof(rtk_prof));
2244 }
2245 
rtk_handle_vender_mailbox_cmp_evt(uint8_t * p,uint8_t len)2246 static void rtk_handle_vender_mailbox_cmp_evt(uint8_t *p, uint8_t len)
2247 {
2248     uint8_t status = *p++;
2249     if (len <= 4)
2250     {
2251         RtkLogMsg("receive mailbox cmd from fw, total length <= 4");
2252         return;
2253     }
2254     uint8_t subcmd = *p++;
2255     RtkLogMsg("receive mailbox cmd from fw, subcmd is 0x%x, status is 0x%x", subcmd, status);
2256     switch (subcmd)
2257     {
2258     case HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO:
2259         if (status == 0) // success
2260         {
2261             if ((len - 5) != 8)
2262                 RtkLogMsg("rtk_handle_vender_mailbox_cmp_evt:HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO len=%d", len);
2263             rtk_notify_info_to_wifi(POLLING_RESPONSE, (len - 5), (uint8_t *)p);
2264         }
2265         break;
2266 
2267     case HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD:
2268         rtk_notify_btcoex_to_wifi(WIFI_BW_CHNL_NOTIFY, status);
2269         break;
2270 
2271     case HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD:
2272         rtk_notify_btcoex_to_wifi(BT_POWER_DECREASE_CONTROL, status);
2273         break;
2274 
2275     case HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD:
2276         rtk_notify_btcoex_to_wifi(IGNORE_WLAN_ACTIVE_CONTROL, status);
2277         break;
2278 
2279     case HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE:
2280         rtk_notify_btcoex_to_wifi(BT_PSD_MODE_CONTROL, status);
2281         break;
2282 
2283     case HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT:
2284         rtk_notify_btcoex_to_wifi(LNA_CONSTRAIN_CONTROL, status);
2285         break;
2286 
2287     case HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE:
2288         break;
2289 
2290     case HCI_VENDOR_SUB_CMD_BT_SET_TXRETRY_REPORT_PARAM:
2291         break;
2292 
2293     case HCI_VENDOR_SUB_CMD_BT_SET_PTATABLE:
2294         break;
2295 
2296     case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L:
2297     {
2298         if (status == 0) // success
2299         {
2300             memcpy(rtk_prof.afh_map, p + 4, 4); // cmd_idx, length, piconet_id, mode
2301             uint8_t temp_cmd[4];
2302             temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M;
2303             temp_cmd[1] = 2;
2304             temp_cmd[2] = rtk_prof.piconet_id;
2305             temp_cmd[3] = rtk_prof.mode;
2306             rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4, temp_cmd, NULL);
2307         }
2308         else // fail
2309         {
2310             memset(rtk_prof.afh_map, 0, 10);
2311             rtk_notify_afhmap_to_wifi();
2312         }
2313         break;
2314     }
2315     case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M:
2316     {
2317         if (status == 0) // success
2318         {
2319             memcpy(rtk_prof.afh_map + 4, p + 4, 4);
2320             uint8_t temp_cmd[4];
2321             temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H;
2322             temp_cmd[1] = 2;
2323             temp_cmd[2] = rtk_prof.piconet_id;
2324             temp_cmd[3] = rtk_prof.mode;
2325             rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4, temp_cmd, NULL);
2326         }
2327         else // fail
2328         {
2329             memset(rtk_prof.afh_map, 0, 10);
2330             rtk_notify_afhmap_to_wifi();
2331         }
2332         break;
2333     }
2334 
2335     case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H:
2336     {
2337         if (status == 0)
2338             memcpy(rtk_prof.afh_map + 8, p + 4, 2);
2339         else
2340             memset(rtk_prof.afh_map, 0, 10);
2341 
2342         rtk_notify_afhmap_to_wifi();
2343         break;
2344     }
2345 
2346     case HCI_VENDOR_SUB_CMD_RD_REG_REQ:
2347     {
2348         if (status == 0)
2349             rtk_notify_regester_to_wifi(p + 3); // cmd_idx,length,regist type
2350         break;
2351     }
2352 
2353     case HCI_VENDOR_SUB_CMD_WR_REG_REQ:
2354         rtk_notify_btcoex_to_wifi(BT_REGISTER_ACCESS, status);
2355         break;
2356 
2357     default:
2358         break;
2359     }
2360 }
2361 
rtk_handle_cmd_complete_evt(uint8_t * p,uint8_t len)2362 static void rtk_handle_cmd_complete_evt(uint8_t *p, uint8_t len)
2363 {
2364     uint16_t opcode;
2365     uint8_t status;
2366     p++;
2367     STREAM_TO_UINT16(opcode, p);
2368     switch (opcode)
2369     {
2370     case HCI_PERIODIC_INQUIRY_MODE:
2371     {
2372         status = *p++;
2373         if (status && rtk_prof.isinquirying)
2374         {
2375             rtk_prof.isinquirying = 0;
2376             RtkLogMsg("HCI_PERIODIC_INQUIRY_MODE start error, notify wifi inquiry stop");
2377             rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0, NULL);
2378         }
2379         break;
2380     }
2381 
2382     case HCI_READ_LOCAL_VERSION_INFO:
2383     {
2384         status = *p++;
2385         if (!status)
2386         {
2387             p++;
2388             STREAM_TO_UINT16(rtk_prof.hci_reversion, p);
2389             p += 3;
2390             STREAM_TO_UINT16(rtk_prof.lmp_subversion, p);
2391         }
2392         RtkLogMsg("rtk_prof.hci_reversion = %x", rtk_prof.hci_reversion);
2393         RtkLogMsg("rtk_prof.lmp_subversion = %x", rtk_prof.lmp_subversion);
2394         break;
2395     }
2396 
2397     case HCI_RESET:
2398     {
2399         RtkLogMsg("bt start ok");
2400         coex_msg_send(invite_req, sizeof(invite_req));
2401 #if 0
2402             if(create_netlink_socket() == 0)
2403             {
2404                 RtkLogMsg("wifi is already on when bt turn on");
2405                 rtk_prof.wifi_on = 1;
2406                 netlink_send(rtk_prof.nlsocket, invite_req);
2407             }
2408             else
2409                 RtkLogMsg("wifi is off when bt turn on, wait for wifi turning on...");
2410 #endif
2411         break;
2412     }
2413 
2414     case 0xfc1b:
2415         RtkLogMsg("received cmd complete event for fc1b");
2416         poweroff_allowed = 1;
2417         break;
2418 
2419     case HCI_VENDOR_MAILBOX_CMD:
2420         rtk_handle_vender_mailbox_cmp_evt(p, len);
2421         break;
2422 
2423     case HCI_VENDOR_ADD_BITPOOL_FW:
2424         status = *p++;
2425         RtkLogMsg("received cmd complete event for HCI_VENDOR_ADD_BITPOOL_FW status:%d", status);
2426 
2427     default:
2428         break;
2429     }
2430 }
2431 
rtk_handle_connection_complete_evt(uint8_t * p)2432 static void rtk_handle_connection_complete_evt(uint8_t *p)
2433 {
2434     uint8_t status = 0;
2435     uint16_t handle = 0;
2436     status = *p++;
2437     STREAM_TO_UINT16(handle, p);
2438     p += 6;
2439     uint8_t link_type = *p++;
2440 
2441     if (status == 0)
2442     {
2443         if (rtk_prof.ispaging)
2444         {
2445             rtk_prof.ispaging = 0;
2446             RtkLogMsg("notify wifi page success end");
2447             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_SUCCESS_END, 0, NULL);
2448         }
2449 
2450         tRTK_CONN_PROF *hci_conn = find_connection_by_handle(&rtk_prof, handle);
2451         if (hci_conn == NULL)
2452         {
2453             hci_conn = allocate_connection_by_handle(handle);
2454             if (hci_conn)
2455             {
2456                 add_connection_to_hash(&rtk_prof, hci_conn);
2457                 hci_conn->profile_bitmap = 0;
2458                 memset(hci_conn->profile_refcount, 0, 8);
2459                 if ((0 == link_type) || (2 == link_type)) // sco or esco
2460                 {
2461                     hci_conn->type = 1;
2462                     update_profile_connection(hci_conn, profile_sco, TRUE);
2463                 }
2464                 else
2465                     hci_conn->type = 0;
2466             }
2467             else
2468             {
2469                 HILOGE("HciConnAllocate fail");
2470             }
2471         }
2472         else
2473         {
2474             RtkLogMsg("HCI Connection handle(0x%x) has already exist!", handle);
2475             hci_conn->profile_bitmap = 0;
2476             memset(hci_conn->profile_refcount, 0, 8);
2477             if ((0 == link_type) || (2 == link_type)) // sco or esco
2478             {
2479                 hci_conn->type = 1;
2480                 update_profile_connection(hci_conn, profile_sco, TRUE);
2481             }
2482             else
2483                 hci_conn->type = 0;
2484         }
2485     }
2486     else if (rtk_prof.ispaging)
2487     {
2488         rtk_prof.ispaging = 0;
2489         RtkLogMsg("notify wifi page unsuccess end");
2490         rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_UNSUCCESS_END, 0, NULL);
2491     }
2492 }
2493 
rtk_handle_disconnect_complete_evt(uint8_t * p)2494 static void rtk_handle_disconnect_complete_evt(uint8_t *p)
2495 {
2496     if (rtk_prof.ispairing) // for slave: connection will be disconnected if authentication fail
2497     {
2498         rtk_prof.ispairing = 0;
2499         RtkLogMsg("notify wifi pair end");
2500         rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
2501     }
2502 
2503     uint8_t status = 0;
2504     uint16_t handle = 0;
2505     uint8_t reason = 0;
2506     status = *p++;
2507     STREAM_TO_UINT16(handle, p);
2508     reason = *p;
2509 
2510     if (status == 0)
2511     {
2512         tRTK_CONN_PROF *hci_conn = find_connection_by_handle(&rtk_prof, handle);
2513         if (hci_conn)
2514         {
2515             switch (hci_conn->type)
2516             {
2517             case 0:
2518             {
2519                 RT_LIST_ENTRY *iter = NULL, *temp = NULL;
2520                 tRTK_PROF_INFO *prof_info = NULL;
2521 
2522                 pthread_mutex_lock(&rtk_prof.profile_mutex);
2523                 LIST_FOR_EACH_SAFELY(iter, temp, &rtk_prof.profile_list)
2524                 {
2525                     prof_info = LIST_ENTRY(iter, tRTK_PROF_INFO, list);
2526                     if ((handle == prof_info->handle) && prof_info->scid && prof_info->dcid)
2527                     {
2528                         RtkLogMsg("find info when hci disconnect, handle:%x, psm:%x, dcid:%x, scid:%x", prof_info->handle, prof_info->psm, prof_info->dcid, prof_info->scid);
2529                         // If both scid and dcid > 0, L2cap connection is exist.
2530                         update_profile_connection(hci_conn, prof_info->profile_index, FALSE);
2531                         delete_profile_from_hash(prof_info);
2532                     }
2533                 }
2534                 pthread_mutex_unlock(&rtk_prof.profile_mutex);
2535                 break;
2536             }
2537 
2538             case 1:
2539                 update_profile_connection(hci_conn, profile_sco, FALSE);
2540                 break;
2541 
2542             case 2:
2543             {
2544                 if (hci_conn->profile_bitmap & BIT(profile_hogp))
2545                     update_profile_connection(hci_conn, profile_hogp, FALSE);
2546 
2547                 if (hci_conn->profile_bitmap & BIT(profile_voice))
2548                     update_profile_connection(hci_conn, profile_voice, FALSE);
2549 
2550                 update_profile_connection(hci_conn, profile_hid, FALSE);
2551                 break;
2552             }
2553 
2554             default:
2555                 break;
2556             }
2557             delete_connection_from_hash(hci_conn);
2558         }
2559         else
2560         {
2561             HILOGE("HCI Connection handle(0x%x) not found", handle);
2562         }
2563     }
2564 }
2565 
rtk_handle_le_connection_complete_evt(uint8_t * p,bool enhanced)2566 static void rtk_handle_le_connection_complete_evt(uint8_t *p, bool enhanced)
2567 {
2568     uint16_t handle, interval;
2569     uint8_t status;
2570     tRTK_CONN_PROF *hci_conn = NULL;
2571 
2572     status = *p++;
2573     STREAM_TO_UINT16(handle, p);
2574     p += 8; // role, address type, address
2575     if (enhanced)
2576     {
2577         p += 12;
2578     }
2579     STREAM_TO_UINT16(interval, p);
2580 
2581     if (status == 0)
2582     {
2583         if (rtk_prof.ispaging)
2584         {
2585             rtk_prof.ispaging = 0;
2586             RtkLogMsg("notify wifi page success end");
2587             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_SUCCESS_END, 0, NULL);
2588         }
2589 
2590         hci_conn = find_connection_by_handle(&rtk_prof, handle);
2591         if (hci_conn == NULL)
2592         {
2593             hci_conn = allocate_connection_by_handle(handle);
2594             if (hci_conn)
2595             {
2596                 add_connection_to_hash(&rtk_prof, hci_conn);
2597                 hci_conn->profile_bitmap = 0;
2598                 memset(hci_conn->profile_refcount, 0, 8);
2599                 hci_conn->type = 2;
2600                 update_profile_connection(hci_conn, profile_hid, TRUE); // for coex, le is the same as hid
2601                 update_hid_active_state(handle, interval);
2602             }
2603             else
2604             {
2605                 HILOGE("hci connection allocate fail");
2606             }
2607         }
2608         else
2609         {
2610             RtkLogMsg("hci connection handle(0x%x) has already exist!", handle);
2611             hci_conn->profile_bitmap = 0;
2612             memset(hci_conn->profile_refcount, 0, 8);
2613             hci_conn->type = 2;
2614             update_profile_connection(hci_conn, profile_hid, TRUE);
2615             update_hid_active_state(handle, interval);
2616         }
2617     }
2618     else if (rtk_prof.ispaging)
2619     {
2620         rtk_prof.ispaging = 0;
2621         RtkLogMsg("notify wifi page unsuccess end");
2622         rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_UNSUCCESS_END, 0, NULL);
2623     }
2624 }
2625 
rtk_handle_le_connection_update_complete_evt(uint8_t * p)2626 static void rtk_handle_le_connection_update_complete_evt(uint8_t *p)
2627 {
2628     uint16_t handle, interval;
2629     uint8_t status;
2630 
2631     status = *p++;
2632     STREAM_TO_UINT16(handle, p);
2633     STREAM_TO_UINT16(interval, p);
2634     update_hid_active_state(handle, interval);
2635 }
2636 
rtk_handle_le_meta_evt(uint8_t * p)2637 static void rtk_handle_le_meta_evt(uint8_t *p)
2638 {
2639     uint8_t sub_event = *p++;
2640     switch (sub_event)
2641     {
2642     case HCI_BLE_CONN_COMPLETE_EVT:
2643         rtk_handle_le_connection_complete_evt(p, false);
2644         break;
2645     case HCI_BLE_ENHANCED_CONN_COMPLETE_EVT:
2646         rtk_handle_le_connection_complete_evt(p, true);
2647         break;
2648     case HCI_BLE_LL_CONN_PARAM_UPD_EVT:
2649         rtk_handle_le_connection_update_complete_evt(p);
2650         break;
2651 
2652     default:
2653         break;
2654     }
2655 }
2656 
coex_msg_send(char * tx_msg,int msg_size)2657 static int coex_msg_send(char *tx_msg, int msg_size)
2658 {
2659     int ret = -1;
2660     if (rtk_prof.udpsocket > 0)
2661     {
2662         ret = udpsocket_send(tx_msg, msg_size);
2663     }
2664     else if (rtk_prof.btcoex_chr > 0)
2665     {
2666         ret = btcoex_chr_send(tx_msg, msg_size);
2667     }
2668     return ret;
2669 }
2670 
coex_msg_recv(uint8_t * recv_msg,uint8_t * msg_size)2671 static int coex_msg_recv(uint8_t *recv_msg, uint8_t *msg_size)
2672 {
2673     int ret = -1;
2674     if (rtk_prof.udpsocket > 0)
2675     {
2676         ret = udpsocket_recv(recv_msg, msg_size);
2677     }
2678     else if (rtk_prof.btcoex_chr > 0)
2679     {
2680         ret = btcoex_chr_recv(recv_msg, msg_size);
2681     }
2682     return ret;
2683 }
rtk_parse_internal_event_intercept(uint8_t * p_msg)2684 void rtk_parse_internal_event_intercept(uint8_t *p_msg)
2685 {
2686     uint8_t *p = p_msg;
2687     uint8_t event_code = *p++;
2688     uint8_t len = *p++;
2689     uint16_t opcode, mode_change_handle, mode_interval, subcode;
2690     uint8_t status, num_hci_cmd_pkts;
2691 
2692     switch (event_code)
2693     {
2694     case HCI_INQUIRY_COMP_EVT:
2695     {
2696         if (rtk_prof.isinquirying)
2697         {
2698             rtk_prof.isinquirying = 0;
2699             RtkLogMsg("notify wifi inquiry end");
2700             rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0, NULL);
2701         }
2702         break;
2703     }
2704 
2705     case HCI_PIN_CODE_REQUEST_EVT:
2706     {
2707         if (!rtk_prof.ispairing)
2708         {
2709             rtk_prof.ispairing = 1;
2710             RtkLogMsg("notify wifi pair start");
2711             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_START, 0, NULL);
2712         }
2713         break;
2714     }
2715 
2716     case HCI_IO_CAPABILITY_REQUEST_EVT:
2717     {
2718         if (!rtk_prof.ispairing)
2719         {
2720             rtk_prof.ispairing = 1;
2721             RtkLogMsg("notify wifi pair start");
2722             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_START, 0, NULL);
2723         }
2724         break;
2725     }
2726 
2727     case HCI_AUTHENTICATION_COMP_EVT:
2728     {
2729         if (rtk_prof.ispairing)
2730         {
2731             rtk_prof.ispairing = 0;
2732             RtkLogMsg("notify wifi pair end");
2733             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
2734         }
2735         break;
2736     }
2737 
2738     case HCI_LINK_KEY_NOTIFICATION_EVT:
2739     {
2740         if (rtk_prof.ispairing)
2741         {
2742             rtk_prof.ispairing = 0;
2743             RtkLogMsg("notify wifi pair end");
2744             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
2745         }
2746         break;
2747     }
2748 
2749     case HCI_MODE_CHANGE_EVT:
2750     {
2751         status = *p++;
2752         STREAM_TO_UINT16(mode_change_handle, p);
2753         p++;
2754         STREAM_TO_UINT16(mode_interval, p);
2755         update_hid_active_state(mode_change_handle, mode_interval);
2756         break;
2757     }
2758 
2759     case HCI_COMMAND_COMPLETE_EVT:
2760         rtk_handle_cmd_complete_evt(p, len);
2761         break;
2762 
2763     case HCI_COMMAND_STATUS_EVT:
2764     {
2765         status = *p++;
2766         num_hci_cmd_pkts = *p++;
2767         STREAM_TO_UINT16(opcode, p);
2768         if ((opcode == HCI_INQUIRY) && (status))
2769         {
2770             if (rtk_prof.isinquirying)
2771             {
2772                 rtk_prof.isinquirying = 0;
2773                 RtkLogMsg("inquiry start error, notify wifi inquiry stop");
2774                 rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0, NULL);
2775             }
2776         }
2777 
2778         if (opcode == HCI_CREATE_CONNECTION)
2779         {
2780             if (!status && !rtk_prof.ispaging)
2781             {
2782                 rtk_prof.ispaging = 1;
2783                 RtkLogMsg("notify wifi start page");
2784                 rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_START, 0, NULL);
2785             }
2786         }
2787         break;
2788     }
2789 
2790     case HCI_CONNECTION_COMP_EVT:
2791     case HCI_ESCO_CONNECTION_COMP_EVT:
2792         rtk_handle_connection_complete_evt(p);
2793         break;
2794 
2795     case HCI_DISCONNECTION_COMP_EVT:
2796         rtk_handle_disconnect_complete_evt(p);
2797         break;
2798 
2799     case HCI_VENDOR_SPECIFIC_EVT:
2800     {
2801         STREAM_TO_UINT16(subcode, p);
2802         if (subcode == HCI_VENDOR_PTA_AUTO_REPORT_EVENT)
2803         {
2804             RtkLogMsg("notify wifi driver with autoreport data");
2805             if ((len - 2) != 8)
2806                 RtkLogMsg("rtk_parse_internal_event_intercept:HCI_VENDOR_SPECIFIC_EVT:HCI_VENDOR_PTA_AUTO_REPORT_EVENT len=%d", len);
2807             rtk_notify_info_to_wifi(AUTO_REPORT, (len - 2), (uint8_t *)p);
2808         }
2809         break;
2810     }
2811 
2812     case HCI_BLE_EVENT:
2813         rtk_handle_le_meta_evt(p);
2814         break;
2815 
2816     default:
2817         break;
2818     }
2819 }
2820 
rtk_parse_command(uint8_t * pp)2821 void rtk_parse_command(uint8_t *pp)
2822 {
2823     uint8_t *p = pp;
2824     uint16_t cmd;
2825     STREAM_TO_UINT16(cmd, p);
2826 
2827     switch (cmd)
2828     {
2829     case HCI_INQUIRY:
2830     case HCI_PERIODIC_INQUIRY_MODE:
2831     {
2832         if (!rtk_prof.isinquirying)
2833         {
2834             rtk_prof.isinquirying = 1;
2835             RtkLogMsg("notify wifi inquiry start");
2836             rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_START, 0, NULL);
2837         }
2838         break;
2839     }
2840 
2841     case HCI_INQUIRY_CANCEL:
2842     case HCI_EXIT_PERIODIC_INQUIRY_MODE:
2843     {
2844         if (rtk_prof.isinquirying)
2845         {
2846             rtk_prof.isinquirying = 0;
2847             RtkLogMsg("notify wifi inquiry stop");
2848             rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0, NULL);
2849         }
2850         break;
2851     }
2852 
2853     case HCI_ACCEPT_CONNECTION_REQUEST:
2854     {
2855         if (!rtk_prof.ispaging)
2856         {
2857             rtk_prof.ispaging = 1;
2858             RtkLogMsg("notify wifi page start");
2859             rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_START, 0, NULL);
2860         }
2861         break;
2862     }
2863 
2864     default:
2865         break;
2866     }
2867 }
2868 
rtk_parse_l2cap_data(uint8_t * pp,uint8_t direction)2869 void rtk_parse_l2cap_data(uint8_t *pp, uint8_t direction)
2870 {
2871     uint16_t handle, total_len, pdu_len, channel_ID, command_len, psm, scid, dcid, result, status;
2872     uint8_t flag, code, identifier;
2873     STREAM_TO_UINT16(handle, pp);
2874     flag = (handle >> HCI_DATA_EVENT_OFFSET) & HCI_DATA_EVENT_MASK;
2875     handle = handle & 0x0FFF;
2876     STREAM_TO_UINT16(total_len, pp);
2877     STREAM_TO_UINT16(pdu_len, pp);
2878     STREAM_TO_UINT16(channel_ID, pp);
2879 
2880     if (flag != RTK_START_PACKET_BOUNDARY)
2881         return;
2882 
2883     if (channel_ID == 0x0001)
2884     {
2885         code = (uint8_t)(*pp++);
2886         switch (code)
2887         {
2888         case L2CAP_CONNECTION_REQ:
2889             identifier = (uint8_t)(*pp++);
2890             STREAM_TO_UINT16(command_len, pp);
2891             STREAM_TO_UINT16(psm, pp);
2892             STREAM_TO_UINT16(scid, pp);
2893             RtkLogMsg("L2CAP_CONNECTION_REQ, handle=%x, PSM=%x, scid=%x", handle, psm, scid);
2894             handle_l2cap_con_req(handle, psm, scid, direction);
2895             break;
2896 
2897         case L2CAP_CONNECTION_RSP:
2898             identifier = (uint8_t)(*pp++);
2899             STREAM_TO_UINT16(command_len, pp);
2900             STREAM_TO_UINT16(dcid, pp);
2901             STREAM_TO_UINT16(scid, pp);
2902             STREAM_TO_UINT16(result, pp);
2903             STREAM_TO_UINT16(status, pp);
2904             RtkLogMsg("L2CAP_CONNECTION_RESP, handle=%x, dcid=%x, scid=%x, result=%x", handle, dcid, scid, result);
2905             // if(result == 0)
2906             handle_l2cap_con_rsp(handle, dcid, scid, direction, result);
2907             break;
2908 
2909         case L2CAP_DISCONNECTION_REQ:
2910             identifier = (uint8_t)(*pp++);
2911             STREAM_TO_UINT16(command_len, pp);
2912             STREAM_TO_UINT16(dcid, pp);
2913             STREAM_TO_UINT16(scid, pp);
2914             RtkLogMsg("L2CAP_DISCONNECTION_REQ, handle=%x, dcid=%x, scid=%x", handle, dcid, scid);
2915             handle_l2cap_discon_req(handle, dcid, scid, direction);
2916             break;
2917 
2918         case L2CAP_DISCONNECTION_RSP:
2919             break;
2920 
2921         default:
2922             break;
2923         }
2924     }
2925     else
2926     {
2927         if ((flag != 0x01) && (is_profile_connected(profile_a2dp) || is_profile_connected(profile_pan))) // Do not count the continuous packets
2928             packets_count(handle, channel_ID, pdu_len, direction, pp);
2929     }
2930 }
2931 
rtk_add_le_profile(BD_ADDR bdaddr,uint16_t handle,uint8_t profile_map)2932 void rtk_add_le_profile(BD_ADDR bdaddr, uint16_t handle, uint8_t profile_map)
2933 {
2934     RTK_UNUSED(bdaddr);
2935     RtkLogMsg("rtk_add_le_profile, handle is %x, profile_map is %x", handle, profile_map);
2936 
2937     tRTK_CONN_PROF *hci_conn = find_connection_by_handle(&rtk_prof, handle);
2938     if (hci_conn)
2939     {
2940         if ((profile_map & 0x01) || (profile_map & 0x02)) // bit0: mouse, bit1:keyboard
2941             update_profile_connection(hci_conn, profile_hogp, TRUE);
2942 
2943         if (profile_map & 0x04)
2944             update_profile_connection(hci_conn, profile_voice, TRUE);
2945     }
2946     else
2947     {
2948         HILOGE("rtk_add_le_profile, connection handle(0x%x) not exist!", handle);
2949     }
2950 }
2951 
rtk_delete_le_profile(BD_ADDR bdaddr,uint16_t handle,uint8_t profile_map)2952 void rtk_delete_le_profile(BD_ADDR bdaddr, uint16_t handle, uint8_t profile_map)
2953 {
2954     RTK_UNUSED(bdaddr);
2955     RtkLogMsg("rtk_delete_le_profile, handle is %x, profile_map is %x", handle, profile_map);
2956 
2957     pthread_mutex_lock(&rtk_prof.profile_mutex);
2958     tRTK_CONN_PROF *hci_conn = find_connection_by_handle(&rtk_prof, handle);
2959     if (hci_conn == NULL)
2960     {
2961         HILOGE("rtk_delete_le_profile, hci_conn not exist with handle %x", handle);
2962     }
2963     else
2964     {
2965         if ((profile_map & 0x01) || (profile_map & 0x02)) // bit0: mouse, bit1:keyboard
2966             update_profile_connection(hci_conn, profile_hogp, FALSE);
2967 
2968         if (profile_map & 0x04)
2969             update_profile_connection(hci_conn, profile_voice, FALSE);
2970     }
2971     pthread_mutex_unlock(&rtk_prof.profile_mutex);
2972 }
2973 
rtk_add_le_data_count(uint8_t data_type)2974 void rtk_add_le_data_count(uint8_t data_type)
2975 {
2976     RtkLogMsg("rtk_add_le_data_count, data_type is %x", data_type);
2977 
2978     if ((data_type == 1) || (data_type == 2)) // 1:keyboard, 2:mouse
2979     {
2980         rtk_prof.hogp_packet_count++;
2981         if (!is_profile_busy(profile_hogp))
2982         {
2983             RtkLogMsg("hogp idle->busy");
2984             update_profile_state(profile_hogp, TRUE);
2985         }
2986     }
2987 
2988     if (data_type == 3) // voice
2989     {
2990         rtk_prof.voice_packet_count++;
2991         if (!is_profile_busy(profile_voice))
2992         {
2993             RtkLogMsg("voice idle->busy");
2994             update_profile_state(profile_voice, TRUE);
2995         }
2996     }
2997 }
2998 
rtk_set_bt_on(uint8_t bt_on)2999 void rtk_set_bt_on(uint8_t bt_on)
3000 {
3001     RtkLogMsg("bt stack is init");
3002     rtk_prof.bt_on = bt_on;
3003     uint8_t ttmp[1] = {1};
3004     rtk_vendor_cmd_to_fw(0xfc1b, 1, ttmp, NULL);
3005 }
3006 
3007 static rtk_parse_manager_t parse_interface = {
3008     rtk_parse_internal_event_intercept,
3009     rtk_parse_l2cap_data,
3010     rtk_parse_init,
3011     rtk_parse_cleanup,
3012     rtk_parse_command,
3013     rtk_add_le_profile,
3014     rtk_delete_le_profile,
3015     rtk_add_le_data_count,
3016     rtk_set_bt_on,
3017 };
3018 
rtk_parse_manager_get_interface()3019 rtk_parse_manager_t *rtk_parse_manager_get_interface()
3020 {
3021     return &parse_interface;
3022 }
3023 
hw_process_event(HC_BT_HDR * p_buf)3024 void hw_process_event(HC_BT_HDR *p_buf)
3025 {
3026     uint16_t opcode;
3027     uint8_t *p = (uint8_t *)(p_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
3028     STREAM_TO_UINT16(opcode, p);
3029 
3030     HILOGD("%s, opcode:0x%04x", __FUNCTION__, opcode);
3031     switch (opcode)
3032     {
3033     case HCI_VSC_UPDATE_BAUDRATE:
3034     case HCI_VSC_READ_CHIP_TYPE:
3035     case HCI_VSC_H5_INIT:
3036     case HCI_VSC_DOWNLOAD_FW_PATCH:
3037     case HCI_READ_LMP_VERSION:
3038     case HCI_VSC_READ_ROM_VERSION:
3039     case HCI_VENDOR_RESET:
3040         hw_usb_config_cback(p_buf);
3041         break;
3042 
3043 #if (HW_END_WITH_HCI_RESET == TRUE)
3044     case HCI_RESET:
3045         hw_epilog_cback(p_buf);
3046         break;
3047 #endif
3048 
3049     case 0xfc1b:
3050     case HCI_CMD_VNDR_HEARTBEAT:
3051     case HCI_VENDOR_SET_PROFILE_REPORT_COMMAND:
3052     case HCI_VENDOR_ADD_BITPOOL_FW:
3053     case HCI_VENDOR_MAILBOX_CMD:
3054         rtk_cmd_complete_cback(p_buf);
3055         break;
3056     }
3057 
3058     HILOGD("%s, Complete", __FUNCTION__);
3059 }