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