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