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