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 }