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