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