blob: a002d94038b8fc22af11cfd8eb54a9d09faf9ff1 [file] [log] [blame]
Dheeraj Shettycc231012014-07-02 21:27:57 +02001/*
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
17extern "C"
18void *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
26int 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
47void 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
56void 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
73void 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
81void 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
124void RilSocket::setListenFd(int fd) {
125 listenFd = fd;
126}
127
128void RilSocket::setCommandFd(int fd) {
129 commandFd = fd;
130}
131
132int RilSocket::getListenFd(void) {
133 return listenFd;
134}
135
136int RilSocket::getCommandFd(void) {
137 return commandFd;
138}
139
140void RilSocket::setListenCb(ril_event_cb cb) {
141 listenCb = cb;
142}
143
144void RilSocket::setCommandCb(ril_event_cb cb) {
145 commandCb = cb;
146}
147
148ril_event_cb RilSocket::getListenCb(void) {
149 return listenCb;
150}
151
152ril_event_cb RilSocket::getCommandCb(void) {
153 return commandCb;
154}
155
156void RilSocket::setListenEvent(ril_event event) {
157 listenEvent = event;
158}
159
160void RilSocket::setCallbackEvent(ril_event event) {
161 callbackEvent = event;
162}
163
164ril_event* RilSocket::getListenEvent(void) {
165 return &listenEvent;
166}
167
168ril_event* RilSocket::getCallbackEvent(void) {
169 return &callbackEvent;
170}
171
172extern "C"
173void *ril_socket_process_requests_loop(void *arg) {
174 RilSocket *socket = (RilSocket *)arg;
175 socket->processRequestsLoop();
176 return NULL;
177}