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 #include <stdint.h>
18 #define RIL_SHLIB
19 #include "RilSapSocket.h"
20 #include "pb_decode.h"
21 #include "pb_encode.h"
22 #undef LOG_TAG
23 #define LOG_TAG "RIL_UIM_SOCKET"
24 #include <utils/Log.h>
25 #include <arpa/inet.h>
26 #include <errno.h>
27 #include <sap_service.h>
28 #include <guest/hals/ril/reference-libril/ril.h>
29 
30 static RilSapSocket::RilSapSocketList *head = NULL;
31 
32 extern "C" void
33 RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
34         const struct timeval *relativeTime);
35 
36 struct RIL_Env RilSapSocket::uimRilEnv = {
37         .OnRequestComplete = RilSapSocket::sOnRequestComplete,
38         .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse,
39         .RequestTimedCallback = RIL_requestTimedCallback
40 };
41 
sOnRequestComplete(RIL_Token t,RIL_Errno e,void * response,size_t responselen)42 void RilSapSocket::sOnRequestComplete (RIL_Token t,
43         RIL_Errno e,
44         void *response,
45         size_t responselen) {
46     RilSapSocket *sap_socket;
47     SapSocketRequest *request = (SapSocketRequest*) t;
48 
49     RLOGD("Socket id:%d", request->socketId);
50 
51     sap_socket = getSocketById(request->socketId);
52 
53     if (sap_socket) {
54         sap_socket->onRequestComplete(t,e,response,responselen);
55     } else {
56         RLOGE("Invalid socket id");
57         if (request->curr) {
58             free(request->curr);
59         }
60         free(request);
61     }
62 }
63 
64 #if defined(ANDROID_MULTI_SIM)
sOnUnsolicitedResponse(int unsolResponse,const void * data,size_t datalen,RIL_SOCKET_ID socketId)65 void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
66         const void *data,
67         size_t datalen,
68         RIL_SOCKET_ID socketId) {
69     RilSapSocket *sap_socket = getSocketById(socketId);
70     if (sap_socket) {
71         sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
72     }
73 }
74 #else
sOnUnsolicitedResponse(int unsolResponse,const void * data,size_t datalen)75 void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
76        const void *data,
77        size_t datalen) {
78     RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1);
79     if(sap_socket){
80         sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
81     }
82 }
83 #endif
84 
printList()85 void RilSapSocket::printList() {
86     RilSapSocketList *current = head;
87     RLOGD("Printing socket list");
88     while(NULL != current) {
89         RLOGD("SocketName:%s",current->socket->name);
90         RLOGD("Socket id:%d",current->socket->id);
91         current = current->next;
92     }
93 }
94 
getSocketById(RIL_SOCKET_ID socketId)95 RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) {
96     RilSapSocket *sap_socket;
97     RilSapSocketList *current = head;
98 
99     RLOGD("Entered getSocketById");
100     printList();
101 
102     while(NULL != current) {
103         if(socketId == current->socket->id) {
104             sap_socket = current->socket;
105             return sap_socket;
106         }
107         current = current->next;
108     }
109     return NULL;
110 }
111 
initSapSocket(const char * socketName,const RIL_RadioFunctions * uimFuncs)112 void RilSapSocket::initSapSocket(const char *socketName,
113         const RIL_RadioFunctions *uimFuncs) {
114 
115     if (strcmp(socketName, RIL1_SERVICE_NAME) == 0) {
116         if(!SocketExists(socketName)) {
117             addSocketToList(socketName, RIL_SOCKET_1, uimFuncs);
118         }
119     }
120 
121 #if (SIM_COUNT >= 2)
122     if (strcmp(socketName, RIL2_SERVICE_NAME) == 0) {
123         if(!SocketExists(socketName)) {
124             addSocketToList(socketName, RIL_SOCKET_2, uimFuncs);
125         }
126     }
127 #endif
128 
129 #if (SIM_COUNT >= 3)
130     if (strcmp(socketName, RIL3_SERVICE_NAME) == 0) {
131         if(!SocketExists(socketName)) {
132             addSocketToList(socketName, RIL_SOCKET_3, uimFuncs);
133         }
134     }
135 #endif
136 
137 #if (SIM_COUNT >= 4)
138     if (strcmp(socketName, RIL4_SERVICE_NAME) == 0) {
139         if(!SocketExists(socketName)) {
140             addSocketToList(socketName, RIL_SOCKET_4, uimFuncs);
141         }
142     }
143 #endif
144 }
145 
addSocketToList(const char * socketName,RIL_SOCKET_ID socketid,const RIL_RadioFunctions * uimFuncs)146 void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid,
147         const RIL_RadioFunctions *uimFuncs) {
148     RilSapSocket* socket = NULL;
149     RilSapSocketList *current;
150 
151     if(!SocketExists(socketName)) {
152         socket = new RilSapSocket(socketName, socketid, uimFuncs);
153         RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList));
154         if (!listItem) {
155             RLOGE("addSocketToList: OOM");
156             delete socket;
157             return;
158         }
159         listItem->socket = socket;
160         listItem->next = NULL;
161 
162         RLOGD("Adding socket with id: %d", socket->id);
163 
164         if(NULL == head) {
165             head = listItem;
166             head->next = NULL;
167         }
168         else {
169             current = head;
170             while(NULL != current->next) {
171                 current = current->next;
172             }
173             current->next = listItem;
174         }
175     }
176 }
177 
SocketExists(const char * socketName)178 bool RilSapSocket::SocketExists(const char *socketName) {
179     RilSapSocketList* current = head;
180 
181     while(NULL != current) {
182         if(strcmp(current->socket->name, socketName) == 0) {
183             return true;
184         }
185         current = current->next;
186     }
187     return false;
188 }
189 
RilSapSocket(const char * socketName,RIL_SOCKET_ID socketId,const RIL_RadioFunctions * inputUimFuncs)190 RilSapSocket::RilSapSocket(const char *socketName,
191         RIL_SOCKET_ID socketId,
192         const RIL_RadioFunctions *inputUimFuncs):
193         RilSocket(socketName, socketId) {
194     if (inputUimFuncs) {
195         uimFuncs = inputUimFuncs;
196     }
197 }
198 
dispatchRequest(MsgHeader * req)199 void RilSapSocket::dispatchRequest(MsgHeader *req) {
200     // SapSocketRequest will be deallocated in onRequestComplete()
201     SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
202     if (!currRequest) {
203         RLOGE("dispatchRequest: OOM");
204         // Free MsgHeader allocated in pushRecord()
205         free(req);
206         return;
207     }
208     currRequest->token = req->token;
209     currRequest->curr = req;
210     currRequest->p_next = NULL;
211     currRequest->socketId = id;
212 
213     pendingResponseQueue.enqueue(currRequest);
214 
215     if (uimFuncs) {
216         RLOGI("RilSapSocket::dispatchRequest [%d] > SAP REQUEST type: %d. id: %d. error: %d, \
217                 token 0x%p",
218                 req->token,
219                 req->type,
220                 req->id,
221                 req->error,
222                 currRequest );
223 
224 #if defined(ANDROID_MULTI_SIM)
225         uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
226 #else
227         uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
228 #endif
229     }
230 }
231 
onRequestComplete(RIL_Token t,RIL_Errno e,void * response,size_t response_len)232 void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
233         size_t response_len) {
234     SapSocketRequest* request= (SapSocketRequest*)t;
235 
236     if (!request || !request->curr) {
237         RLOGE("RilSapSocket::onRequestComplete: request/request->curr is NULL");
238         return;
239     }
240 
241     MsgHeader *hdr = request->curr;
242 
243     MsgHeader rsp;
244     rsp.token = request->curr->token;
245     rsp.type = MsgType_RESPONSE;
246     rsp.id = request->curr->id;
247     rsp.error = (Error)e;
248     rsp.payload = (pb_bytes_array_t *)calloc(1, sizeof(pb_bytes_array_t) + response_len);
249     if (!rsp.payload) {
250         RLOGE("onRequestComplete: OOM");
251     } else {
252         if (response && response_len > 0) {
253             memcpy(rsp.payload->bytes, response, response_len);
254             rsp.payload->size = response_len;
255         } else {
256             rsp.payload->size = 0;
257         }
258 
259         RLOGE("RilSapSocket::onRequestComplete: Token:%d, MessageId:%d ril token 0x%p",
260                 hdr->token, hdr->id, t);
261 
262         sap::processResponse(&rsp, this);
263         free(rsp.payload);
264     }
265 
266     // Deallocate SapSocketRequest
267     if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) {
268         RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
269         RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id");
270     }
271 
272     // Deallocate MsgHeader
273     free(hdr);
274 }
275 
onUnsolicitedResponse(int unsolResponse,void * data,size_t datalen)276 void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) {
277     if (data && datalen > 0) {
278         pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1,
279                 sizeof(pb_bytes_array_t) + datalen);
280         if (!payload) {
281             RLOGE("onUnsolicitedResponse: OOM");
282             return;
283         }
284         memcpy(payload->bytes, data, datalen);
285         payload->size = datalen;
286         MsgHeader rsp;
287         rsp.payload = payload;
288         rsp.type = MsgType_UNSOL_RESPONSE;
289         rsp.id = (MsgId)unsolResponse;
290         rsp.error = Error_RIL_E_SUCCESS;
291         sap::processUnsolResponse(&rsp, this);
292         free(payload);
293     }
294 }
295