blob: 92cc98c898ddde2bcf69d0752563a642ad6ecbd9 [file] [log] [blame]
Dheeraj Shetty27976c42014-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
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#define LOG_TAG "RIL_UIM_SOCKET"
25#include <utils/Log.h>
26#include <arpa/inet.h>
27
28RilSapSocket::RilSapSocketList *head;
29
30void ril_sap_on_request_complete (
31 RIL_Token t, RIL_Errno e,
32 void *response, size_t responselen
33);
34
35void ril_sap_on_unsolicited_response (
36 int unsolResponse, const void *data,
37 size_t datalen
38);
39extern "C" void
40RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
41 const struct timeval *relativeTime);
42
43struct RIL_Env RilSapSocket::uimRilEnv = {
44 .OnRequestComplete = RilSapSocket::sOnRequestComplete,
45 .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse,
46 .RequestTimedCallback = RIL_requestTimedCallback
47};
48
49void RilSapSocket::sOnRequestComplete (RIL_Token t,
50 RIL_Errno e,
51 void *response,
52 size_t responselen) {
53 RilSapSocket *sap_socket;
54 SapSocketRequest *request = (SapSocketRequest*) t;
55
56 RLOGD("Socket id:%d", request->socketId);
57
58 sap_socket = getSocketById(request->socketId);
59
60 if (sap_socket) {
61 sap_socket->onRequestComplete(t,e,response,responselen);
62 } else {
63 RLOGE("Invalid socket id");
64 free(request->curr);
65 free(request);
66 }
67}
68
69#if defined(ANDROID_MULTI_SIM)
70void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
71 const void *data,
72 size_t datalen,
73 RIL_SOCKET_ID socketId) {
74 RilSapSocket *sap_socket = getSocketById(socketId);
75 if (sap_socket) {
76 sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
77 }
78}
79#else
80void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
81 const void *data,
82 size_t datalen) {
83 RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1);
84 sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
85}
86#endif
87
88void RilSapSocket::printList() {
89 RilSapSocketList *current = head;
90 RLOGD("Printing socket list");
91 while(NULL != current) {
92 RLOGD("SocketName:%s",current->socket->name);
93 RLOGD("Socket id:%d",current->socket->id);
94 current = current->next;
95 }
96}
97
98RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) {
99 RilSapSocket *sap_socket;
100 RilSapSocketList *current = head;
101
102 RLOGD("Entered getSocketById");
103 printList();
104
105 while(NULL != current) {
106 if(socketId == current->socket->id) {
107 sap_socket = current->socket;
108 return sap_socket;
109 }
110 current = current->next;
111 }
112 return NULL;
113}
114
115void RilSapSocket::initSapSocket(const char *socketName,
116 RIL_RadioFunctions *uimFuncs) {
117
118 if (strcmp(socketName, "sap_uim_socket1") == 0) {
119 if(!SocketExists(socketName)) {
120 addSocketToList(socketName, RIL_SOCKET_1, uimFuncs);
121 }
122 }
123
124#if (SIM_COUNT >= 2)
125 if (strcmp(socketName, "sap_uim_socket2") == 0) {
126 if(!SocketExists(socketName)) {
127 addSocketToList(socketName, RIL_SOCKET_2, uimFuncs);
128 }
129 }
130#endif
131
132#if (SIM_COUNT >= 3)
133 if (strcmp(socketName, "sap_uim_socket3") == 0) {
134 if(!SocketExists(socketName)) {
135 addSocketToList(socketName, RIL_SOCKET_3, uimFuncs);
136 }
137 }
138#endif
139
140#if (SIM_COUNT >= 4)
141 if (strcmp(socketName, "sap_uim_socket4") == 0) {
142 if(!SocketExists(socketName)) {
143 addSocketToList(socketName, RIL_SOCKET_4, uimFuncs);
144 }
145 }
146#endif
147}
148
149void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid,
150 RIL_RadioFunctions *uimFuncs) {
151 RilSapSocket* socket = NULL;
152 RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList));
153 RilSapSocketList *current;
154
155 if(!SocketExists(socketName)) {
156 socket = new RilSapSocket(socketName, socketid, uimFuncs);
157 listItem->socket = socket;
158 listItem->next = NULL;
159
160 RLOGD("Adding socket with id: %d", socket->id);
161
162 if(NULL == head) {
163 head = listItem;
164 head->next = NULL;
165 }
166 else {
167 current = head;
168 while(NULL != current->next) {
169 current = current->next;
170 }
171 current->next = listItem;
172 }
173 socket->socketInit();
174 }
175}
176
177bool RilSapSocket::SocketExists(const char *socketName) {
178 RilSapSocketList* current = head;
179
180 while(NULL != current) {
181 if(strcmp(current->socket->name, socketName) == 0) {
182 return true;
183 }
184 current = current->next;
185 }
186 return false;
187}
188
189void* RilSapSocket::processRequestsLoop(void) {
190 SapSocketRequest *req = (SapSocketRequest*)malloc(sizeof(SapSocketRequest));
191 RLOGI("UIM_SOCKET:Request loop started");
192
193 while(true) {
194 req = dispatchQueue.dequeue();
195
196 RLOGI("New request from the dispatch Queue");
197
198 if (req != NULL) {
199 processRequest(req->curr);
200 free(req);
201 } else {
202 RLOGE("Fetched null buffer from queue!");
203 }
204 }
205 return NULL;
206}
207
208RilSapSocket::RilSapSocket(const char *socketName,
209 RIL_SOCKET_ID socketId,
210 RIL_RadioFunctions *inputUimFuncs):
211 RilSocket(socketName, socketId) {
212 if (inputUimFuncs) {
213 uimFuncs = inputUimFuncs;
214 }
215}
216
217int RilSapSocket::processRequest(MsgHeader *request) {
218 dispatchRequest(request);
219 return 0;
220}
221
222#define BYTES_PER_LINE 16
223
224#define NIBBLE_TO_HEX(n) ({ \
225 uint8_t __n = (uint8_t) n & 0x0f; \
226 __nibble >= 10 ? 'A' + __n - 10: '0' + __n; \
227})
228
229#define HEX_HIGH(b) ({ \
230 uint8_t __b = (uint8_t) b; \
231 uint8_t __nibble = (__b >> 4) & 0x0f; \
232 NIBBLE_TO_HEX(__nibble); \
233})
234
235#define HEX_LOW(b) ({ \
236 uint8_t __b = (uint8_t) b; \
237 uint8_t __nibble = __b & 0x0f; \
238 NIBBLE_TO_HEX(__nibble); \
239})
240
241void log_hex(const char *who, const uint8_t *buffer, int length) {
242 char out[80];
243 int source = 0;
244 int dest = 0;
245 int dest_len = sizeof(out);
246 int per_line = 0;
247
248 do {
249 dest += sprintf(out, "%8.8s [%8.8x] ", who, source);
250 for(; source < length && dest_len - dest > 3 && per_line < BYTES_PER_LINE; source++,
251 per_line ++) {
252 out[dest++] = HEX_HIGH(buffer[source]);
253 out[dest++] = HEX_LOW(buffer[source]);
254 out[dest++] = ' ';
255 }
256 if (dest < dest_len && (per_line == BYTES_PER_LINE || source >= length)) {
257 out[dest++] = 0;
258 per_line = 0;
259 dest = 0;
260 RLOGD("%s\n", out);
261 }
262 } while(source < length && dest < dest_len);
263}
264
265void RilSapSocket::dispatchRequest(MsgHeader *req) {
266 SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
267 currRequest->token = req->token;
268 currRequest->curr = req;
269 currRequest->p_next = NULL;
270 currRequest->socketId = id;
271
272 pendingResponseQueue.enqueue(currRequest);
273
274 if (uimFuncs) {
275 RLOGI("[%d] > SAP REQUEST type: %d. id: %d. error: %d",
276 req->token,
277 req->type,
278 req->id,
279 req->error );
280
281#if defined(ANDROID_MULTI_SIM)
282 uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
283#else
284 uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
285#endif
286 }
287}
288
289void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
290 size_t response_len) {
291 SapSocketRequest* request= (SapSocketRequest*)t;
292 MsgHeader *hdr = request->curr;
293 pb_bytes_array_t *payload = (pb_bytes_array_t *)
294 calloc(1,sizeof(pb_bytes_array_t) + response_len);
295
296 if (hdr && payload) {
297 memcpy(payload->bytes, response, response_len);
298 payload->size = response_len;
299 hdr->payload = payload;
300 hdr->type = MsgType_RESPONSE;
301 hdr->error = (Error) e;
302
303 RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
304
305 if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) {
306 RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
307 RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id");
308 return;
309 }
310
311 sendResponse(hdr);
312 free(hdr);
313 }
314}
315
316void RilSapSocket::sendResponse(MsgHeader* hdr) {
317 size_t encoded_size = 0;
318 uint32_t written_size;
319 size_t buffer_size = 0;
320 pb_ostream_t ostream;
321 bool success = false;
322
323 pthread_mutex_lock(&write_lock);
324
325 if ((success = pb_get_encoded_size(&encoded_size, MsgHeader_fields,
326 hdr)) && encoded_size <= INT32_MAX && commandFd != -1) {
327 buffer_size = encoded_size + sizeof(uint32_t);
328 uint8_t buffer[buffer_size];
329 written_size = htonl((uint32_t) encoded_size);
330 ostream = pb_ostream_from_buffer(buffer, buffer_size);
331 pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size));
332 success = pb_encode(&ostream, MsgHeader_fields, hdr);
333
334 if (success) {
335 RLOGD("Size: %d (0x%x) Size as written: 0x%x", encoded_size, encoded_size,
336 written_size);
337 log_hex("onRequestComplete", &buffer[sizeof(written_size)], encoded_size);
338 RLOGI("[%d] < SAP RESPONSE type: %d. id: %d. error: %d",
339 hdr->token, hdr->type, hdr->id,hdr->error );
340
341 if ( 0 != blockingWrite_helper(commandFd, buffer, buffer_size)) {
342 RLOGE("Error %d while writing to fd", errno);
343 } else {
344 RLOGD("Write successful");
345 }
346 } else {
347 RLOGE("Error while encoding response of type %d id %d buffer_size: %d: %s.",
348 hdr->type, hdr->id, buffer_size, PB_GET_ERROR(&ostream));
349 }
350 } else {
351 RLOGE("Not sending response type %d: encoded_size: %u. commandFd: %d. encoded size result: %d",
352 hdr->type, encoded_size, commandFd, success);
353 }
354
355 pthread_mutex_unlock(&write_lock);
356}
357
358void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) {
359 MsgHeader *hdr = new MsgHeader;
360 pb_bytes_array_t *payload = (pb_bytes_array_t *)
361 calloc(1, sizeof(pb_bytes_array_t) + datalen);
362 if (hdr && payload) {
363 memcpy(payload->bytes, data, datalen);
364 payload->size = datalen;
365 hdr->payload = payload;
366 hdr->type = MsgType_UNSOL_RESPONSE;
367 hdr->id = (MsgId)unsolResponse;
368 hdr->error = Error_RIL_E_SUCCESS;
369 sendResponse(hdr);
370 delete hdr;
371 }
372}
373
374void RilSapSocket::pushRecord(void *p_record, size_t recordlen) {
375 int ret;
376 SapSocketRequest *recv = (SapSocketRequest*)malloc(sizeof(SapSocketRequest));
377 MsgHeader *reqHeader;
378 pb_istream_t stream;
379
380 stream = pb_istream_from_buffer((uint8_t *)p_record, recordlen);
381 reqHeader = (MsgHeader *)malloc(sizeof (MsgHeader));
382 memset(reqHeader, 0, sizeof(MsgHeader));
383
384 log_hex("BtSapTest-Payload", (const uint8_t*)p_record, recordlen);
385
386 if (!pb_decode(&stream, MsgHeader_fields, reqHeader) ) {
387 RLOGE("Error decoding protobuf buffer : %s", PB_GET_ERROR(&stream));
388 } else {
389 recv->token = reqHeader->token;
390 recv->curr = reqHeader;
391 recv->socketId = id;
392
393 dispatchQueue.enqueue(recv);
394 }
395}
396
397void RilSapSocket::sendDisconnect() {
398 MsgHeader *hdr = new MsgHeader;
399 pb_bytes_array_t *payload ;
400 size_t encoded_size = 0;
401 uint32_t written_size;
402 size_t buffer_size = 0;
403 pb_ostream_t ostream;
404 bool success = false;
405 ssize_t written_bytes;
406
407 RIL_SIM_SAP_DISCONNECT_REQ disconnectReq;
408
409 if ((success = pb_get_encoded_size(&encoded_size, RIL_SIM_SAP_DISCONNECT_REQ_fields,
410 &disconnectReq)) && encoded_size <= INT32_MAX) {
411 buffer_size = encoded_size + sizeof(uint32_t);
412 uint8_t buffer[buffer_size];
413 written_size = htonl((uint32_t) encoded_size);
414 ostream = pb_ostream_from_buffer(buffer, buffer_size);
415 pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size));
416 success = pb_encode(&ostream, RIL_SIM_SAP_DISCONNECT_REQ_fields, buffer);
417
418 if(success) {
419 pb_bytes_array_t *payload = (pb_bytes_array_t *)
420 calloc(1,sizeof(pb_bytes_array_t) + written_size);
421
422 memcpy(payload->bytes, buffer, written_size);
423 payload->size = written_size;
424 hdr->payload = payload;
425 hdr->type = MsgType_REQUEST;
426 hdr->id = MsgId_RIL_SIM_SAP_DISCONNECT;
427 hdr->error = Error_RIL_E_SUCCESS;
428 dispatchDisconnect(hdr);
429 }
430 else {
431 RLOGE("Encode failed in send disconnect!");
432 delete hdr;
433 free(payload);
434 }
435 }
436}
437
438void RilSapSocket::dispatchDisconnect(MsgHeader *req) {
439 SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
440 currRequest->token = -1;
441 currRequest->curr = req;
442 currRequest->p_next = NULL;
443 currRequest->socketId = (RIL_SOCKET_ID)99;
444
445 RLOGD("Sending disconnect on command close!");
446
447#if defined(ANDROID_MULTI_SIM)
448 uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
449#else
450 uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
451#endif
452}
453
454void RilSapSocket::onCommandsSocketClosed() {
455 sendDisconnect();
456 RLOGE("Socket command closed");
457}