blob: 24fa7111064727a20f5933d12c247c8a65e3eb91 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
Jakub Pawlowski5b790fe2017-09-18 09:00:20 -07003 * Copyright 2009-2012 Broadcom Corporation
The Android Open Source Project5738f832012-12-12 16:00:35 -08004 *
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 *
Pavlin Radoslavovb2a292b2016-10-14 19:34:48 -070021 * Filename: uipc.cc
The Android Open Source Project5738f832012-12-12 16:00:35 -080022 *
Marie Janssen21da6372016-11-02 18:31:55 -070023 * Description: UIPC implementation for fluoride
The Android Open Source Project5738f832012-12-12 16:00:35 -080024 *
25 *****************************************************************************/
26
The Android Open Source Project5738f832012-12-12 16:00:35 -080027#include <errno.h>
Miao Chou10969122015-06-09 17:39:46 -070028#include <fcntl.h>
Miao Chou10969122015-06-09 17:39:46 -070029#include <signal.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080033#include <sys/mman.h>
Miao Chou10969122015-06-09 17:39:46 -070034#include <sys/poll.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080035#include <sys/prctl.h>
Miao Chou10969122015-06-09 17:39:46 -070036#include <sys/select.h>
37#include <sys/socket.h>
38#include <sys/stat.h>
39#include <sys/un.h>
40#include <unistd.h>
Marie Janssen21da6372016-11-02 18:31:55 -070041#include <mutex>
Hansong Zhangf88552c2018-02-01 18:02:53 -080042#include <set>
The Android Open Source Project5738f832012-12-12 16:00:35 -080043
Pavlin Radoslavov304ceeb2017-04-05 16:18:26 -070044#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
Myles Watson911d1ae2016-11-28 16:44:40 -080045#include "bt_common.h"
Miao Chou10969122015-06-09 17:39:46 -070046#include "bt_types.h"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080047#include "bt_utils.h"
Pavlin Radoslavovd6121a32016-05-12 11:36:44 -070048#include "osi/include/osi.h"
Miao Chou10969122015-06-09 17:39:46 -070049#include "osi/include/socket_utils/sockets.h"
50#include "uipc.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080051
52/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -080053 * Constants & Macros
54 *****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080055
56#define PCM_FILENAME "/data/test.pcm"
57
Myles Watson911d1ae2016-11-28 16:44:40 -080058#define MAX(a, b) ((a) > (b) ? (a) : (b))
The Android Open Source Project5738f832012-12-12 16:00:35 -080059
Myles Watson911d1ae2016-11-28 16:44:40 -080060#define CASE_RETURN_STR(const) \
61 case const: \
62 return #const;
The Android Open Source Project5738f832012-12-12 16:00:35 -080063
64#define UIPC_DISCONNECTED (-1)
65
Marie Janssend19e0782016-07-15 12:48:27 -070066#define SAFE_FD_ISSET(fd, set) (((fd) == -1) ? false : FD_ISSET((fd), (set)))
Elliott Hughes2408d9e2013-10-02 21:28:50 -070067
Andre Eisenbachc5916e92014-11-07 15:46:04 -080068#define UIPC_FLUSH_BUFFER_SIZE 1024
69
The Android Open Source Project5738f832012-12-12 16:00:35 -080070/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -080071 * Local type definitions
72 *****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080073
74typedef enum {
Myles Watson911d1ae2016-11-28 16:44:40 -080075 UIPC_TASK_FLAG_DISCONNECT_CHAN = 0x1,
The Android Open Source Project5738f832012-12-12 16:00:35 -080076} tUIPC_TASK_FLAGS;
77
The Android Open Source Project5738f832012-12-12 16:00:35 -080078/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -080079 * Static functions
80 *****************************************************************************/
Jakub Pawlowski4653f212018-03-01 16:23:58 -080081static int uipc_close_ch_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -080082
83/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -080084 * Externs
85 *****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080086
The Android Open Source Project5738f832012-12-12 16:00:35 -080087/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -080088 * Helper functions
89 *****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080090
Myles Watson911d1ae2016-11-28 16:44:40 -080091const char* dump_uipc_event(tUIPC_EVENT event) {
92 switch (event) {
93 CASE_RETURN_STR(UIPC_OPEN_EVT)
94 CASE_RETURN_STR(UIPC_CLOSE_EVT)
95 CASE_RETURN_STR(UIPC_RX_DATA_EVT)
96 CASE_RETURN_STR(UIPC_RX_DATA_READY_EVT)
97 CASE_RETURN_STR(UIPC_TX_DATA_READY_EVT)
98 default:
99 return "UNKNOWN MSG ID";
100 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800101}
102
103/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800104 * socket helper functions
105 ****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800106
Myles Watson911d1ae2016-11-28 16:44:40 -0800107static inline int create_server_socket(const char* name) {
108 int s = socket(AF_LOCAL, SOCK_STREAM, 0);
109 if (s < 0) return -1;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800110
Myles Watson911d1ae2016-11-28 16:44:40 -0800111 BTIF_TRACE_EVENT("create_server_socket %s", name);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800112
Myles Watson911d1ae2016-11-28 16:44:40 -0800113 if (osi_socket_local_server_bind(s, name,
Jakub Pawlowski7da3a4a2016-10-13 15:46:30 -0700114#if defined(OS_GENERIC)
Myles Watson911d1ae2016-11-28 16:44:40 -0800115 ANDROID_SOCKET_NAMESPACE_FILESYSTEM
116#else // !defined(OS_GENERIC)
117 ANDROID_SOCKET_NAMESPACE_ABSTRACT
Jakub Pawlowski7da3a4a2016-10-13 15:46:30 -0700118#endif // defined(OS_GENERIC)
Myles Watson911d1ae2016-11-28 16:44:40 -0800119 ) < 0) {
120 BTIF_TRACE_EVENT("socket failed to create (%s)", strerror(errno));
121 close(s);
122 return -1;
123 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800124
Myles Watson911d1ae2016-11-28 16:44:40 -0800125 if (listen(s, 5) < 0) {
126 BTIF_TRACE_EVENT("listen failed", strerror(errno));
127 close(s);
128 return -1;
129 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800130
Myles Watson911d1ae2016-11-28 16:44:40 -0800131 BTIF_TRACE_EVENT("created socket fd %d", s);
132 return s;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800133}
134
Myles Watson911d1ae2016-11-28 16:44:40 -0800135static int accept_server_socket(int sfd) {
136 struct sockaddr_un remote;
137 struct pollfd pfd;
138 int fd;
139 socklen_t len = sizeof(struct sockaddr_un);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800140
Myles Watson911d1ae2016-11-28 16:44:40 -0800141 BTIF_TRACE_EVENT("accept fd %d", sfd);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800142
Myles Watson911d1ae2016-11-28 16:44:40 -0800143 /* make sure there is data to process */
144 pfd.fd = sfd;
145 pfd.events = POLLIN;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800146
Myles Watson911d1ae2016-11-28 16:44:40 -0800147 int poll_ret;
148 OSI_NO_INTR(poll_ret = poll(&pfd, 1, 0));
149 if (poll_ret == 0) {
150 BTIF_TRACE_WARNING("accept poll timeout");
151 return -1;
152 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800153
Myles Watson911d1ae2016-11-28 16:44:40 -0800154 // BTIF_TRACE_EVENT("poll revents 0x%x", pfd.revents);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800155
Myles Watson911d1ae2016-11-28 16:44:40 -0800156 OSI_NO_INTR(fd = accept(sfd, (struct sockaddr*)&remote, &len));
157 if (fd == -1) {
158 BTIF_TRACE_ERROR("sock accept failed (%s)", strerror(errno));
159 return -1;
160 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800161
Myles Watson911d1ae2016-11-28 16:44:40 -0800162 // match socket buffer size option with client
163 const int size = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
164 int ret =
165 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&size, (int)sizeof(size));
166 if (ret < 0) {
167 BTIF_TRACE_ERROR("setsockopt failed (%s)", strerror(errno));
168 }
Andy Hung3d022152016-05-04 15:47:05 -0700169
Myles Watson911d1ae2016-11-28 16:44:40 -0800170 // BTIF_TRACE_EVENT("new fd %d", fd);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800171
Myles Watson911d1ae2016-11-28 16:44:40 -0800172 return fd;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800173}
174
175/*****************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800176 *
177 * uipc helper functions
178 *
179 ****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800180
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800181static int uipc_main_init(tUIPC_STATE& uipc) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800182 int i;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800183
Myles Watson911d1ae2016-11-28 16:44:40 -0800184 BTIF_TRACE_EVENT("### uipc_main_init ###");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800185
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800186 uipc.tid = 0;
187 uipc.running = 0;
188 memset(&uipc.active_set, 0, sizeof(uipc.active_set));
189 memset(&uipc.read_set, 0, sizeof(uipc.read_set));
190 uipc.max_fd = 0;
191 memset(&uipc.signal_fds, 0, sizeof(uipc.signal_fds));
192 memset(&uipc.ch, 0, sizeof(uipc.ch));
Marie Janssen21da6372016-11-02 18:31:55 -0700193
Myles Watson911d1ae2016-11-28 16:44:40 -0800194 /* setup interrupt socket pair */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800195 if (socketpair(AF_UNIX, SOCK_STREAM, 0, uipc.signal_fds) < 0) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800196 return -1;
197 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800198
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800199 FD_SET(uipc.signal_fds[0], &uipc.active_set);
200 uipc.max_fd = MAX(uipc.max_fd, uipc.signal_fds[0]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800201
Myles Watson911d1ae2016-11-28 16:44:40 -0800202 for (i = 0; i < UIPC_CH_NUM; i++) {
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800203 tUIPC_CHAN* p = &uipc.ch[i];
Myles Watson911d1ae2016-11-28 16:44:40 -0800204 p->srvfd = UIPC_DISCONNECTED;
205 p->fd = UIPC_DISCONNECTED;
206 p->task_evt_flags = 0;
Myles Watson911d1ae2016-11-28 16:44:40 -0800207 p->cback = NULL;
208 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800209
Myles Watson911d1ae2016-11-28 16:44:40 -0800210 return 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800211}
212
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800213void uipc_main_cleanup(tUIPC_STATE& uipc) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800214 int i;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800215
Myles Watson911d1ae2016-11-28 16:44:40 -0800216 BTIF_TRACE_EVENT("uipc_main_cleanup");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800217
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800218 close(uipc.signal_fds[0]);
219 close(uipc.signal_fds[1]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800220
Myles Watson911d1ae2016-11-28 16:44:40 -0800221 /* close any open channels */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800222 for (i = 0; i < UIPC_CH_NUM; i++) uipc_close_ch_locked(uipc, i);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800223}
224
The Android Open Source Project5738f832012-12-12 16:00:35 -0800225/* check pending events in read task */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800226static void uipc_check_task_flags_locked(tUIPC_STATE& uipc) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800227 int i;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800228
Myles Watson911d1ae2016-11-28 16:44:40 -0800229 for (i = 0; i < UIPC_CH_NUM; i++) {
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800230 if (uipc.ch[i].task_evt_flags & UIPC_TASK_FLAG_DISCONNECT_CHAN) {
231 uipc.ch[i].task_evt_flags &= ~UIPC_TASK_FLAG_DISCONNECT_CHAN;
232 uipc_close_ch_locked(uipc, i);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800233 }
234
Myles Watson911d1ae2016-11-28 16:44:40 -0800235 /* add here */
236 }
237}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800238
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800239static int uipc_check_fd_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800240 if (ch_id >= UIPC_CH_NUM) return -1;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800241
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800242 // BTIF_TRACE_EVENT("CHECK SRVFD %d (ch %d)", uipc.ch[ch_id].srvfd,
Myles Watson911d1ae2016-11-28 16:44:40 -0800243 // ch_id);
244
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800245 if (SAFE_FD_ISSET(uipc.ch[ch_id].srvfd, &uipc.read_set)) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800246 BTIF_TRACE_EVENT("INCOMING CONNECTION ON CH %d", ch_id);
247
Pavlin Radoslavov09fa9c52017-02-22 22:07:17 -0800248 // Close the previous connection
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800249 if (uipc.ch[ch_id].fd != UIPC_DISCONNECTED) {
250 BTIF_TRACE_EVENT("CLOSE CONNECTION (FD %d)", uipc.ch[ch_id].fd);
251 close(uipc.ch[ch_id].fd);
252 FD_CLR(uipc.ch[ch_id].fd, &uipc.active_set);
253 uipc.ch[ch_id].fd = UIPC_DISCONNECTED;
Pavlin Radoslavov09fa9c52017-02-22 22:07:17 -0800254 }
255
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800256 uipc.ch[ch_id].fd = accept_server_socket(uipc.ch[ch_id].srvfd);
Myles Watson911d1ae2016-11-28 16:44:40 -0800257
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800258 BTIF_TRACE_EVENT("NEW FD %d", uipc.ch[ch_id].fd);
Myles Watson911d1ae2016-11-28 16:44:40 -0800259
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800260 if ((uipc.ch[ch_id].fd >= 0) && uipc.ch[ch_id].cback) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800261 /* if we have a callback we should add this fd to the active set
262 and notify user with callback event */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800263 BTIF_TRACE_EVENT("ADD FD %d TO ACTIVE SET", uipc.ch[ch_id].fd);
264 FD_SET(uipc.ch[ch_id].fd, &uipc.active_set);
265 uipc.max_fd = MAX(uipc.max_fd, uipc.ch[ch_id].fd);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800266 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800267
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800268 if (uipc.ch[ch_id].fd < 0) {
Pavlin Radoslavov7b673022017-09-19 20:29:33 -0700269 BTIF_TRACE_ERROR("FAILED TO ACCEPT CH %d", ch_id);
Myles Watson911d1ae2016-11-28 16:44:40 -0800270 return -1;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800271 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800272
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800273 if (uipc.ch[ch_id].cback) uipc.ch[ch_id].cback(ch_id, UIPC_OPEN_EVT);
Myles Watson911d1ae2016-11-28 16:44:40 -0800274 }
275
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800276 // BTIF_TRACE_EVENT("CHECK FD %d (ch %d)", uipc.ch[ch_id].fd, ch_id);
Myles Watson911d1ae2016-11-28 16:44:40 -0800277
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800278 if (SAFE_FD_ISSET(uipc.ch[ch_id].fd, &uipc.read_set)) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800279 // BTIF_TRACE_EVENT("INCOMING DATA ON CH %d", ch_id);
280
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800281 if (uipc.ch[ch_id].cback)
282 uipc.ch[ch_id].cback(ch_id, UIPC_RX_DATA_READY_EVT);
Myles Watson911d1ae2016-11-28 16:44:40 -0800283 }
284 return 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800285}
286
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800287static void uipc_check_interrupt_locked(tUIPC_STATE& uipc) {
288 if (SAFE_FD_ISSET(uipc.signal_fds[0], &uipc.read_set)) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800289 char sig_recv = 0;
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800290 OSI_NO_INTR(
291 recv(uipc.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL));
Myles Watson911d1ae2016-11-28 16:44:40 -0800292 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800293}
294
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800295static inline void uipc_wakeup_locked(tUIPC_STATE& uipc) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800296 char sig_on = 1;
297 BTIF_TRACE_EVENT("UIPC SEND WAKE UP");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800298
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800299 OSI_NO_INTR(send(uipc.signal_fds[1], &sig_on, sizeof(sig_on), 0));
Myles Watson911d1ae2016-11-28 16:44:40 -0800300}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800301
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800302static int uipc_setup_server_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id,
303 const char* name, tUIPC_RCV_CBACK* cback) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800304 int fd;
305
306 BTIF_TRACE_EVENT("SETUP CHANNEL SERVER %d", ch_id);
307
308 if (ch_id >= UIPC_CH_NUM) return -1;
309
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800310 std::lock_guard<std::recursive_mutex> guard(uipc.mutex);
Myles Watson911d1ae2016-11-28 16:44:40 -0800311
312 fd = create_server_socket(name);
313
314 if (fd < 0) {
315 BTIF_TRACE_ERROR("failed to setup %s", name, strerror(errno));
Myles Watson911d1ae2016-11-28 16:44:40 -0800316 return -1;
317 }
318
319 BTIF_TRACE_EVENT("ADD SERVER FD TO ACTIVE SET %d", fd);
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800320 FD_SET(fd, &uipc.active_set);
321 uipc.max_fd = MAX(uipc.max_fd, fd);
Myles Watson911d1ae2016-11-28 16:44:40 -0800322
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800323 uipc.ch[ch_id].srvfd = fd;
324 uipc.ch[ch_id].cback = cback;
325 uipc.ch[ch_id].read_poll_tmo_ms = DEFAULT_READ_POLL_TMO_MS;
Myles Watson911d1ae2016-11-28 16:44:40 -0800326
327 /* trigger main thread to update read set */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800328 uipc_wakeup_locked(uipc);
Myles Watson911d1ae2016-11-28 16:44:40 -0800329
Myles Watson911d1ae2016-11-28 16:44:40 -0800330 return 0;
331}
332
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800333static void uipc_flush_ch_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800334 char buf[UIPC_FLUSH_BUFFER_SIZE];
335 struct pollfd pfd;
336
337 pfd.events = POLLIN;
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800338 pfd.fd = uipc.ch[ch_id].fd;
Myles Watson911d1ae2016-11-28 16:44:40 -0800339
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800340 if (uipc.ch[ch_id].fd == UIPC_DISCONNECTED) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800341 BTIF_TRACE_EVENT("%s() - fd disconnected. Exiting", __func__);
342 return;
343 }
344
345 while (1) {
346 int ret;
347 OSI_NO_INTR(ret = poll(&pfd, 1, 1));
348 if (ret == 0) {
349 BTIF_TRACE_VERBOSE("%s(): poll() timeout - nothing to do. Exiting",
350 __func__);
351 return;
352 }
353 if (ret < 0) {
354 BTIF_TRACE_WARNING(
355 "%s() - poll() failed: return %d errno %d (%s). Exiting", __func__,
356 ret, errno, strerror(errno));
357 return;
358 }
359 BTIF_TRACE_VERBOSE("%s() - polling fd %d, revents: 0x%x, ret %d", __func__,
360 pfd.fd, pfd.revents, ret);
361 if (pfd.revents & (POLLERR | POLLHUP)) {
362 BTIF_TRACE_WARNING("%s() - POLLERR or POLLHUP. Exiting", __func__);
363 return;
364 }
365
366 /* read sufficiently large buffer to ensure flush empties socket faster than
367 it is getting refilled */
368 read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE);
369 }
370}
371
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800372static void uipc_flush_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800373 if (ch_id >= UIPC_CH_NUM) return;
374
375 switch (ch_id) {
376 case UIPC_CH_ID_AV_CTRL:
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800377 uipc_flush_ch_locked(uipc, UIPC_CH_ID_AV_CTRL);
Myles Watson911d1ae2016-11-28 16:44:40 -0800378 break;
379
380 case UIPC_CH_ID_AV_AUDIO:
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800381 uipc_flush_ch_locked(uipc, UIPC_CH_ID_AV_AUDIO);
Myles Watson911d1ae2016-11-28 16:44:40 -0800382 break;
383 }
384}
385
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800386static int uipc_close_ch_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800387 int wakeup = 0;
388
389 BTIF_TRACE_EVENT("CLOSE CHANNEL %d", ch_id);
390
391 if (ch_id >= UIPC_CH_NUM) return -1;
392
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800393 if (uipc.ch[ch_id].srvfd != UIPC_DISCONNECTED) {
394 BTIF_TRACE_EVENT("CLOSE SERVER (FD %d)", uipc.ch[ch_id].srvfd);
395 close(uipc.ch[ch_id].srvfd);
396 FD_CLR(uipc.ch[ch_id].srvfd, &uipc.active_set);
397 uipc.ch[ch_id].srvfd = UIPC_DISCONNECTED;
Myles Watson911d1ae2016-11-28 16:44:40 -0800398 wakeup = 1;
399 }
400
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800401 if (uipc.ch[ch_id].fd != UIPC_DISCONNECTED) {
402 BTIF_TRACE_EVENT("CLOSE CONNECTION (FD %d)", uipc.ch[ch_id].fd);
403 close(uipc.ch[ch_id].fd);
404 FD_CLR(uipc.ch[ch_id].fd, &uipc.active_set);
405 uipc.ch[ch_id].fd = UIPC_DISCONNECTED;
Myles Watson911d1ae2016-11-28 16:44:40 -0800406 wakeup = 1;
407 }
408
409 /* notify this connection is closed */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800410 if (uipc.ch[ch_id].cback) uipc.ch[ch_id].cback(ch_id, UIPC_CLOSE_EVT);
Myles Watson911d1ae2016-11-28 16:44:40 -0800411
412 /* trigger main thread update if something was updated */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800413 if (wakeup) uipc_wakeup_locked(uipc);
Myles Watson911d1ae2016-11-28 16:44:40 -0800414
415 return 0;
416}
417
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800418void uipc_close_locked(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id) {
419 if (uipc.ch[ch_id].srvfd == UIPC_DISCONNECTED) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800420 BTIF_TRACE_EVENT("CHANNEL %d ALREADY CLOSED", ch_id);
421 return;
422 }
423
424 /* schedule close on this channel */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800425 uipc.ch[ch_id].task_evt_flags |= UIPC_TASK_FLAG_DISCONNECT_CHAN;
426 uipc_wakeup_locked(uipc);
Myles Watson911d1ae2016-11-28 16:44:40 -0800427}
428
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800429static void* uipc_read_task(void* arg) {
430 tUIPC_STATE& uipc = *((tUIPC_STATE*)arg);
Myles Watson911d1ae2016-11-28 16:44:40 -0800431 int ch_id;
432 int result;
433
434 prctl(PR_SET_NAME, (unsigned long)"uipc-main", 0, 0, 0);
435
436 raise_priority_a2dp(TASK_UIPC_READ);
437
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800438 while (uipc.running) {
439 uipc.read_set = uipc.active_set;
Myles Watson911d1ae2016-11-28 16:44:40 -0800440
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800441 result = select(uipc.max_fd + 1, &uipc.read_set, NULL, NULL, NULL);
Myles Watson911d1ae2016-11-28 16:44:40 -0800442
443 if (result == 0) {
444 BTIF_TRACE_EVENT("select timeout");
445 continue;
446 }
447 if (result < 0) {
Marie Janssen21da6372016-11-02 18:31:55 -0700448 if (errno != EINTR) {
449 BTIF_TRACE_EVENT("select failed %s", strerror(errno));
450 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800451 continue;
452 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800453
Marie Janssen21da6372016-11-02 18:31:55 -0700454 {
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800455 std::lock_guard<std::recursive_mutex> guard(uipc.mutex);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800456
Marie Janssen21da6372016-11-02 18:31:55 -0700457 /* clear any wakeup interrupt */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800458 uipc_check_interrupt_locked(uipc);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800459
Marie Janssen21da6372016-11-02 18:31:55 -0700460 /* check pending task events */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800461 uipc_check_task_flags_locked(uipc);
Myles Watson911d1ae2016-11-28 16:44:40 -0800462
Marie Janssen21da6372016-11-02 18:31:55 -0700463 /* make sure we service audio channel first */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800464 uipc_check_fd_locked(uipc, UIPC_CH_ID_AV_AUDIO);
Myles Watson911d1ae2016-11-28 16:44:40 -0800465
Marie Janssen21da6372016-11-02 18:31:55 -0700466 /* check for other connections */
467 for (ch_id = 0; ch_id < UIPC_CH_NUM; ch_id++) {
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800468 if (ch_id != UIPC_CH_ID_AV_AUDIO) uipc_check_fd_locked(uipc, ch_id);
Marie Janssen21da6372016-11-02 18:31:55 -0700469 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800470 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800471 }
Pavlin Radoslavovdbf75f12016-11-08 00:57:53 +0000472
Myles Watson911d1ae2016-11-28 16:44:40 -0800473 BTIF_TRACE_EVENT("UIPC READ THREAD EXITING");
474
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800475 uipc_main_cleanup(uipc);
Myles Watson911d1ae2016-11-28 16:44:40 -0800476
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800477 uipc.tid = 0;
Myles Watson911d1ae2016-11-28 16:44:40 -0800478
479 BTIF_TRACE_EVENT("UIPC READ THREAD DONE");
480
481 return nullptr;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800482}
483
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800484int uipc_start_main_server_thread(tUIPC_STATE& uipc) {
485 uipc.running = 1;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800486
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800487 if (pthread_create(&uipc.tid, (const pthread_attr_t*)NULL, uipc_read_task,
488 &uipc) < 0) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800489 BTIF_TRACE_ERROR("uipc_thread_create pthread_create failed:%d", errno);
490 return -1;
491 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800492
Myles Watson911d1ae2016-11-28 16:44:40 -0800493 return 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800494}
495
496/* blocking call */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800497void uipc_stop_main_server_thread(tUIPC_STATE& uipc) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800498 /* request shutdown of read thread */
Marie Janssen21da6372016-11-02 18:31:55 -0700499 {
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800500 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
501 uipc.running = 0;
502 uipc_wakeup_locked(uipc);
Marie Janssen21da6372016-11-02 18:31:55 -0700503 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800504
Myles Watson911d1ae2016-11-28 16:44:40 -0800505 /* wait until read thread is fully terminated */
506 /* tid might hold pointer value where it's value
507 is negative vaule with singed bit is set, so
508 corrected the logic to check zero or non zero */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800509 if (uipc.tid) pthread_join(uipc.tid, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800510}
511
512/*******************************************************************************
513 **
514 ** Function UIPC_Init
515 **
516 ** Description Initialize UIPC module
517 **
518 ** Returns void
519 **
Myles Watsonee96a3c2016-11-23 14:49:54 -0800520 ******************************************************************************/
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800521std::unique_ptr<tUIPC_STATE> UIPC_Init() {
522 std::unique_ptr<tUIPC_STATE> uipc = std::make_unique<tUIPC_STATE>();
Myles Watson911d1ae2016-11-28 16:44:40 -0800523 BTIF_TRACE_DEBUG("UIPC_Init");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800524
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800525 std::lock_guard<std::recursive_mutex> lock(uipc->mutex);
526
527 uipc_main_init(*uipc);
528 uipc_start_main_server_thread(*uipc);
529
530 return uipc;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800531}
532
533/*******************************************************************************
534 **
535 ** Function UIPC_Open
536 **
537 ** Description Open UIPC interface
538 **
Marie Janssend19e0782016-07-15 12:48:27 -0700539 ** Returns true in case of success, false in case of failure.
The Android Open Source Project5738f832012-12-12 16:00:35 -0800540 **
Myles Watsonee96a3c2016-11-23 14:49:54 -0800541 ******************************************************************************/
Jakub Pawlowski16a63402018-03-02 02:22:33 -0800542bool UIPC_Open(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback,
543 const char* socket_path) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800544 BTIF_TRACE_DEBUG("UIPC_Open : ch_id %d, p_cback %x", ch_id, p_cback);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800545
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800546 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800547
Myles Watson911d1ae2016-11-28 16:44:40 -0800548 if (ch_id >= UIPC_CH_NUM) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800549 return false;
550 }
Pavlin Radoslavovdbf75f12016-11-08 00:57:53 +0000551
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800552 if (uipc.ch[ch_id].srvfd != UIPC_DISCONNECTED) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800553 BTIF_TRACE_EVENT("CHANNEL %d ALREADY OPEN", ch_id);
Myles Watson911d1ae2016-11-28 16:44:40 -0800554 return 0;
555 }
556
Jakub Pawlowski16a63402018-03-02 02:22:33 -0800557 uipc_setup_server_locked(uipc, ch_id, socket_path, p_cback);
Myles Watson911d1ae2016-11-28 16:44:40 -0800558
Myles Watson911d1ae2016-11-28 16:44:40 -0800559 return true;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800560}
561
562/*******************************************************************************
563 **
564 ** Function UIPC_Close
565 **
566 ** Description Close UIPC interface
567 **
568 ** Returns void
569 **
Myles Watsonee96a3c2016-11-23 14:49:54 -0800570 ******************************************************************************/
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800571void UIPC_Close(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800572 BTIF_TRACE_DEBUG("UIPC_Close : ch_id %d", ch_id);
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800573
Myles Watson911d1ae2016-11-28 16:44:40 -0800574 /* special case handling uipc shutdown */
575 if (ch_id != UIPC_CH_ID_ALL) {
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800576 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
577 uipc_close_locked(uipc, ch_id);
Hansong Zhangf88552c2018-02-01 18:02:53 -0800578 return;
579 }
580
Marie Janssen21da6372016-11-02 18:31:55 -0700581 BTIF_TRACE_DEBUG("UIPC_Close : waiting for shutdown to complete");
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800582 uipc_stop_main_server_thread(uipc);
Marie Janssen21da6372016-11-02 18:31:55 -0700583 BTIF_TRACE_DEBUG("UIPC_Close : shutdown complete");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800584}
585
586/*******************************************************************************
587 **
The Android Open Source Project5738f832012-12-12 16:00:35 -0800588 ** Function UIPC_Send
589 **
590 ** Description Called to transmit a message over UIPC.
591 **
Marie Janssend19e0782016-07-15 12:48:27 -0700592 ** Returns true in case of success, false in case of failure.
The Android Open Source Project5738f832012-12-12 16:00:35 -0800593 **
Myles Watsonee96a3c2016-11-23 14:49:54 -0800594 ******************************************************************************/
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800595bool UIPC_Send(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id,
596 UNUSED_ATTR uint16_t msg_evt, const uint8_t* p_buf,
597 uint16_t msglen) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800598 BTIF_TRACE_DEBUG("UIPC_Send : ch_id:%d %d bytes", ch_id, msglen);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800599
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800600 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800601
Myles Watson911d1ae2016-11-28 16:44:40 -0800602 ssize_t ret;
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800603 OSI_NO_INTR(ret = write(uipc.ch[ch_id].fd, p_buf, msglen));
Myles Watson911d1ae2016-11-28 16:44:40 -0800604 if (ret < 0) {
605 BTIF_TRACE_ERROR("failed to write (%s)", strerror(errno));
606 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800607
Myles Watson911d1ae2016-11-28 16:44:40 -0800608 return false;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800609}
610
611/*******************************************************************************
612 **
The Android Open Source Project5738f832012-12-12 16:00:35 -0800613 ** Function UIPC_Read
614 **
615 ** Description Called to read a message from UIPC.
616 **
617 ** Returns return the number of bytes read.
618 **
Myles Watsonee96a3c2016-11-23 14:49:54 -0800619 ******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800620
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800621uint32_t UIPC_Read(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id,
622 UNUSED_ATTR uint16_t* p_msg_evt, uint8_t* p_buf,
623 uint32_t len) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800624 if (ch_id >= UIPC_CH_NUM) {
625 BTIF_TRACE_ERROR("UIPC_Read : invalid ch id %d", ch_id);
626 return 0;
627 }
628
Chienyuanfa626172019-01-30 11:50:01 +0800629 int n_read = 0;
630 int fd = uipc.ch[ch_id].fd;
631 struct pollfd pfd;
632
Myles Watson911d1ae2016-11-28 16:44:40 -0800633 if (fd == UIPC_DISCONNECTED) {
634 BTIF_TRACE_ERROR("UIPC_Read : channel %d closed", ch_id);
635 return 0;
636 }
637
Myles Watson911d1ae2016-11-28 16:44:40 -0800638 while (n_read < (int)len) {
639 pfd.fd = fd;
640 pfd.events = POLLIN | POLLHUP;
641
642 /* make sure there is data prior to attempting read to avoid blocking
643 a read for more than poll timeout */
644
645 int poll_ret;
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800646 OSI_NO_INTR(poll_ret = poll(&pfd, 1, uipc.ch[ch_id].read_poll_tmo_ms));
Myles Watson911d1ae2016-11-28 16:44:40 -0800647 if (poll_ret == 0) {
648 BTIF_TRACE_WARNING("poll timeout (%d ms)",
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800649 uipc.ch[ch_id].read_poll_tmo_ms);
Myles Watson911d1ae2016-11-28 16:44:40 -0800650 break;
651 }
652 if (poll_ret < 0) {
653 BTIF_TRACE_ERROR("%s(): poll() failed: return %d errno %d (%s)", __func__,
654 poll_ret, errno, strerror(errno));
655 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800656 }
657
Myles Watson911d1ae2016-11-28 16:44:40 -0800658 // BTIF_TRACE_EVENT("poll revents %x", pfd.revents);
659
660 if (pfd.revents & (POLLHUP | POLLNVAL)) {
661 BTIF_TRACE_WARNING("poll : channel detached remotely");
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800662 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
663 uipc_close_locked(uipc, ch_id);
Myles Watson911d1ae2016-11-28 16:44:40 -0800664 return 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800665 }
666
Myles Watson911d1ae2016-11-28 16:44:40 -0800667 ssize_t n;
668 OSI_NO_INTR(n = recv(fd, p_buf + n_read, len - n_read, 0));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800669
Myles Watson911d1ae2016-11-28 16:44:40 -0800670 // BTIF_TRACE_EVENT("read %d bytes", n);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800671
Myles Watson911d1ae2016-11-28 16:44:40 -0800672 if (n == 0) {
673 BTIF_TRACE_WARNING("UIPC_Read : channel detached remotely");
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800674 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
675 uipc_close_locked(uipc, ch_id);
Myles Watson911d1ae2016-11-28 16:44:40 -0800676 return 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800677 }
678
Myles Watson911d1ae2016-11-28 16:44:40 -0800679 if (n < 0) {
680 BTIF_TRACE_WARNING("UIPC_Read : read failed (%s)", strerror(errno));
681 return 0;
682 }
683
684 n_read += n;
685 }
686
687 return n_read;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800688}
689
690/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800691 *
692 * Function UIPC_Ioctl
693 *
694 * Description Called to control UIPC.
695 *
696 * Returns void
697 *
698 ******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800699
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800700extern bool UIPC_Ioctl(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id, uint32_t request,
701 void* param) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800702 BTIF_TRACE_DEBUG("#### UIPC_Ioctl : ch_id %d, request %d ####", ch_id,
703 request);
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800704 std::lock_guard<std::recursive_mutex> lock(uipc.mutex);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800705
Myles Watson911d1ae2016-11-28 16:44:40 -0800706 switch (request) {
707 case UIPC_REQ_RX_FLUSH:
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800708 uipc_flush_locked(uipc, ch_id);
Myles Watson911d1ae2016-11-28 16:44:40 -0800709 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800710
Myles Watson911d1ae2016-11-28 16:44:40 -0800711 case UIPC_REG_CBACK:
712 // BTIF_TRACE_EVENT("register callback ch %d srvfd %d, fd %d", ch_id,
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800713 // uipc.ch[ch_id].srvfd, uipc.ch[ch_id].fd);
714 uipc.ch[ch_id].cback = (tUIPC_RCV_CBACK*)param;
Myles Watson911d1ae2016-11-28 16:44:40 -0800715 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800716
Myles Watson911d1ae2016-11-28 16:44:40 -0800717 case UIPC_REG_REMOVE_ACTIVE_READSET:
Myles Watson911d1ae2016-11-28 16:44:40 -0800718 /* user will read data directly and not use select loop */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800719 if (uipc.ch[ch_id].fd != UIPC_DISCONNECTED) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800720 /* remove this channel from active set */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800721 FD_CLR(uipc.ch[ch_id].fd, &uipc.active_set);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800722
Myles Watson911d1ae2016-11-28 16:44:40 -0800723 /* refresh active set */
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800724 uipc_wakeup_locked(uipc);
Myles Watson911d1ae2016-11-28 16:44:40 -0800725 }
726 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800727
Myles Watson911d1ae2016-11-28 16:44:40 -0800728 case UIPC_SET_READ_POLL_TMO:
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800729 uipc.ch[ch_id].read_poll_tmo_ms = (intptr_t)param;
Myles Watson911d1ae2016-11-28 16:44:40 -0800730 BTIF_TRACE_EVENT("UIPC_SET_READ_POLL_TMO : CH %d, TMO %d ms", ch_id,
Jakub Pawlowski4653f212018-03-01 16:23:58 -0800731 uipc.ch[ch_id].read_poll_tmo_ms);
Myles Watson911d1ae2016-11-28 16:44:40 -0800732 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800733
Myles Watson911d1ae2016-11-28 16:44:40 -0800734 default:
735 BTIF_TRACE_EVENT("UIPC_Ioctl : request not handled (%d)", request);
736 break;
737 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800738
Myles Watson911d1ae2016-11-28 16:44:40 -0800739 return false;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800740}