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 * Filename: rtk_btservice.c
22 *
23 * Description: start unix socketc
24 *
25 ******************************************************************************/
26
27 #define LOG_TAG "bt_service"
28 #define RTKBT_RELEASE_NAME "20190717_BT_ANDROID_9.0"
29
30 #include <utils/Log.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <signal.h>
34 #include <termios.h>
35 #include <sys/syscall.h>
36 #include <time.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <dirent.h>
40 #include <ctype.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <sys/eventfd.h>
44 #include <semaphore.h>
45 #include <endian.h>
46 #include <byteswap.h>
47 #include <sys/un.h>
48 #include <stddef.h>
49 #include <sys/socket.h>
50 #include <sys/types.h>
51 #include "bt_hci_bdroid.h"
52 #include "bt_vendor_rtk.h"
53 #include "userial.h"
54 #include "userial_vendor.h"
55 #include "upio.h"
56 #include "rtk_parse.h"
57 #include "rtk_btservice.h"
58
59 #include "bt_vendor_lib.h"
60
61 // HCI VENDOR Command opcode
62 #define HCI_VSC_READ_REGISTER 0xFFFF
63
64 #define RTKBTSERVICE_SOCKETPATH "@/data/misc/bluedroid/rtkbt_service.sock"
65 #define MAX_CONNECTION_NUMBER 10
66
67 #define RTK_HCICMD 0x01
68 #define RTK_CLOSESOCRET 0x02
69 #define RTK_INNER 0x03
70 #define OTHER 0xff
71
72 #define Rtk_Service_Data_SIZE 259
73 #define Rtk_Service_Send_Data_SIZE 259
74
75 #define HCICMD_REPLY_TIMEOUT_VALUE 8000 // ms
76
77 typedef void (*tTIMER_HANDLE_CBACK)(union sigval sigval_value);
78
79 typedef struct Rtk_Btservice_Info {
80 int socketfd;
81 int sig_fd[2];
82 pthread_t cmdreadythd;
83 pthread_t epollthd;
84 int current_client_sock;
85 int epoll_fd;
86 int autopair_fd;
87 sem_t cmdqueue_sem;
88 sem_t cmdsend_sem;
89 timer_t timer_hcicmd_reply;
90 RT_LIST_HEAD cmdqueue_list;
91 pthread_mutex_t cmdqueue_mutex;
92 volatile uint8_t cmdqueue_thread_running;
93 volatile uint8_t epoll_thread_running;
94 void (*current_complete_cback)(HC_BT_HDR *);
95 } Rtk_Btservice_Info;
96
97 typedef struct Rtk_Queue_Data {
98 RT_LIST_ENTRY list;
99 int client_sock;
100 uint16_t opcode;
101 uint8_t parameter_len;
102 uint8_t *parameter;
103 void (*complete_cback)(void *);
104 } Rtkqueuedata;
105 typedef void (*tINT_CMD_CBACK)(void *p_mem);
106 static Rtk_Btservice_Info *rtk_btservice = NULL;
107 static void Rtk_Service_Send_Hwerror_Event(void);
OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)108 static timer_t OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)
109 {
110 struct sigevent sigev;
111 timer_t timerid;
112
113 (void)memset_s(&sigev, sizeof(struct sigevent), 0, sizeof(struct sigevent));
114 // Create the POSIX timer to generate signo
115 sigev.sigev_notify = SIGEV_THREAD;
116 sigev.sigev_notify_function = timer_callback;
117 sigev.sigev_value.sival_ptr = &timerid;
118
119 HILOGD("OsAllocateTimer bt_service sigev.sigev_notify_thread_id = syscall(__NR_gettid)!");
120 // Create the Timer using timer_create signal
121
122 if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0) {
123 return timerid;
124 } else {
125 HILOGE("timer_create error!");
126 return (timer_t)-1;
127 }
128 }
129
OsFreeTimer(timer_t timerid)130 static int OsFreeTimer(timer_t timerid)
131 {
132 int ret = 0;
133 ret = timer_delete(timerid);
134 if (ret != 0) {
135 HILOGE("timer_delete fail with errno(%d)", errno);
136 }
137
138 return ret;
139 }
140
OsStartTimer(timer_t timerid,int msec,int mode)141 static int OsStartTimer(timer_t timerid, int msec, int mode)
142 {
143 struct itimerspec itval;
144
145 #define TIMER_MEC_1000 1000
146 itval.it_value.tv_sec = msec / TIMER_MEC_1000;
147 itval.it_value.tv_nsec = (long)(msec % TIMER_MEC_1000) * (1000000L);
148
149 if (mode == 1) {
150 itval.it_interval.tv_sec = itval.it_value.tv_sec;
151 itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
152 } else {
153 itval.it_interval.tv_sec = 0;
154 itval.it_interval.tv_nsec = 0;
155 }
156
157 // Set the Timer when to expire through timer_settime
158
159 if (timer_settime(timerid, 0, &itval, NULL) != 0) {
160 HILOGE("time_settime error!");
161 return -1;
162 }
163
164 return 0;
165 }
166
OsStopTimer(timer_t timerid)167 static int OsStopTimer(timer_t timerid)
168 {
169 return OsStartTimer(timerid, 0, 0);
170 }
171
init_cmdqueue_hash(Rtk_Btservice_Info * rtk_info)172 static void init_cmdqueue_hash(Rtk_Btservice_Info *rtk_info)
173 {
174 RT_LIST_HEAD *head = &rtk_info->cmdqueue_list;
175 ListInitializeHeader(head);
176 }
177
delete_cmdqueue_from_hash(Rtkqueuedata * desc)178 static void delete_cmdqueue_from_hash(Rtkqueuedata *desc)
179 {
180 Rtkqueuedata *parameter = desc;
181 if (parameter) {
182 ListDeleteNode(¶meter->list);
183 free(parameter);
184 parameter = NULL;
185 }
186 }
187
flush_cmdqueue_hash(Rtk_Btservice_Info * rtk_info)188 static void flush_cmdqueue_hash(Rtk_Btservice_Info *rtk_info)
189 {
190 RT_LIST_HEAD *head = &rtk_info->cmdqueue_list;
191 RT_LIST_ENTRY *iter = NULL, *temp = NULL;
192 Rtkqueuedata *desc = NULL;
193
194 pthread_mutex_lock(&rtk_info->cmdqueue_mutex);
195 LIST_FOR_EACH_SAFELY(iter, temp, head)
196 {
197 desc = LIST_ENTRY(iter, Rtkqueuedata, list);
198 delete_cmdqueue_from_hash(desc);
199 }
200 pthread_mutex_unlock(&rtk_info->cmdqueue_mutex);
201 }
202
hcicmd_reply_timeout_handler(void)203 static void hcicmd_reply_timeout_handler(void) // (union sigval sigev_value)
204 {
205 Rtk_Service_Send_Hwerror_Event();
206 }
207
hcicmd_alloc_reply_timer(void)208 static int hcicmd_alloc_reply_timer(void)
209 {
210 // Create and set the timer when to expire
211 rtk_btservice->timer_hcicmd_reply = OsAllocateTimer(hcicmd_reply_timeout_handler);
212
213 return 0;
214 }
215
hcicmd_free_reply_timer(void)216 static int hcicmd_free_reply_timer(void)
217 {
218 return OsFreeTimer(rtk_btservice->timer_hcicmd_reply);
219 }
220
hcicmd_start_reply_timer(void)221 static int hcicmd_start_reply_timer(void)
222 {
223 return OsStartTimer(rtk_btservice->timer_hcicmd_reply, HCICMD_REPLY_TIMEOUT_VALUE, 1);
224 }
225
hcicmd_stop_reply_timer(void)226 static int hcicmd_stop_reply_timer(void)
227 {
228 return OsStopTimer(rtk_btservice->timer_hcicmd_reply);
229 }
230
Rtk_Client_Cmd_Cback(HC_BT_HDR * p_mem)231 static void Rtk_Client_Cmd_Cback(HC_BT_HDR *p_mem)
232 {
233 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
234 unsigned char *sendbuf = NULL;
235 int len;
236
237 #define LENTH_8 8
238 if (p_evt_buf != NULL) {
239 len = LENTH_8 + p_evt_buf->len;
240 sendbuf = p_mem;
241 if (rtk_btservice->current_client_sock != -1) {
242 write(rtk_btservice->current_client_sock, sendbuf, len);
243 } else {
244 HILOGE("%s current_client_sock is not exist!", __func__);
245 }
246 }
247 }
248
Rtk_Service_Vendorcmd_Hook(Rtk_Service_Data * RtkData,int client_sock)249 void Rtk_Service_Vendorcmd_Hook(Rtk_Service_Data *RtkData, int client_sock)
250 {
251 Rtkqueuedata *rtkqueue_data = NULL;
252 if (!rtk_btservice) {
253 HILOGE("rtkbt service is null");
254 return;
255 }
256
257 pthread_mutex_lock(&rtk_btservice->cmdqueue_mutex);
258 rtkqueue_data = (Rtkqueuedata *)malloc(sizeof(Rtkqueuedata));
259 if (rtkqueue_data == NULL) {
260 HILOGE("rtkqueue_data: allocate error");
261 if (RtkData->parameter_len > 0) {
262 free(RtkData->parameter);
263 }
264 return;
265 }
266
267 rtkqueue_data->opcode = RtkData->opcode;
268 rtkqueue_data->parameter = RtkData->parameter;
269 rtkqueue_data->parameter_len = RtkData->parameter_len;
270 rtkqueue_data->client_sock = client_sock;
271 rtkqueue_data->complete_cback = RtkData->complete_cback;
272
273 ListAddToTail(&(rtkqueue_data->list), &(rtk_btservice->cmdqueue_list));
274 sem_post(&rtk_btservice->cmdqueue_sem);
275 pthread_mutex_unlock(&rtk_btservice->cmdqueue_mutex);
276 }
277
Rtk_Service_Cmd_Event_Cback(HC_BT_HDR * p_mem)278 static void Rtk_Service_Cmd_Event_Cback(HC_BT_HDR *p_mem)
279 {
280 if (p_mem != NULL) {
281 if (rtk_btservice->current_complete_cback != NULL) {
282 (*rtk_btservice->current_complete_cback)(p_mem);
283 } else {
284 HILOGE("%s current_complete_cback is not exist!", __func__);
285 }
286 rtk_btservice->current_complete_cback = NULL;
287 hcicmd_stop_reply_timer();
288 sem_post(&rtk_btservice->cmdsend_sem);
289 }
290 }
291
Rtk_Service_Send_Hwerror_Event(void)292 static void Rtk_Service_Send_Hwerror_Event(void)
293 {
294 #define EVENT_P_BUF_2 2
295 #define EVENT_P_BUF_3 3
296 unsigned char p_buf[4];
297 int length = 4;
298 p_buf[0] = 0x04; // event
299 p_buf[1] = 0x10; // hardware error
300 p_buf[EVENT_P_BUF_2] = 0x01; // len
301 p_buf[EVENT_P_BUF_3] = 0xfd; // rtkbtservice error code
302 userial_recv_rawdata_hook(p_buf, length);
303 }
304
cmdready_thread(void)305 static void *cmdready_thread(void)
306 {
307 while (rtk_btservice->cmdqueue_thread_running) {
308 sem_wait(&rtk_btservice->cmdqueue_sem);
309 sem_wait(&rtk_btservice->cmdsend_sem);
310
311 if (rtk_btservice->cmdqueue_thread_running != 0) {
312 pthread_mutex_lock(&rtk_btservice->cmdqueue_mutex);
313 RT_LIST_ENTRY *iter = ListGetTop(&(rtk_btservice->cmdqueue_list));
314 Rtkqueuedata *desc = NULL;
315 if (iter) {
316 desc = LIST_ENTRY(iter, Rtkqueuedata, list);
317 if (desc) {
318 ListDeleteNode(&desc->list);
319 }
320 }
321
322 pthread_mutex_unlock(&rtk_btservice->cmdqueue_mutex);
323
324 if (desc) {
325 if (desc->opcode == 0xfc77) {
326 rtk_btservice->autopair_fd = desc->client_sock;
327 }
328
329 if (desc->opcode != 0xfc94) {
330 HILOGD("%s, transmit_command Opcode:%x", __func__, desc->opcode);
331 }
332 rtk_btservice->current_client_sock = desc->client_sock;
333 rtk_btservice->current_complete_cback = desc->complete_cback;
334 rtk_vendor_cmd_to_fw(desc->opcode, desc->parameter_len, desc->parameter, Rtk_Service_Cmd_Event_Cback);
335 hcicmd_start_reply_timer();
336 if (desc->parameter_len > 0) {
337 free(desc->parameter);
338 }
339 }
340 free(desc);
341 }
342 }
343 pthread_exit(0);
344 }
345
Getpacket_RTK_HCICMD(int client_sock_temp,int recvlen_temp)346 int Getpacket_RTK_HCICMD(int client_sock_temp, int recvlen_temp)
347 {
348 unsigned char opcodeh = 0;
349 unsigned char opcodel = 0;
350 unsigned char parameter_length = 0;
351 unsigned char *parameter = NULL;
352 int client_sock = 0;
353 int recvlen = 0;
354
355 Rtk_Service_Data *p_buf;
356
357 recvlen = read(client_sock, &opcodeh, 1);
358 if (recvlen <= 0) {
359 HILOGE("read opcode high char error");
360 return -1;
361 }
362 recvlen = read(client_sock, &opcodel, 1);
363 if (recvlen <= 0) {
364 HILOGE("read opcode low char error");
365 return -1;
366 }
367 recvlen = read(client_sock, ¶meter_length, 1);
368 if (recvlen <= 0) {
369 HILOGE("read parameter_length char error");
370 return -1;
371 }
372
373 if (parameter_length > 0) {
374 parameter = (unsigned char *)malloc(sizeof(char) * parameter_length);
375 if (!parameter) {
376 HILOGE("%s parameter alloc fail!", __func__);
377 return 1;
378 }
379 recvlen = read(client_sock, parameter, parameter_length);
380 HILOGD("%s parameter_length=%d,recvlen=%d", __func__, parameter_length, recvlen);
381 if (recvlen <= 0 || recvlen != parameter_length) {
382 HILOGE("read parameter_length char error recvlen=%d,parameter_length=%d\n", recvlen,
383 parameter_length);
384 free(parameter);
385 return -1;
386 }
387 }
388 p_buf = (Rtk_Service_Data *)malloc(sizeof(Rtk_Service_Data));
389 if (p_buf == NULL) {
390 HILOGE("p_buf: allocate error");
391 if (parameter) {
392 free(parameter);
393 }
394 return 1;
395 }
396
397 p_buf->opcode = (((unsigned short)opcodeh) << 8L) | opcodel;
398 p_buf->parameter = parameter;
399 p_buf->parameter_len = parameter_length;
400 p_buf->complete_cback = Rtk_Client_Cmd_Cback;
401 Rtk_Service_Vendorcmd_Hook(p_buf, client_sock);
402 free(p_buf);
403 return -1;
404 }
405
Getpacket(int client_sock)406 static void Getpacket(int client_sock)
407 {
408 unsigned char type = 0;
409 int recvlen = 0;
410 int ret = 0;
411
412 recvlen = read(client_sock, &type, 1);
413 HILOGD("%s recvlen=%d,type=%d", __func__, recvlen, type);
414 if (recvlen <= 0) {
415 close(client_sock);
416 if (client_sock == rtk_btservice->autopair_fd) {
417 rtk_btservice->autopair_fd = -1;
418 }
419 return;
420 }
421
422 switch (type) {
423 case RTK_HCICMD: {
424 ret = Getpacket_RTK_HCICMD(client_sock, recvlen);
425 if (ret == 1) {
426 return;
427 }
428 if (ret == -1) {
429 break;
430 }
431 }
432 case RTK_CLOSESOCRET: {
433 close(client_sock);
434 break;
435 }
436 default: {
437 HILOGE("%s The RtkSockData type is not found!", __func__);
438 break;
439 }
440 }
441 }
442
rtk_btservice_internal_event_intercept(uint8_t * p_full_msg,uint8_t * p_msg)443 void rtk_btservice_internal_event_intercept(uint8_t *p_full_msg, uint8_t *p_msg)
444 {
445 uint8_t *p = p_msg;
446 uint8_t event_code = *p++;
447 uint8_t subcode;
448 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_full_msg;
449 if (event_code == 0xff) {
450 HILOGD("rtk_btservice_internal_event_intercept event_code=0x%x", event_code);
451 }
452 switch (event_code) {
453 case HCI_VENDOR_SPECIFIC_EVT: {
454 STREAM_TO_UINT8(subcode, p);
455 switch (subcode) {
456 case HCI_RTKBT_AUTOPAIR_EVT: {
457 HILOGD("p_evt_buf_len=%d", p_evt_buf->len);
458 if (rtk_btservice->autopair_fd != -1) {
459 #define P_EVT_BUF_LEN_8 8
460 #define P_BLUEDROID_3 3
461 write(rtk_btservice->autopair_fd, p_evt_buf, p_evt_buf->len + P_EVT_BUF_LEN_8);
462 uint8_t p_bluedroid_len = p_evt_buf->len + 1;
463 uint8_t p_bluedroid[p_bluedroid_len];
464 p_bluedroid[0] = DATA_TYPE_EVENT;
465 (void)memcpy_s((uint8_t *)(p_bluedroid + 1), p_evt_buf->len, p_msg, p_evt_buf->len);
466 p_bluedroid[1] = 0x3e; // event_code
467 p_bluedroid[P_BLUEDROID_3] = 0x02; // subcode
468 userial_recv_rawdata_hook(p_bluedroid, p_bluedroid_len);
469 }
470 }
471 break;
472 default:
473 break;
474 }
475 break;
476 }
477 default:
478 break;
479 }
480 }
481
socket_accept(socketfd)482 static int socket_accept(socketfd)
483 {
484 struct sockaddr_un un;
485 socklen_t len;
486 int client_sock = 0;
487 len = sizeof(un);
488 struct epoll_event event;
489
490 client_sock = accept(socketfd, (struct sockaddr *)&un, &len);
491 if (client_sock < 0) {
492 printf("accept failed\n");
493 return -1;
494 }
495
496 event.data.fd = client_sock;
497 event.events = EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR;
498 if (epoll_ctl(rtk_btservice->epoll_fd, EPOLL_CTL_ADD, client_sock, &event) == -1) {
499 HILOGE("%s unable to register fd %d to epoll set: %s", __func__, client_sock, strerror(errno));
500 close(client_sock);
501 return -1;
502 }
503 return 0;
504 }
505
epoll_thread(void)506 static void *epoll_thread(void)
507 {
508 struct epoll_event events[64];
509 int nfds = 0;
510 int i = 0;
511
512 while (rtk_btservice->epoll_thread_running) {
513 #define EPOLL_WAIT_32 32
514 #define EPOLL_WAIT_500 500
515 nfds = epoll_wait(rtk_btservice->epoll_fd, events, EPOLL_WAIT_32, EPOLL_WAIT_500);
516 if (rtk_btservice->epoll_thread_running != 0) {
517 if (nfds > 0) {
518 for (i = 0; i < nfds; i++) {
519 if (events[i].data.fd == rtk_btservice->sig_fd[1]) {
520 HILOGE("epoll_thread , receive exit signal");
521 continue;
522 }
523
524 if (events[i].data.fd == rtk_btservice->socketfd && (events[i].events & EPOLLIN)) {
525 if (socket_accept(events[i].data.fd) < 0) {
526 pthread_exit(0);
527 }
528 } else if (events[i].events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR)) {
529 HILOGD("%s events[i].data.fd = %d ", __func__, events[i].data.fd);
530 Getpacket(events[i].data.fd);
531 }
532 }
533 }
534 }
535 }
536 pthread_exit(0);
537 }
538
unix_socket_start(const char * servername)539 static int unix_socket_start(const char *servername)
540 {
541 int len;
542 struct sockaddr_un un;
543 struct epoll_event event;
544
545 if ((rtk_btservice->socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
546 HILOGE("%s create AF_UNIX socket fail!", __func__);
547 return -1;
548 }
549
550 (void)memset_s(&un, sizeof(un), 0, sizeof(un));
551 un.sun_family = AF_UNIX;
552 (void)strcpy_s(un.sun_path, sizeof(un.sun_path), servername);
553 un.sun_path[0] = 0;
554 len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
555
556 if (bind(rtk_btservice->socketfd, (struct sockaddr *)&un, len) < 0) {
557 HILOGE("%s bind socket fail!", __func__);
558 return -1;
559 }
560
561 if (listen(rtk_btservice->socketfd, MAX_CONNECTION_NUMBER) < 0) {
562 HILOGE("%s listen socket fail!", __func__);
563 return -1;
564 }
565
566 event.data.fd = rtk_btservice->socketfd;
567 event.events = EPOLLIN;
568 if (epoll_ctl(rtk_btservice->epoll_fd, EPOLL_CTL_ADD, rtk_btservice->socketfd, &event) == -1) {
569 HILOGE("%s unable to register fd %d to epoll set: %s", __func__, rtk_btservice->socketfd, strerror(errno));
570 return -1;
571 }
572
573 event.data.fd = rtk_btservice->sig_fd[1];
574 event.events = EPOLLIN;
575 if (epoll_ctl(rtk_btservice->epoll_fd, EPOLL_CTL_ADD, rtk_btservice->sig_fd[1], &event) == -1) {
576 HILOGE("%s unable to register signal fd %d to epoll set: %s", __func__, rtk_btservice->sig_fd[1],
577 strerror(errno));
578 return -1;
579 }
580 return 0;
581 }
582
RTK_btservice_send_close_signal(void)583 void RTK_btservice_send_close_signal(void)
584 {
585 unsigned char close_signal = 1;
586 ssize_t ret;
587 RTK_NO_INTR(ret = write(rtk_btservice->sig_fd[0], &close_signal, 1));
588 }
589
RTK_btservice_thread_start(void)590 int RTK_btservice_thread_start(void)
591 {
592 rtk_btservice->epoll_thread_running = 1;
593 if (pthread_create(&rtk_btservice->epollthd, NULL, epoll_thread, NULL) != 0) {
594 HILOGE("pthread_create epoll_thread: %s", strerror(errno));
595 return -1;
596 }
597
598 rtk_btservice->cmdqueue_thread_running = 1;
599 if (pthread_create(&rtk_btservice->cmdreadythd, NULL, cmdready_thread, NULL) != 0) {
600 HILOGE("pthread_create cmdready_thread: %s", strerror(errno));
601 return -1;
602 }
603
604 return 0;
605 }
606
RTK_btservice_thread_stop(void)607 void RTK_btservice_thread_stop(void)
608 {
609 rtk_btservice->epoll_thread_running = 0;
610 rtk_btservice->cmdqueue_thread_running = 0;
611 RTK_btservice_send_close_signal();
612 sem_post(&rtk_btservice->cmdqueue_sem);
613 sem_post(&rtk_btservice->cmdsend_sem);
614 pthread_join(rtk_btservice->cmdreadythd, NULL);
615 pthread_join(rtk_btservice->epollthd, NULL);
616 close(rtk_btservice->epoll_fd);
617 HILOGD("%s end!", __func__);
618 }
619
RTK_btservice_init(void)620 int RTK_btservice_init(void)
621 {
622 int ret;
623 rtk_btservice = (Rtk_Btservice_Info *)malloc(sizeof(Rtk_Btservice_Info));
624 if (rtk_btservice) {
625 (void)memset_s(rtk_btservice, sizeof(Rtk_Btservice_Info), 0, sizeof(Rtk_Btservice_Info));
626 } else {
627 HILOGE("%s, alloc fail", __func__);
628 return -1;
629 }
630
631 rtk_btservice->current_client_sock = -1;
632 rtk_btservice->current_complete_cback = NULL;
633 rtk_btservice->autopair_fd = -1;
634 hcicmd_alloc_reply_timer();
635
636 sem_init(&rtk_btservice->cmdqueue_sem, 0, 0);
637 sem_init(&rtk_btservice->cmdsend_sem, 0, 1);
638
639 pthread_mutex_init(&rtk_btservice->cmdqueue_mutex, NULL);
640 init_cmdqueue_hash(rtk_btservice);
641 if (bt_vendor_cbacks == NULL) {
642 HILOGE("%s bt_vendor_cbacks is NULL!", __func__);
643 return -1;
644 }
645
646 if ((ret = socketpair(AF_UNIX, SOCK_STREAM, 0, rtk_btservice->sig_fd)) < 0) {
647 HILOGE("%s, errno : %s", __func__, strerror(errno));
648 return ret;
649 }
650
651 #define EPOLL_CREATE_64 64
652 rtk_btservice->epoll_fd = epoll_create(EPOLL_CREATE_64);
653 if (rtk_btservice->epoll_fd == -1) {
654 HILOGE("%s unable to create epoll instance: %s", __func__, strerror(errno));
655 return -1;
656 }
657
658 if (unix_socket_start(RTKBTSERVICE_SOCKETPATH) < 0) {
659 HILOGE("%s unix_socket_start fail!", __func__);
660 return -1;
661 }
662
663 ret = RTK_btservice_thread_start();
664 if (ret < 0) {
665 HILOGE("%s RTK_btservice_thread_start fail!", __func__);
666 return -1;
667 }
668 HILOGD("%s init done!", __func__);
669 return 0;
670 }
671
RTK_btservice_destroyed(void)672 void RTK_btservice_destroyed(void)
673 {
674 if (!rtk_btservice) {
675 return;
676 }
677 RTK_btservice_thread_stop();
678 close(rtk_btservice->socketfd);
679 rtk_btservice->socketfd = -1;
680 close(rtk_btservice->sig_fd[0]);
681 close(rtk_btservice->sig_fd[1]);
682 sem_destroy(&rtk_btservice->cmdqueue_sem);
683 sem_destroy(&rtk_btservice->cmdsend_sem);
684 flush_cmdqueue_hash(rtk_btservice);
685 hcicmd_free_reply_timer();
686 pthread_mutex_destroy(&rtk_btservice->cmdqueue_mutex);
687 rtk_btservice->autopair_fd = -1;
688 rtk_btservice->current_client_sock = -1;
689 free(rtk_btservice);
690 rtk_btservice = NULL;
691 HILOGD("%s destroyed done!", __func__);
692 }
693