127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty/*
227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* Copyright (C) 2014 The Android Open Source Project
327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty*
427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* Licensed under the Apache License, Version 2.0 (the "License");
527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* you may not use this file except in compliance with the License.
627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* You may obtain a copy of the License at
727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty*
827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty*     http://www.apache.org/licenses/LICENSE-2.0
927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty*
1027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* Unless required by applicable law or agreed to in writing, software
1127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* distributed under the License is distributed on an "AS IS" BASIS,
1227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* See the License for the specific language governing permissions and
1427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty* limitations under the License.
1527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty*/
1627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
1727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define __STDC_LIMIT_MACROS
1827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include <stdint.h>
1927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define RIL_SHLIB
2027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include "telephony/ril.h"
2127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include "RilSapSocket.h"
2227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include "pb_decode.h"
2327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include "pb_encode.h"
24f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe#undef LOG_TAG
2527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define LOG_TAG "RIL_UIM_SOCKET"
2627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include <utils/Log.h>
2727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#include <arpa/inet.h>
281b1ec2dc592aa12d4bb5a3755658f1bbfcd1b171Vinit Deshpande#include <errno.h>
2927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
30d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiakstatic RilSapSocket::RilSapSocketList *head = NULL;
3127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
3227976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid ril_sap_on_request_complete (
3327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_Token t, RIL_Errno e,
3427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        void *response, size_t responselen
3527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty);
3627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
3727976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid ril_sap_on_unsolicited_response (
3827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        int unsolResponse, const void *data,
3927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        size_t datalen
4027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty);
4127976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyextern "C" void
4227976c479473bb772703fe4caa100e535e635e84Dheeraj ShettyRIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
4327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        const struct timeval *relativeTime);
4427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
4527976c479473bb772703fe4caa100e535e635e84Dheeraj Shettystruct RIL_Env RilSapSocket::uimRilEnv = {
4627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        .OnRequestComplete = RilSapSocket::sOnRequestComplete,
4727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse,
4827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        .RequestTimedCallback = RIL_requestTimedCallback
4927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty};
5027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
5127976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::sOnRequestComplete (RIL_Token t,
5227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_Errno e,
5327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        void *response,
5427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        size_t responselen) {
5527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocket *sap_socket;
5627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    SapSocketRequest *request = (SapSocketRequest*) t;
5727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
5827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RLOGD("Socket id:%d", request->socketId);
5927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
6027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    sap_socket = getSocketById(request->socketId);
6127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
6227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (sap_socket) {
6327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        sap_socket->onRequestComplete(t,e,response,responselen);
6427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    } else {
6527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGE("Invalid socket id");
66d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        if (request->curr->payload) {
67d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            free(request->curr->payload);
68d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        }
6927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        free(request->curr);
7027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        free(request);
7127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
7227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
7327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
7427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#if defined(ANDROID_MULTI_SIM)
7527976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
7627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        const void *data,
7727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        size_t datalen,
7827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_SOCKET_ID socketId) {
7927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocket *sap_socket = getSocketById(socketId);
8027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (sap_socket) {
8127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
8227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
8327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
8427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#else
8527976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
8627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty       const void *data,
8727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty       size_t datalen) {
8827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1);
8927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
9027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
9127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#endif
9227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
9327976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::printList() {
9427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocketList *current = head;
9527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RLOGD("Printing socket list");
9627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    while(NULL != current) {
9727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGD("SocketName:%s",current->socket->name);
9827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGD("Socket id:%d",current->socket->id);
9927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        current = current->next;
10027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
10127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
10227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
10327976c479473bb772703fe4caa100e535e635e84Dheeraj ShettyRilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) {
10427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocket *sap_socket;
10527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocketList *current = head;
10627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
10727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RLOGD("Entered getSocketById");
10827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    printList();
10927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
11027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    while(NULL != current) {
11127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(socketId == current->socket->id) {
11227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            sap_socket = current->socket;
11327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            return sap_socket;
11427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
11527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        current = current->next;
11627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
11727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    return NULL;
11827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
11927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
12027976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::initSapSocket(const char *socketName,
12127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_RadioFunctions *uimFuncs) {
12227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
12327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (strcmp(socketName, "sap_uim_socket1") == 0) {
12427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(!SocketExists(socketName)) {
12527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            addSocketToList(socketName, RIL_SOCKET_1, uimFuncs);
12627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
12727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
12827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
12927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#if (SIM_COUNT >= 2)
13027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (strcmp(socketName, "sap_uim_socket2") == 0) {
13127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(!SocketExists(socketName)) {
13227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            addSocketToList(socketName, RIL_SOCKET_2, uimFuncs);
13327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
13427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
13527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#endif
13627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
13727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#if (SIM_COUNT >= 3)
13827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (strcmp(socketName, "sap_uim_socket3") == 0) {
13927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(!SocketExists(socketName)) {
14027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            addSocketToList(socketName, RIL_SOCKET_3, uimFuncs);
14127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
14227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
14327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#endif
14427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
14527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#if (SIM_COUNT >= 4)
14627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (strcmp(socketName, "sap_uim_socket4") == 0) {
14727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(!SocketExists(socketName)) {
14827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            addSocketToList(socketName, RIL_SOCKET_4, uimFuncs);
14927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
15027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
15127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#endif
15227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
15327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
15427976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid,
15527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_RadioFunctions *uimFuncs) {
15627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocket* socket = NULL;
15727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocketList *current;
15827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
15927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if(!SocketExists(socketName)) {
16027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        socket = new RilSapSocket(socketName, socketid, uimFuncs);
161d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList));
162d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        if (!listItem) {
163d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            RLOGE("addSocketToList: OOM");
164d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            return;
165d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        }
16627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        listItem->socket = socket;
16727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        listItem->next = NULL;
16827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
16927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGD("Adding socket with id: %d", socket->id);
17027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
17127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(NULL == head) {
17227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            head = listItem;
17327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            head->next = NULL;
17427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
17527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        else {
17627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            current = head;
17727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            while(NULL != current->next) {
17827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty                current = current->next;
17927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            }
18027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            current->next = listItem;
18127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
18227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        socket->socketInit();
18327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
18427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
18527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
18627976c479473bb772703fe4caa100e535e635e84Dheeraj Shettybool RilSapSocket::SocketExists(const char *socketName) {
18727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RilSapSocketList* current = head;
18827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
18927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    while(NULL != current) {
19027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(strcmp(current->socket->name, socketName) == 0) {
19127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            return true;
19227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
19327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        current = current->next;
19427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
19527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    return false;
19627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
19727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
19827976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid* RilSapSocket::processRequestsLoop(void) {
19927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RLOGI("UIM_SOCKET:Request loop started");
20027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
20127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    while(true) {
202d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        SapSocketRequest *req = dispatchQueue.dequeue();
20327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
20427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGI("New request from the dispatch Queue");
20527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
20627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if (req != NULL) {
207d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            dispatchRequest(req->curr);
20827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            free(req);
20927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        } else {
21027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            RLOGE("Fetched null buffer from queue!");
21127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
21227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
21327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    return NULL;
21427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
21527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
21627976c479473bb772703fe4caa100e535e635e84Dheeraj ShettyRilSapSocket::RilSapSocket(const char *socketName,
21727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_SOCKET_ID socketId,
21827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RIL_RadioFunctions *inputUimFuncs):
21927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RilSocket(socketName, socketId) {
22027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (inputUimFuncs) {
22127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        uimFuncs = inputUimFuncs;
22227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
22327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
22427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
22527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define BYTES_PER_LINE 16
22627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
22727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define NIBBLE_TO_HEX(n) ({ \
22827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  uint8_t __n = (uint8_t) n & 0x0f; \
22927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  __nibble >= 10 ? 'A' + __n - 10: '0' + __n; \
23027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty})
23127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
23227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define HEX_HIGH(b) ({ \
23327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  uint8_t __b = (uint8_t) b; \
23427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  uint8_t __nibble = (__b >> 4) & 0x0f; \
23527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  NIBBLE_TO_HEX(__nibble); \
23627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty})
23727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
23827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#define HEX_LOW(b) ({ \
23927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  uint8_t __b = (uint8_t) b; \
24027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  uint8_t __nibble = __b & 0x0f; \
24127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty  NIBBLE_TO_HEX(__nibble); \
24227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty})
24327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
24427976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid log_hex(const char *who, const uint8_t *buffer, int length) {
24527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    char out[80];
24627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    int source = 0;
24727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    int dest = 0;
24827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    int dest_len = sizeof(out);
24927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    int per_line = 0;
25027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
25127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    do {
25227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        dest += sprintf(out, "%8.8s [%8.8x] ", who, source);
25327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        for(; source < length && dest_len - dest > 3 && per_line < BYTES_PER_LINE; source++,
25427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        per_line ++) {
25527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            out[dest++] = HEX_HIGH(buffer[source]);
25627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            out[dest++] = HEX_LOW(buffer[source]);
25727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            out[dest++] = ' ';
25827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
25927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if (dest < dest_len && (per_line == BYTES_PER_LINE || source >= length)) {
26027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            out[dest++] = 0;
26127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            per_line = 0;
26227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            dest = 0;
26327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            RLOGD("%s\n", out);
26427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
26527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    } while(source < length && dest < dest_len);
26627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
26727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
26827976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::dispatchRequest(MsgHeader *req) {
269d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    // SapSocketRequest will be deallocated in onRequestComplete()
27027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
271d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    if (!currRequest) {
272d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        RLOGE("dispatchRequest: OOM");
273d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        // Free MsgHeader allocated in pushRecord()
274d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        free(req);
275d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        return;
276d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    }
27727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->token = req->token;
27827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->curr = req;
27927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->p_next = NULL;
28027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->socketId = id;
28127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
28227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    pendingResponseQueue.enqueue(currRequest);
28327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
28427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (uimFuncs) {
28527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGI("[%d] > SAP REQUEST type: %d. id: %d. error: %d",
28627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        req->token,
28727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        req->type,
28827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        req->id,
28927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        req->error );
29027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
29127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#if defined(ANDROID_MULTI_SIM)
29227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
29327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#else
29427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
29527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#endif
29627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
29727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
29827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
29927976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
30027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        size_t response_len) {
30127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    SapSocketRequest* request= (SapSocketRequest*)t;
30227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    MsgHeader *hdr = request->curr;
30327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
304638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    MsgHeader rsp;
305638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    rsp.token = request->curr->token;
306638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    rsp.type = MsgType_RESPONSE;
307638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    rsp.id = request->curr->id;
308638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    rsp.error = (Error)e;
309638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    rsp.payload = (pb_bytes_array_t *)calloc(1, sizeof(pb_bytes_array_t) + response_len);
310638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    if (!rsp.payload) {
311638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        RLOGE("onRequestComplete: OOM");
312638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe    } else {
313638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        if (response && response_len > 0) {
314d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            memcpy(rsp.payload->bytes, response, response_len);
315d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            rsp.payload->size = response_len;
316638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        } else {
317638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe            rsp.payload->size = 0;
318638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        }
31927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
320638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
321d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak
322638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        sendResponse(&rsp);
323638a723ac3b12068e4e5ca44e640db382c0d46ebSanket Padawe        free(rsp.payload);
324d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    }
32527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
326d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    // Deallocate SapSocketRequest
327d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) {
328d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
329d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id");
33027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
331d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak
332d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    // Deallocate MsgHeader
333d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    free(hdr);
33427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
33527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
33627976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::sendResponse(MsgHeader* hdr) {
33727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    size_t encoded_size = 0;
33827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    uint32_t written_size;
33927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    size_t buffer_size = 0;
34027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    pb_ostream_t ostream;
34127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    bool success = false;
34227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
34327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    pthread_mutex_lock(&write_lock);
34427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
34527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if ((success = pb_get_encoded_size(&encoded_size, MsgHeader_fields,
34627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        hdr)) && encoded_size <= INT32_MAX && commandFd != -1) {
34727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        buffer_size = encoded_size + sizeof(uint32_t);
34849db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        uint8_t* buffer = (uint8_t*)malloc(buffer_size);
34949db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        if (!buffer) {
35049db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan            RLOGE("sendResponse: OOM");
35149db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan            pthread_mutex_unlock(&write_lock);
35249db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan            return;
35349db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        }
35427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        written_size = htonl((uint32_t) encoded_size);
35527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        ostream = pb_ostream_from_buffer(buffer, buffer_size);
35627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size));
35727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        success = pb_encode(&ostream, MsgHeader_fields, hdr);
35827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
35927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if (success) {
360f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe            RLOGD("Size: %zu (0x%zx) Size as written: 0x%x", encoded_size,
361f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe                    encoded_size, written_size);
36227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            log_hex("onRequestComplete", &buffer[sizeof(written_size)], encoded_size);
36327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            RLOGI("[%d] < SAP RESPONSE type: %d. id: %d. error: %d",
36427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        hdr->token, hdr->type, hdr->id,hdr->error );
36527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
36627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            if ( 0 != blockingWrite_helper(commandFd, buffer, buffer_size)) {
36727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty                RLOGE("Error %d while writing to fd", errno);
36827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            } else {
36927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty                RLOGD("Write successful");
37027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            }
37127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        } else {
372f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe            RLOGE("Error while encoding response of type %d id %d buffer_size: %zu: %s.",
373f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe                    hdr->type, hdr->id, buffer_size, PB_GET_ERROR(&ostream));
37427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
37549db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        free(buffer);
37627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    } else {
377f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe        RLOGE("Not sending response type %d: encoded_size: %zu. commandFd: %d. encoded size result:\
378f0c8ca7f09ed9a827e5c79e019526e8f2c77eeb4Sanket Padawe                %d", hdr->type, encoded_size, commandFd, success);
37927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
38027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
38127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    pthread_mutex_unlock(&write_lock);
38227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
38327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
38427976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) {
385d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    if (data && datalen > 0) {
386d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1,
387d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                sizeof(pb_bytes_array_t) + datalen);
388d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        if (!payload) {
389d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            RLOGE("onUnsolicitedResponse: OOM");
390d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            return;
391d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        }
39227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        memcpy(payload->bytes, data, datalen);
39327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        payload->size = datalen;
394d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        MsgHeader rsp;
395d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        rsp.payload = payload;
396d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        rsp.type = MsgType_UNSOL_RESPONSE;
397d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        rsp.id = (MsgId)unsolResponse;
398d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        rsp.error = Error_RIL_E_SUCCESS;
399d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        sendResponse(&rsp);
400d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        free(payload);
40127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
40227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
40327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
40427976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::pushRecord(void *p_record, size_t recordlen) {
405d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    pb_istream_t stream = pb_istream_from_buffer((uint8_t *)p_record, recordlen);
406d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    // MsgHeader will be deallocated in onRequestComplete()
407d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    MsgHeader *reqHeader = (MsgHeader *)malloc(sizeof (MsgHeader));
408d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    if (!reqHeader) {
409d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        RLOGE("pushRecord: OOM");
410d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        return;
411d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    }
41227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    memset(reqHeader, 0, sizeof(MsgHeader));
41327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
41427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    log_hex("BtSapTest-Payload", (const uint8_t*)p_record, recordlen);
41527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
41627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    if (!pb_decode(&stream, MsgHeader_fields, reqHeader) ) {
41727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        RLOGE("Error decoding protobuf buffer : %s", PB_GET_ERROR(&stream));
418d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        free(reqHeader);
41927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    } else {
420d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        // SapSocketRequest will be deallocated in processRequestsLoop()
421d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        SapSocketRequest *recv = (SapSocketRequest*)malloc(sizeof(SapSocketRequest));
422d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        if (!recv) {
423d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            RLOGE("pushRecord: OOM");
424d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            free(reqHeader);
425d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            return;
426d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        }
42727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        recv->token = reqHeader->token;
42827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        recv->curr = reqHeader;
42927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        recv->socketId = id;
43027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
43127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        dispatchQueue.enqueue(recv);
43227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
43327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
43427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
43527976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::sendDisconnect() {
43627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    size_t encoded_size = 0;
43727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    uint32_t written_size;
43827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    size_t buffer_size = 0;
43927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    pb_ostream_t ostream;
44027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    bool success = false;
44127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
44227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RIL_SIM_SAP_DISCONNECT_REQ disconnectReq;
44327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
44427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty   if ((success = pb_get_encoded_size(&encoded_size, RIL_SIM_SAP_DISCONNECT_REQ_fields,
44527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        &disconnectReq)) && encoded_size <= INT32_MAX) {
44627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        buffer_size = encoded_size + sizeof(uint32_t);
44749db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        uint8_t* buffer = (uint8_t*)malloc(buffer_size);
44849db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        if (!buffer) {
44949db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan            RLOGE("sendDisconnect: OOM");
45049db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan            return;
45149db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        }
45227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        written_size = htonl((uint32_t) encoded_size);
45327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        ostream = pb_ostream_from_buffer(buffer, buffer_size);
45427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size));
45527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        success = pb_encode(&ostream, RIL_SIM_SAP_DISCONNECT_REQ_fields, buffer);
45627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
45727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        if(success) {
458d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            // Buffer will be deallocated in sOnRequestComplete()
459d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1,
460d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                    sizeof(pb_bytes_array_t) + written_size);
461d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            if (!payload) {
462d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                RLOGE("sendDisconnect: OOM");
463d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                return;
464d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            }
46527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            memcpy(payload->bytes, buffer, written_size);
46627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            payload->size = written_size;
467d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            // MsgHeader will be deallocated in sOnRequestComplete()
468d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            MsgHeader *hdr = (MsgHeader *)malloc(sizeof(MsgHeader));
469d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            if (!hdr) {
470d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                RLOGE("sendDisconnect: OOM");
471d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                free(payload);
472d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak                return;
473d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak            }
47427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            hdr->payload = payload;
47527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            hdr->type = MsgType_REQUEST;
47627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            hdr->id = MsgId_RIL_SIM_SAP_DISCONNECT;
47727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            hdr->error = Error_RIL_E_SUCCESS;
47827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            dispatchDisconnect(hdr);
47927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
48027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        else {
48127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty            RLOGE("Encode failed in send disconnect!");
48227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty        }
48349db26c574687ccbbd033f30bca516e44ba06a21Amit Mahajan        free(buffer);
48427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    }
48527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
48627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
48727976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::dispatchDisconnect(MsgHeader *req) {
488d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    // SapSocketRequest will be deallocated in sOnRequestComplete()
48927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
490d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    if (!currRequest) {
491d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        RLOGE("dispatchDisconnect: OOM");
492d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        // Free memory allocated in sendDisconnect
493d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        free(req->payload);
494d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        free(req);
495d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak        return;
496d33397bed7bab16991d2a9d83d84d157b1e02b29Pavel Zhamaitsiak    }
49727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->token = -1;
49827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->curr = req;
49927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->p_next = NULL;
50027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    currRequest->socketId = (RIL_SOCKET_ID)99;
50127976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
50227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RLOGD("Sending disconnect on command close!");
50327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
50427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#if defined(ANDROID_MULTI_SIM)
50527976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
50627976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#else
50727976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
50827976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty#endif
50927976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
51027976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty
51127976c479473bb772703fe4caa100e535e635e84Dheeraj Shettyvoid RilSapSocket::onCommandsSocketClosed() {
51227976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    sendDisconnect();
51327976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty    RLOGE("Socket command closed");
51427976c479473bb772703fe4caa100e535e635e84Dheeraj Shetty}
515