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}