15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009-2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/************************************************************************************ 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Filename: btif_sock_thread.c 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: socket select thread 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ***********************************************************************************/ 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bluetooth.h> 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bt_sock.h> 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//bta_jv_co_rfc_data 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h> 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h> 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h> 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h> 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/types.h> 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/socket.h> 385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/un.h> 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <time.h> 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <fcntl.h> 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <unistd.h> 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <signal.h> 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <pthread.h> 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <ctype.h> 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/select.h> 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/poll.h> 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <cutils/sockets.h> 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <alloca.h> 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define LOG_TAG "BTIF_SOCK" 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_common.h" 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_util.h" 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bd.h" 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_api.h" 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock.h" 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_thread.h" 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_util.h" 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <cutils/log.h> 63e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati#define asrt(s) if(!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define print_events(events) do { \ 65e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("print poll event:%x", events); \ 66e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLIN) APPL_TRACE_DEBUG( " POLLIN "); \ 67e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLPRI) APPL_TRACE_DEBUG( " POLLPRI "); \ 68e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLOUT) APPL_TRACE_DEBUG( " POLLOUT "); \ 69e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLERR) APPL_TRACE_DEBUG( " POLLERR "); \ 70e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLHUP) APPL_TRACE_DEBUG( " POLLHUP "); \ 71e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLNVAL) APPL_TRACE_DEBUG(" POLLNVAL "); \ 72e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLRDHUP) APPL_TRACE_DEBUG(" POLLRDHUP"); \ 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } while(0) 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_THREAD 8 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_POLL 64 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define POLL_EXCEPTION_EVENTS (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL) 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define IS_EXCEPTION(e) ((e) & POLL_EXCEPTION_EVENTS) 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define IS_READ(e) ((e) & POLLIN) 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define IS_WRITE(e) ((e) & POLLOUT) 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*cmd executes in socket poll thread */ 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_WAKEUP 1 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_EXIT 2 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_ADD_FD 3 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_USER_PRIVATE 4 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct { 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct pollfd pfd; 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t user_id; 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int type; 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int flags; 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} poll_slot_t; 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct { 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int cmd_fdr, cmd_fdw; 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int poll_count; 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project poll_slot_t ps[MAX_POLL]; 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int psi[MAX_POLL]; //index of poll slot 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project volatile pid_t thread_id; 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsock_signaled_cb callback; 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsock_cmd_cb cmd_callback; 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int used; 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} thread_slot_t; 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic thread_slot_t ts[MAX_THREAD]; 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *sock_poll_thread(void *arg); 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void close_cmd_fd(int h); 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id); 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic pthread_mutex_t thread_slot_lock; 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void set_socket_blocking(int s, int blocking) 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int opts; 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project opts = fcntl(s, F_GETFL); 119e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (opts<0) APPL_TRACE_ERROR("set blocking (%s)", strerror(errno)); 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(blocking) 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project opts &= ~O_NONBLOCK; 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else opts |= O_NONBLOCK; 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcntl(s, F_SETFL, opts); 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline int create_server_socket(const char* name) 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int s = socket(AF_LOCAL, SOCK_STREAM, 0); 129e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("covert name to android abstract name:%s", name); 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0) 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(listen(s, 5) == 0) 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 134e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("listen to local socket:%s, fd:%d", name, s); 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return s; 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 137e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else APPL_TRACE_ERROR("listen to local socket:%s, fd:%d failed, errno:%d", name, s, errno); 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 139e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else APPL_TRACE_ERROR("create local socket:%s fd:%d, failed, errno:%d", name, s, errno); 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(s); 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline int connect_server_socket(const char* name) 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int s = socket(AF_LOCAL, SOCK_STREAM, 0); 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project set_socket_blocking(s, TRUE); 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(socket_local_client_connect(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) >= 0) 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 149e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("connected to local socket:%s, fd:%d", name, s); 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return s; 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 152e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else APPL_TRACE_ERROR("connect to local socket:%s, fd:%d failed, errno:%d", name, s, errno); 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(s); 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline int accept_server_socket(int s) 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct sockaddr_un client_address; 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project socklen_t clen; 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd = accept(s, (struct sockaddr*)&client_address, &clen); 161e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("accepted fd:%d for server fd:%d", fd, s); 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return fd; 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline pthread_t create_thread(void *(*start_routine)(void *), void * arg) 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_t thread_attr; 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_init(&thread_attr); 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_t thread_id = -1; 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( pthread_create(&thread_id, &thread_attr, start_routine, arg)!=0 ) 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 172e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("pthread_create : %s", strerror(errno)); 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return thread_id; 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void init_poll(int cmd_fd); 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int alloc_thread_slot() 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //revserd order to save guard uninitialized access to 0 index 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(i = MAX_THREAD - 1; i >=0; i--) 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 184e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("ts[%d].used:%d", i, ts[i].used); 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(!ts[i].used) 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[i].used = 1; 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return i; 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 191e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("execeeded max thread count"); 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void free_thread_slot(int h) 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(0 <= h && h < MAX_THREAD) 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close_cmd_fd(h); 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].used = 0; 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 201e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else APPL_TRACE_ERROR("invalid thread handle:%d", h); 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_init() 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project static int initialized; 206e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("in initialized:%d", initialized); 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(!initialized) 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project initialized = 1; 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project init_slot_lock(&thread_slot_lock); 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int h; 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(h = 0; h < MAX_THREAD; h++) 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_fdr = ts[h].cmd_fdw = -1; 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].used = 0; 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].thread_id = -1; 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].poll_count = 0; 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback = NULL; 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback = NULL; 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback) 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret = FALSE; 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(callback || cmd_callback); 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lock_slot(&thread_slot_lock); 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int h = alloc_thread_slot(); 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unlock_slot(&thread_slot_lock); 231e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("alloc_thread_slot ret:%d", h); 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h >= 0) 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project init_poll(h); 23522c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT if((ts[h].thread_id = create_thread(sock_poll_thread, (void*)(uintptr_t)h)) != -1) 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 237e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("h:%d, thread id:%d", h, ts[h].thread_id); 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback = callback; 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback = cmd_callback; 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free_thread_slot(h); 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h = -1; 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return h; 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* create dummy socket pair used to wake up select loop */ 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void init_cmd_fd(int h) 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].cmd_fdr == -1 && ts[h].cmd_fdw == -1); 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(socketpair(AF_UNIX, SOCK_STREAM, 0, &ts[h].cmd_fdr) < 0) 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 256e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("socketpair failed: %s", strerror(errno)); 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 259e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("h:%d, cmd_fdr:%d, cmd_fdw:%d", h, ts[h].cmd_fdr, ts[h].cmd_fdw); 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //add the cmd fd for read & write 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project add_poll(h, ts[h].cmd_fdr, 0, SOCK_THREAD_FD_RD, 0); 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void close_cmd_fd(int h) 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdr != -1) 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(ts[h].cmd_fdr); 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_fdr = -1; 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw != -1) 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(ts[h].cmd_fdw); 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_fdw = -1; 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int id; 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd; 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int type; 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int flags; 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t user_id; 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} sock_cmd_t; 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 288e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 293e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("cmd socket is not created. socket thread may not initialized"); 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags & SOCK_THREAD_ADD_FD_SYNC) 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //must executed in socket poll thread 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].thread_id == pthread_self()) 3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //cleanup one-time flags 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags &= ~SOCK_THREAD_ADD_FD_SYNC; 3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project add_poll(h, fd, type, flags, user_id); 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 306e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async"); 3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id}; 309e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags); 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id) 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 316e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 321e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("cmd socket is not created. socket thread may not initialized"); 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id}; 325e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("post cmd type:%d, size:%d, h:%d, ", type, size, h); 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t* cmd_send = &cmd; 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int size_send = sizeof(cmd); 3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(data && size) 3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project size_send = sizeof(cmd) + size; 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project cmd_send = (sock_cmd_t*)alloca(size_send); 3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(cmd_send) 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *cmd_send = cmd; 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy(cmd_send + 1, data, size); 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 339e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("alloca failed at h:%d, cmd type:%d, size:%d", h, type, size_send); 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send; 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_wakeup(int h) 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 349e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 354e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("thread handle:%d, cmd socket is not created", h); 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0}; 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_exit(int h) 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 364e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 369e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("cmd socket is not created"); 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0}; 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd)) 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_join(ts[h].thread_id, 0); 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lock_slot(&thread_slot_lock); 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free_thread_slot(h); 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unlock_slot(&thread_slot_lock); 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void init_poll(int h) 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].poll_count = 0; 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].thread_id = -1; 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback = NULL; 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback = NULL; 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(i = 0; i < MAX_POLL; i++) 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].ps[i].pfd.fd = -1; 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].psi[i] = -1; 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project init_cmd_fd(h); 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline unsigned int flags2pevents(int flags) 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unsigned int pevents = 0; 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags & SOCK_THREAD_FD_WR) 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pevents |= POLLOUT; 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags & SOCK_THREAD_FD_RD) 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pevents |= POLLIN; 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pevents |= POLL_EXCEPTION_EVENTS; 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return pevents; 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void set_poll(poll_slot_t* ps, int fd, int type, int flags, uint32_t user_id) 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.fd = fd; 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->user_id = user_id; 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ps->type != 0 && ps->type != type) 413e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("poll socket type should not changed! type was:%d, type now:%d", ps->type, type); 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->type = type; 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->flags = flags; 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.events = flags2pevents(flags); 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.revents = 0; 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id) 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(fd != -1); 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int empty = -1; 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project poll_slot_t* ps = ts[h].ps; 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(i = 0; i < MAX_POLL; i++) 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ps[i].pfd.fd == fd) 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].poll_count < MAX_POLL); 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project set_poll(&ps[i], fd, type, flags | ps[i].flags, user_id); 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if(empty < 0 && ps[i].pfd.fd == -1) 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project empty = i; 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(empty >= 0) 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].poll_count < MAX_POLL); 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project set_poll(&ps[empty], fd, type, flags, user_id); 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ++ts[h].poll_count; 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 445e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("exceeded max poll slot:%d!", MAX_POLL); 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void remove_poll(int h, poll_slot_t* ps, int flags) 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags == ps->flags) 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //all monitored events signaled. To remove it, just clear the slot 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project --ts[h].poll_count; 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(ps, 0, sizeof(*ps)); 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.fd = -1; 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //one read or one write monitor event signaled, removed the accordding bit 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->flags &= ~flags; 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //update the poll events mask 4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.events = flags2pevents(ps->flags); 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int process_cmd_sock(int h) 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {-1, 0, 0, 0, 0}; 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd = ts[h].cmd_fdr; 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd)) 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 470e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("recv cmd errno:%d", errno); 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 473e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("cmd.id:%d", cmd.id); 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch(cmd.id) 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_ADD_FD: 4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id); 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_WAKEUP: 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_USER_PRIVATE: 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].cmd_callback); 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_callback) 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id); 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_EXIT: 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project default: 489e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("unknown cmd: %d", cmd.id); 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_data_sock(int h, struct pollfd *pfds, int count) 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(count <= ts[h].poll_count); 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for( i= 1; i < ts[h].poll_count; i++) 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(pfds[i].revents) 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ps_i = ts[h].psi[i]; 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(pfds[i].fd == ts[h].ps[ps_i].pfd.fd); 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t user_id = ts[h].ps[ps_i].user_id; 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int type = ts[h].ps[ps_i].type; 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int flags = 0; 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project print_events(pfds[i].revents); 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(IS_READ(pfds[i].revents)) 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags |= SOCK_THREAD_FD_RD; 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(IS_WRITE(pfds[i].revents)) 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags |= SOCK_THREAD_FD_WR; 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(IS_EXCEPTION(pfds[i].revents)) 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags |= SOCK_THREAD_FD_EXCEPTION; 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //remove the whole slot not flags 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project remove_poll(h, &ts[h].ps[ps_i], ts[h].ps[ps_i].flags); 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if(flags) 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project remove_poll(h, &ts[h].ps[ps_i], flags); //remove the monitor flags that already processed 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags) 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback(pfds[i].fd, type, flags, user_id); 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void prepare_poll_fds(int h, struct pollfd* pfds) 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int count = 0; 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ps_i = 0; 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int pfd_i = 0; 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].poll_count <= MAX_POLL); 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(pfds, 0, sizeof(pfds[0])*ts[h].poll_count); 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while(count < ts[h].poll_count) 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ps_i >= MAX_POLL) 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 541e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("exceed max poll range, ps_i:%d, MAX_POLL:%d, count:%d, ts[h].poll_count:%d", 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps_i, MAX_POLL, count, ts[h].poll_count); 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].ps[ps_i].pfd.fd >= 0) 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pfds[pfd_i] = ts[h].ps[ps_i].pfd; 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].psi[pfd_i] = ps_i; 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project count++; 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pfd_i++; 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps_i++; 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *sock_poll_thread(void *arg) 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct pollfd pfds[MAX_POLL]; 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(pfds, 0, sizeof(pfds)); 55922c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT int h = (intptr_t)arg; 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(;;) 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project prepare_poll_fds(h, pfds); 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret = poll(pfds, ts[h].poll_count, -1); 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ret == -1) 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 566e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno)); 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ret != 0) 5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int need_process_data_fd = TRUE; 5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(pfds[0].revents) //cmd fd always is the first one 5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(pfds[0].fd == ts[h].cmd_fdr); 5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(!process_cmd_sock(h)) 5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 577e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("h:%d, process_cmd_sock return false, exit...", h); 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ret == 1) 5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project need_process_data_fd = FALSE; 5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else ret--; //exclude the cmd fd 5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(need_process_data_fd) 5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project process_data_sock(h, pfds, ret); 5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 587e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else {APPL_TRACE_DEBUG("no data, select ret: %d", ret)}; 5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].thread_id = -1; 590e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("socket poll thread exiting, h:%d", h); 5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 594