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