Home | History | Annotate | Download | only in libril
      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 
     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)
     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
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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