1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 extern "C" 18 void *ril_socket_process_requests_loop(void *arg); 19 20 #include "RilSocket.h" 21 #include <cutils/sockets.h> 22 #include <utils/Log.h> 23 #include <assert.h> 24 #define SOCKET_LISTEN_BACKLOG 0 25 26 int RilSocket::socketInit(void) { 27 int ret; 28 29 listenCb = &RilSocket::sSocketListener; 30 commandCb = &RilSocket::sSocketRequestsHandler; 31 listenFd = android_get_control_socket(name); 32 33 //Start listening 34 ret = listen(listenFd, SOCKET_LISTEN_BACKLOG); 35 36 if (ret < 0) { 37 RLOGE("Failed to listen on %s socket '%d': %s", 38 name, listenFd, strerror(errno)); 39 return ret; 40 } 41 //Add listen event to the event loop 42 ril_event_set(&listenEvent, listenFd, false, listenCb, this); 43 rilEventAddWakeup_helper(&listenEvent); 44 return ret; 45 } 46 47 void RilSocket::sSocketListener(int fd, short flags, void *param) { 48 RilSocket *theSocket = (RilSocket *) param; 49 MySocketListenParam listenParam; 50 listenParam.socket = theSocket; 51 listenParam.sListenParam.type = RIL_SAP_SOCKET; 52 53 listenCallback_helper(fd, flags, (void*)&listenParam); 54 } 55 56 void RilSocket::onNewCommandConnect() { 57 pthread_attr_t attr; 58 PthreadPtr pptr = ril_socket_process_requests_loop; 59 int result; 60 61 pthread_attr_init(&attr); 62 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 63 64 //Start socket request processing loop thread 65 result = pthread_create(&socketThreadId, &attr, pptr, this); 66 if(result < 0) { 67 RLOGE("pthread_create failed with result:%d",result); 68 } 69 70 RLOGE("New socket command connected and socket request thread started"); 71 } 72 73 void RilSocket::sSocketRequestsHandler(int fd, short flags, void *param) { 74 socketClient *sc = (socketClient *) param; 75 RilSocket *theSocket = sc->socketPtr; 76 RecordStream *rs = sc->rs; 77 78 theSocket->socketRequestsHandler(fd, flags, rs); 79 } 80 81 void RilSocket::socketRequestsHandler(int fd, short flags, RecordStream *p_rs) { 82 int ret; 83 assert(fd == commandFd); 84 void *p_record; 85 size_t recordlen; 86 87 for (;;) { 88 /* loop until EAGAIN/EINTR, end of stream, or other error */ 89 ret = record_stream_get_next(p_rs, &p_record, &recordlen); 90 91 if (ret == 0 && p_record == NULL) { 92 /* end-of-stream */ 93 break; 94 } else if (ret < 0) { 95 break; 96 } else if (ret == 0) { 97 pushRecord(p_record, recordlen); 98 } 99 } 100 101 if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) { 102 /* fatal error or end-of-stream */ 103 if (ret != 0) { 104 RLOGE("error on reading command socket errno:%d\n", errno); 105 } else { 106 RLOGW("EOS. Closing command socket."); 107 } 108 109 close(commandFd); 110 commandFd = -1; 111 112 ril_event_del(&callbackEvent); 113 114 record_stream_free(p_rs); 115 116 /* start listening for new connections again */ 117 118 rilEventAddWakeup_helper(&listenEvent); 119 120 onCommandsSocketClosed(); 121 } 122 } 123 124 void RilSocket::setListenFd(int fd) { 125 listenFd = fd; 126 } 127 128 void RilSocket::setCommandFd(int fd) { 129 commandFd = fd; 130 } 131 132 int RilSocket::getListenFd(void) { 133 return listenFd; 134 } 135 136 int RilSocket::getCommandFd(void) { 137 return commandFd; 138 } 139 140 void RilSocket::setListenCb(ril_event_cb cb) { 141 listenCb = cb; 142 } 143 144 void RilSocket::setCommandCb(ril_event_cb cb) { 145 commandCb = cb; 146 } 147 148 ril_event_cb RilSocket::getListenCb(void) { 149 return listenCb; 150 } 151 152 ril_event_cb RilSocket::getCommandCb(void) { 153 return commandCb; 154 } 155 156 void RilSocket::setListenEvent(ril_event event) { 157 listenEvent = event; 158 } 159 160 void RilSocket::setCallbackEvent(ril_event event) { 161 callbackEvent = event; 162 } 163 164 ril_event* RilSocket::getListenEvent(void) { 165 return &listenEvent; 166 } 167 168 ril_event* RilSocket::getCallbackEvent(void) { 169 return &callbackEvent; 170 } 171 172 extern "C" 173 void *ril_socket_process_requests_loop(void *arg) { 174 RilSocket *socket = (RilSocket *)arg; 175 socket->processRequestsLoop(); 176 return NULL; 177 } 178