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->payload) {
     59             free(request->curr->payload);
     60         }
     61         free(request->curr);
     62         free(request);
     63     }
     64 }
     65 
     66 #if defined(ANDROID_MULTI_SIM)
     67 void 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
     77 void 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 
     87 void 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 
     97 RilSapSocket *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 
    114 void 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 
    148 void 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 
    180 bool 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 
    192 RilSapSocket::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 
    201 void 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 
    234 void 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 
    272 void 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 }