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