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 
socketInit(void)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 
sSocketListener(int fd,short flags,void * param)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 
onNewCommandConnect()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 
sSocketRequestsHandler(int fd,short flags,void * param)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 
socketRequestsHandler(int fd,short flags,RecordStream * p_rs)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 
setListenFd(int fd)124 void RilSocket::setListenFd(int fd) {
125     listenFd = fd;
126 }
127 
setCommandFd(int fd)128 void RilSocket::setCommandFd(int fd) {
129     commandFd = fd;
130 }
131 
getListenFd(void)132 int RilSocket::getListenFd(void) {
133     return listenFd;
134 }
135 
getCommandFd(void)136 int RilSocket::getCommandFd(void) {
137     return commandFd;
138 }
139 
setListenCb(ril_event_cb cb)140 void RilSocket::setListenCb(ril_event_cb cb) {
141     listenCb = cb;
142 }
143 
setCommandCb(ril_event_cb cb)144 void RilSocket::setCommandCb(ril_event_cb cb) {
145     commandCb = cb;
146 }
147 
getListenCb(void)148 ril_event_cb RilSocket::getListenCb(void) {
149     return listenCb;
150 }
151 
getCommandCb(void)152 ril_event_cb RilSocket::getCommandCb(void) {
153     return commandCb;
154 }
155 
setListenEvent(ril_event event)156 void RilSocket::setListenEvent(ril_event event) {
157     listenEvent = event;
158 }
159 
setCallbackEvent(ril_event event)160 void RilSocket::setCallbackEvent(ril_event event) {
161     callbackEvent = event;
162 }
163 
getListenEvent(void)164 ril_event* RilSocket::getListenEvent(void)  {
165     return &listenEvent;
166 }
167 
getCallbackEvent(void)168 ril_event* RilSocket::getCallbackEvent(void) {
169     return &callbackEvent;
170 }
171 
172 extern "C"
ril_socket_process_requests_loop(void * arg)173 void *ril_socket_process_requests_loop(void *arg) {
174     RilSocket *socket = (RilSocket *)arg;
175     socket->processRequestsLoop();
176     return NULL;
177 }
178