1168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat/* 2168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Copyright (C) 2008 The Android Open Source Project 3168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 4168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * you may not use this file except in compliance with the License. 6168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * You may obtain a copy of the License at 7168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 8168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 10168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Unless required by applicable law or agreed to in writing, software 11168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * See the License for the specific language governing permissions and 14168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * limitations under the License. 15168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat */ 16168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdio.h> 17168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <errno.h> 18168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdlib.h> 19168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/socket.h> 20168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/select.h> 21168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/time.h> 22168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/types.h> 23168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/un.h> 24168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 25168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#define LOG_TAG "SocketListener" 26168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/log.h> 27168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/sockets.h> 28168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 29168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sysutils/SocketListener.h> 30fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <sysutils/SocketClient.h> 31168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 32fa644ffe944c01a9b00f8d7676d58394fabee285San MehatSocketListener::SocketListener(const char *socketName, bool listen) { 33fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mListen = listen; 34168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName = socketName; 35168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = -1; 36fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_init(&mClientsLock, NULL); 37fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients = new SocketClientCollection(); 38168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 39168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 40fa644ffe944c01a9b00f8d7676d58394fabee285San MehatSocketListener::SocketListener(int socketFd, bool listen) { 41fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mListen = listen; 42168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName = NULL; 43168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = socketFd; 44fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_init(&mClientsLock, NULL); 45fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients = new SocketClientCollection(); 46168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 47168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 48c4a895b7094461c98101924cf096680bfb7856f1San MehatSocketListener::~SocketListener() { 49c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mSocketName && mSock > -1) 50c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mSock); 51c4a895b7094461c98101924cf096680bfb7856f1San Mehat 52c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mCtrlPipe[0] != -1) { 53c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mCtrlPipe[0]); 54c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mCtrlPipe[1]); 55c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 56c4a895b7094461c98101924cf096680bfb7856f1San Mehat SocketClientCollection::iterator it; 57c4a895b7094461c98101924cf096680bfb7856f1San Mehat for (it = mClients->begin(); it != mClients->end(); ++it) { 58c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete (*it); 59c4a895b7094461c98101924cf096680bfb7856f1San Mehat it = mClients->erase(it); 60c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 61c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete mClients; 62c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 63c4a895b7094461c98101924cf096680bfb7856f1San Mehat 64fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatint SocketListener::startListener() { 65168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 66168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (!mSocketName && mSock == -1) { 677e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Failed to start unbound listener"); 68168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat errno = EINVAL; 69168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 70168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (mSocketName) { 71168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((mSock = android_get_control_socket(mSocketName)) < 0) { 727e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Obtaining file descriptor socket '%s' failed: %s", 73168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName, strerror(errno)); 74168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 75168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 76168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 77168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 78fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen && listen(mSock, 4) < 0) { 797e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Unable to listen on socket (%s)", strerror(errno)); 80fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 81df6c1b91e3813886070f35929583c30cfaead918San Mehat } else if (!mListen) 82fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients->push_back(new SocketClient(mSock)); 83168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 84c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (pipe(mCtrlPipe)) { 857e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("pipe failed (%s)", strerror(errno)); 86fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 87c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 88fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 89c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) { 907e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("pthread_create (%s)", strerror(errno)); 91fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 92c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 93fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 94fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return 0; 95fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 96fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 97fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatint SocketListener::stopListener() { 98fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat char c = 0; 99fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 100fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (write(mCtrlPipe[1], &c, 1) != 1) { 1017e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Error writing to control pipe (%s)", strerror(errno)); 102fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 103fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 104fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 105fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat void *ret; 106fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (pthread_join(mThread, &ret)) { 1077e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Error joining to listener thread (%s)", strerror(errno)); 108fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 109fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 110dbdb0db516fa4935ff7b5c05914932099237d808San Mehat close(mCtrlPipe[0]); 111dbdb0db516fa4935ff7b5c05914932099237d808San Mehat close(mCtrlPipe[1]); 112c4a895b7094461c98101924cf096680bfb7856f1San Mehat mCtrlPipe[0] = -1; 113c4a895b7094461c98101924cf096680bfb7856f1San Mehat mCtrlPipe[1] = -1; 114c4a895b7094461c98101924cf096680bfb7856f1San Mehat 115c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mSocketName && mSock > -1) { 116c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mSock); 117c4a895b7094461c98101924cf096680bfb7856f1San Mehat mSock = -1; 118c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 119c4a895b7094461c98101924cf096680bfb7856f1San Mehat 120c4a895b7094461c98101924cf096680bfb7856f1San Mehat SocketClientCollection::iterator it; 121c4a895b7094461c98101924cf096680bfb7856f1San Mehat for (it = mClients->begin(); it != mClients->end(); ++it) { 122c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete (*it); 123c4a895b7094461c98101924cf096680bfb7856f1San Mehat it = mClients->erase(it); 124c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 125fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return 0; 126fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 127fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 128fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatvoid *SocketListener::threadStart(void *obj) { 129fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketListener *me = reinterpret_cast<SocketListener *>(obj); 130fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 131fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat me->runListener(); 132fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_exit(NULL); 133fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return NULL; 134fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 135fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 136fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatvoid SocketListener::runListener() { 137fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 138168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat while(1) { 139fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator it; 140168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat fd_set read_fds; 141168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int rc = 0; 142fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat int max = 0; 143fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 144168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat FD_ZERO(&read_fds); 145168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 146fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen) { 147168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat max = mSock; 148fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET(mSock, &read_fds); 149168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 150168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 151fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET(mCtrlPipe[0], &read_fds); 152fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mCtrlPipe[0] > max) 153fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat max = mCtrlPipe[0]; 154fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 155fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 156fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (it = mClients->begin(); it != mClients->end(); ++it) { 157fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET((*it)->getSocket(), &read_fds); 158fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if ((*it)->getSocket() > max) 159fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat max = (*it)->getSocket(); 160fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 161fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 16203f0d27f6c49530a91402ed42f8ca4b2fda04b9fSan Mehat 163df6c1b91e3813886070f35929583c30cfaead918San Mehat if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) { 1647e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("select failed (%s)", strerror(errno)); 165fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat sleep(1); 166168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat continue; 167df6c1b91e3813886070f35929583c30cfaead918San Mehat } else if (!rc) 168fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 169fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 170dbdb0db516fa4935ff7b5c05914932099237d808San Mehat if (FD_ISSET(mCtrlPipe[0], &read_fds)) 171fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat break; 172fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen && FD_ISSET(mSock, &read_fds)) { 173fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat struct sockaddr addr; 174fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat socklen_t alen = sizeof(addr); 175fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat int c; 176fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 177fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if ((c = accept(mSock, &addr, &alen)) < 0) { 1787e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("accept failed (%s)", strerror(errno)); 179fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat sleep(1); 180fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 181168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 182fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 183fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients->push_back(new SocketClient(c)); 184fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 185fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 186fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 187fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat do { 188fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 189fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (it = mClients->begin(); it != mClients->end(); ++it) { 190fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat int fd = (*it)->getSocket(); 191fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (FD_ISSET(fd, &read_fds)) { 192fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 193fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (!onDataAvailable(*it)) { 194fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat close(fd); 195fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 196fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat delete *it; 197fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat it = mClients->erase(it); 198fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 199fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 200fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_CLR(fd, &read_fds); 201fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 202fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 203168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 204fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 205fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } while (0); 206168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 207168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 208168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 209db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) { 210fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 211fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator i; 212fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 213fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (i = mClients->begin(); i != mClients->end(); ++i) { 214d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat if ((*i)->sendMsg(code, msg, addErrno)) { 2157e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGW("Error sending broadcast (%s)", strerror(errno)); 216fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 217fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 218fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 219fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 220fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 221db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(const char *msg) { 222fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 223fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator i; 224fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 225fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (i = mClients->begin(); i != mClients->end(); ++i) { 226d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat if ((*i)->sendMsg(msg)) { 2277e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGW("Error sending broadcast (%s)", strerror(errno)); 228fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 229fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 230fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 231168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 232