diff --git a/ril/include/libril/ril_ex.h b/ril/include/libril/ril_ex.h index 692e4df2..ef59a70c 100644 --- a/ril/include/libril/ril_ex.h +++ b/ril/include/libril/ril_ex.h @@ -22,6 +22,8 @@ #define NUM_ELEMS_SOCKET(a) (sizeof (a) / sizeof (a)[0]) +struct ril_event; + void rilEventAddWakeup_helper(struct ril_event *ev); void listenCallback_helper(int fd, short flags, void *param); int blockingWrite_helper(int fd, void* data, size_t len); diff --git a/ril/libril/Android.mk b/ril/libril/Android.mk index b0f982d3..b83ca01b 100644 --- a/ril/libril/Android.mk +++ b/ril/libril/Android.mk @@ -1,49 +1,41 @@ # Copyright 2006 The Android Open Source Project -ifeq ($(BOARD_PROVIDES_LIBRIL),true) +ifneq ($(BOARD_PROVIDES_LIBRIL),true) LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_VENDOR_MODULE := true + LOCAL_SRC_FILES:= \ ril.cpp \ ril_event.cpp\ - RilSocket.cpp \ RilSapSocket.cpp \ + ril_service.cpp \ + sap_service.cpp LOCAL_SHARED_LIBRARIES := \ liblog \ libutils \ - libbinder \ libcutils \ libhardware_legacy \ librilutils \ + android.hardware.radio@1.0 \ + android.hardware.radio.deprecated@1.0 \ + libhidlbase \ + libhidltransport \ + libhwbinder LOCAL_STATIC_LIBRARIES := \ libprotobuf-c-nano-enable_malloc \ -LOCAL_CFLAGS := +LOCAL_CFLAGS += -Wno-unused-parameter ifeq ($(SIM_COUNT), 2) - LOCAL_CFLAGS += -DANDROID_MULTI_SIM + LOCAL_CFLAGS += -DANDROID_MULTI_SIM -DDSDA_RILD1 LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 endif -ifneq ($(filter xmm6262 xmm6360,$(BOARD_MODEM_TYPE)),) -LOCAL_CFLAGS += -DMODEM_TYPE_XMM6262 -endif -ifeq ($(BOARD_MODEM_TYPE),xmm6260) -LOCAL_CFLAGS += -DMODEM_TYPE_XMM6260 -endif -ifneq ($(filter m7450 mdm9x35 ss333 tss310 xmm7260,$(BOARD_MODEM_TYPE)),) -LOCAL_CFLAGS += -DSAMSUNG_NEXT_GEN_MODEM -endif - -ifeq ($(BOARD_MODEM_NEEDS_VIDEO_CALL_FIELD), true) -LOCAL_CFLAGS += -DNEEDS_VIDEO_CALL_FIELD -endif - -LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_C_INCLUDES += external/nanopb-c LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include @@ -54,32 +46,4 @@ LOCAL_SANITIZE := integer include $(BUILD_SHARED_LIBRARY) - -# For RdoServD which needs a static library -# ========================================= -ifneq ($(ANDROID_BIONIC_TRANSITION),) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - ril.cpp - -LOCAL_STATIC_LIBRARIES := \ - libutils_static \ - libcutils \ - librilutils_static \ - libprotobuf-c-nano-enable_malloc - -LOCAL_CFLAGS := - -ifneq ($(filter xmm6262 xmm6360,$(BOARD_MODEM_TYPE)),) -LOCAL_CFLAGS += -DMODEM_TYPE_XMM6262 -endif -ifeq ($(BOARD_MODEM_TYPE),xmm6260) -LOCAL_CFLAGS += -DMODEM_TYPE_XMM6260 -endif - -LOCAL_MODULE:= libril_static - -include $(BUILD_STATIC_LIBRARY) -endif # ANDROID_BIONIC_TRANSITION endif # BOARD_PROVIDES_LIBRIL diff --git a/ril/libril/RilSapSocket.cpp b/ril/libril/RilSapSocket.cpp index 33eabb5d..cf99773c 100644 --- a/ril/libril/RilSapSocket.cpp +++ b/ril/libril/RilSapSocket.cpp @@ -26,18 +26,10 @@ #include #include #include +#include static RilSapSocket::RilSapSocketList *head = NULL; -void ril_sap_on_request_complete ( - RIL_Token t, RIL_Errno e, - void *response, size_t responselen -); - -void ril_sap_on_unsolicited_response ( - int unsolResponse, const void *data, - size_t datalen -); extern "C" void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime); @@ -86,7 +78,9 @@ void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen) { RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1); - sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); + if(sap_socket){ + sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); + } } #endif @@ -120,14 +114,14 @@ RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) { void RilSapSocket::initSapSocket(const char *socketName, RIL_RadioFunctions *uimFuncs) { - if (strcmp(socketName, "sap_uim_socket1") == 0) { + if (strcmp(socketName, RIL1_SERVICE_NAME) == 0) { if(!SocketExists(socketName)) { addSocketToList(socketName, RIL_SOCKET_1, uimFuncs); } } #if (SIM_COUNT >= 2) - if (strcmp(socketName, "sap_uim_socket2") == 0) { + if (strcmp(socketName, RIL2_SERVICE_NAME) == 0) { if(!SocketExists(socketName)) { addSocketToList(socketName, RIL_SOCKET_2, uimFuncs); } @@ -135,7 +129,7 @@ void RilSapSocket::initSapSocket(const char *socketName, #endif #if (SIM_COUNT >= 3) - if (strcmp(socketName, "sap_uim_socket3") == 0) { + if (strcmp(socketName, RIL3_SERVICE_NAME) == 0) { if(!SocketExists(socketName)) { addSocketToList(socketName, RIL_SOCKET_3, uimFuncs); } @@ -143,7 +137,7 @@ void RilSapSocket::initSapSocket(const char *socketName, #endif #if (SIM_COUNT >= 4) - if (strcmp(socketName, "sap_uim_socket4") == 0) { + if (strcmp(socketName, RIL4_SERVICE_NAME) == 0) { if(!SocketExists(socketName)) { addSocketToList(socketName, RIL_SOCKET_4, uimFuncs); } @@ -161,6 +155,7 @@ void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketi RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList)); if (!listItem) { RLOGE("addSocketToList: OOM"); + delete socket; return; } listItem->socket = socket; @@ -179,7 +174,6 @@ void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketi } current->next = listItem; } - socket->socketInit(); } } @@ -195,24 +189,6 @@ bool RilSapSocket::SocketExists(const char *socketName) { return false; } -void* RilSapSocket::processRequestsLoop(void) { - RLOGI("UIM_SOCKET:Request loop started"); - - while(true) { - SapSocketRequest *req = dispatchQueue.dequeue(); - - RLOGI("New request from the dispatch Queue"); - - if (req != NULL) { - dispatchRequest(req->curr); - free(req); - } else { - RLOGE("Fetched null buffer from queue!"); - } - } - return NULL; -} - RilSapSocket::RilSapSocket(const char *socketName, RIL_SOCKET_ID socketId, RIL_RadioFunctions *inputUimFuncs): @@ -222,49 +198,6 @@ RilSapSocket::RilSapSocket(const char *socketName, } } -#define BYTES_PER_LINE 16 - -#define NIBBLE_TO_HEX(n) ({ \ - uint8_t __n = (uint8_t) n & 0x0f; \ - __nibble >= 10 ? 'A' + __n - 10: '0' + __n; \ -}) - -#define HEX_HIGH(b) ({ \ - uint8_t __b = (uint8_t) b; \ - uint8_t __nibble = (__b >> 4) & 0x0f; \ - NIBBLE_TO_HEX(__nibble); \ -}) - -#define HEX_LOW(b) ({ \ - uint8_t __b = (uint8_t) b; \ - uint8_t __nibble = __b & 0x0f; \ - NIBBLE_TO_HEX(__nibble); \ -}) - -void log_hex(const char *who, const uint8_t *buffer, int length) { - char out[80]; - int source = 0; - int dest = 0; - int dest_len = sizeof(out); - int per_line = 0; - - do { - dest += sprintf(out, "%8.8s [%8.8x] ", who, source); - for(; source < length && dest_len - dest > 3 && per_line < BYTES_PER_LINE; source++, - per_line ++) { - out[dest++] = HEX_HIGH(buffer[source]); - out[dest++] = HEX_LOW(buffer[source]); - out[dest++] = ' '; - } - if (dest < dest_len && (per_line == BYTES_PER_LINE || source >= length)) { - out[dest++] = 0; - per_line = 0; - dest = 0; - RLOGD("%s\n", out); - } - } while(source < length && dest < dest_len); -} - void RilSapSocket::dispatchRequest(MsgHeader *req) { // SapSocketRequest will be deallocated in onRequestComplete() SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest)); @@ -282,11 +215,13 @@ void RilSapSocket::dispatchRequest(MsgHeader *req) { pendingResponseQueue.enqueue(currRequest); if (uimFuncs) { - RLOGI("[%d] > SAP REQUEST type: %d. id: %d. error: %d", - req->token, - req->type, - req->id, - req->error ); + RLOGI("RilSapSocket::dispatchRequest [%d] > SAP REQUEST type: %d. id: %d. error: %d, \ + token 0x%p", + req->token, + req->type, + req->id, + req->error, + currRequest ); #if defined(ANDROID_MULTI_SIM) uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id); @@ -317,9 +252,10 @@ void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response, rsp.payload->size = 0; } - RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id); + RLOGE("RilSapSocket::onRequestComplete: Token:%d, MessageId:%d ril token 0x%p", + hdr->token, hdr->id, t); - sendResponse(&rsp); + sap::processResponse(&rsp, this); free(rsp.payload); } @@ -333,54 +269,6 @@ void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response, free(hdr); } -void RilSapSocket::sendResponse(MsgHeader* hdr) { - size_t encoded_size = 0; - uint32_t written_size; - size_t buffer_size = 0; - pb_ostream_t ostream; - bool success = false; - - pthread_mutex_lock(&write_lock); - - if ((success = pb_get_encoded_size(&encoded_size, MsgHeader_fields, - hdr)) && encoded_size <= INT32_MAX && commandFd != -1) { - buffer_size = encoded_size + sizeof(uint32_t); - uint8_t* buffer = (uint8_t*)malloc(buffer_size); - if (!buffer) { - RLOGE("sendResponse: OOM"); - pthread_mutex_unlock(&write_lock); - return; - } - written_size = htonl((uint32_t) encoded_size); - ostream = pb_ostream_from_buffer(buffer, buffer_size); - pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size)); - success = pb_encode(&ostream, MsgHeader_fields, hdr); - - if (success) { - RLOGD("Size: %zu (0x%zx) Size as written: 0x%x", encoded_size, - encoded_size, written_size); - log_hex("onRequestComplete", &buffer[sizeof(written_size)], encoded_size); - RLOGI("[%d] < SAP RESPONSE type: %d. id: %d. error: %d", - hdr->token, hdr->type, hdr->id,hdr->error ); - - if ( 0 != blockingWrite_helper(commandFd, buffer, buffer_size)) { - RLOGE("Error %d while writing to fd", errno); - } else { - RLOGD("Write successful"); - } - } else { - RLOGE("Error while encoding response of type %d id %d buffer_size: %zu: %s.", - hdr->type, hdr->id, buffer_size, PB_GET_ERROR(&ostream)); - } - free(buffer); - } else { - RLOGE("Not sending response type %d: encoded_size: %zu. commandFd: %d. encoded size result:\ - %d", hdr->type, encoded_size, commandFd, success); - } - - pthread_mutex_unlock(&write_lock); -} - void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) { if (data && datalen > 0) { pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1, @@ -396,119 +284,7 @@ void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t d rsp.type = MsgType_UNSOL_RESPONSE; rsp.id = (MsgId)unsolResponse; rsp.error = Error_RIL_E_SUCCESS; - sendResponse(&rsp); + sap::processUnsolResponse(&rsp, this); free(payload); } -} - -void RilSapSocket::pushRecord(void *p_record, size_t recordlen) { - pb_istream_t stream = pb_istream_from_buffer((uint8_t *)p_record, recordlen); - // MsgHeader will be deallocated in onRequestComplete() - MsgHeader *reqHeader = (MsgHeader *)malloc(sizeof (MsgHeader)); - if (!reqHeader) { - RLOGE("pushRecord: OOM"); - return; - } - memset(reqHeader, 0, sizeof(MsgHeader)); - - log_hex("BtSapTest-Payload", (const uint8_t*)p_record, recordlen); - - if (!pb_decode(&stream, MsgHeader_fields, reqHeader) ) { - RLOGE("Error decoding protobuf buffer : %s", PB_GET_ERROR(&stream)); - free(reqHeader); - } else { - // SapSocketRequest will be deallocated in processRequestsLoop() - SapSocketRequest *recv = (SapSocketRequest*)malloc(sizeof(SapSocketRequest)); - if (!recv) { - RLOGE("pushRecord: OOM"); - free(reqHeader); - return; - } - recv->token = reqHeader->token; - recv->curr = reqHeader; - recv->socketId = id; - - dispatchQueue.enqueue(recv); - } -} - -void RilSapSocket::sendDisconnect() { - size_t encoded_size = 0; - uint32_t written_size; - size_t buffer_size = 0; - pb_ostream_t ostream; - bool success = false; - - RIL_SIM_SAP_DISCONNECT_REQ disconnectReq; - - if ((success = pb_get_encoded_size(&encoded_size, RIL_SIM_SAP_DISCONNECT_REQ_fields, - &disconnectReq)) && encoded_size <= INT32_MAX) { - buffer_size = encoded_size + sizeof(uint32_t); - uint8_t* buffer = (uint8_t*)malloc(buffer_size); - if (!buffer) { - RLOGE("sendDisconnect: OOM"); - return; - } - written_size = htonl((uint32_t) encoded_size); - ostream = pb_ostream_from_buffer(buffer, buffer_size); - pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size)); - success = pb_encode(&ostream, RIL_SIM_SAP_DISCONNECT_REQ_fields, buffer); - - if(success) { - // Buffer will be deallocated in sOnRequestComplete() - pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1, - sizeof(pb_bytes_array_t) + written_size); - if (!payload) { - RLOGE("sendDisconnect: OOM"); - return; - } - memcpy(payload->bytes, buffer, written_size); - payload->size = written_size; - // MsgHeader will be deallocated in sOnRequestComplete() - MsgHeader *hdr = (MsgHeader *)malloc(sizeof(MsgHeader)); - if (!hdr) { - RLOGE("sendDisconnect: OOM"); - free(payload); - return; - } - hdr->payload = payload; - hdr->type = MsgType_REQUEST; - hdr->id = MsgId_RIL_SIM_SAP_DISCONNECT; - hdr->error = Error_RIL_E_SUCCESS; - dispatchDisconnect(hdr); - } - else { - RLOGE("Encode failed in send disconnect!"); - } - free(buffer); - } -} - -void RilSapSocket::dispatchDisconnect(MsgHeader *req) { - // SapSocketRequest will be deallocated in sOnRequestComplete() - SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest)); - if (!currRequest) { - RLOGE("dispatchDisconnect: OOM"); - // Free memory allocated in sendDisconnect - free(req->payload); - free(req); - return; - } - currRequest->token = -1; - currRequest->curr = req; - currRequest->p_next = NULL; - currRequest->socketId = (RIL_SOCKET_ID)99; - - RLOGD("Sending disconnect on command close!"); - -#if defined(ANDROID_MULTI_SIM) - uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id); -#else - uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest); -#endif -} - -void RilSapSocket::onCommandsSocketClosed() { - sendDisconnect(); - RLOGE("Socket command closed"); -} +} \ No newline at end of file diff --git a/ril/libril/RilSapSocket.h b/ril/libril/RilSapSocket.h index 75c39654..1f6163e7 100644 --- a/ril/libril/RilSapSocket.h +++ b/ril/libril/RilSapSocket.h @@ -99,9 +99,20 @@ class RilSapSocket : public RilSocket { static void printList(); /** - * Clean up method to be called on command close. + * Dispatches the request to the lower layers. + * It calls the on request function. + * + * @param request The request message. */ - void onCommandsSocketClosed(void); + void dispatchRequest(MsgHeader *request); + + /** + * Class method to get the socket from the socket list. + * + * @param socketId Socket id. + * @return the sap socket. + */ + static RilSapSocket* getSocketById(RIL_SOCKET_ID socketId); /** * Datatype to handle the socket list. @@ -112,16 +123,6 @@ class RilSapSocket : public RilSocket { } RilSapSocketList; protected: - /** - * Process each record read from the socket and - * push a new request created from that record to - * the dispatch request queue. - * - * @param The record data. - * @param The record length. - */ - void pushRecord(void *record, size_t recordlen); - /** * Socket handler to be called when a request has * been completed. @@ -145,27 +146,6 @@ class RilSapSocket : public RilSocket { void onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen); - /** - * Class method to get the socket from the socket list. - * - * @param Socket id. - * @return the sap socket. - */ - static RilSapSocket* getSocketById(RIL_SOCKET_ID socketId); - - /** - * Method to send response to SAP. It does an atomic write operation on the - * socket. - * - * @param the response header with the payload. - */ - void sendResponse(MsgHeader *hdr); - - /** - * A loop for processing the requests in the request dispatch queue. - */ - void *processRequestsLoop(void); - /** * Class method to add the sap socket to the list of sockets. * Does nothing if the socket is already present in the list. @@ -183,18 +163,6 @@ class RilSapSocket : public RilSocket { */ static bool SocketExists(const char *socketName); - /** - * Send a clean up SAP DISCONNECT if the socket disconnects before doing a SAP - * disconnect. - */ - void sendDisconnect(void); - - /** - * Dispatch the clean up disconnect request. - */ - void dispatchDisconnect(MsgHeader *req); - - private: /** * Constructor. @@ -207,14 +175,6 @@ class RilSapSocket : public RilSocket { RIL_SOCKET_ID socketId, RIL_RadioFunctions *inputUimFuncs); - /** - * Dispatches the request to the lower layers. - * It calls the on request function. - * - * @param The request message. - */ - void dispatchRequest(MsgHeader *request); - /** * Class method that selects the socket on which the onRequestComplete * is called. diff --git a/ril/libril/RilSocket.cpp b/ril/libril/RilSocket.cpp deleted file mode 100644 index a002d940..00000000 --- a/ril/libril/RilSocket.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* -* Copyright (C) 2014 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -extern "C" -void *ril_socket_process_requests_loop(void *arg); - -#include "RilSocket.h" -#include -#include -#include -#define SOCKET_LISTEN_BACKLOG 0 - -int RilSocket::socketInit(void) { - int ret; - - listenCb = &RilSocket::sSocketListener; - commandCb = &RilSocket::sSocketRequestsHandler; - listenFd = android_get_control_socket(name); - - //Start listening - ret = listen(listenFd, SOCKET_LISTEN_BACKLOG); - - if (ret < 0) { - RLOGE("Failed to listen on %s socket '%d': %s", - name, listenFd, strerror(errno)); - return ret; - } - //Add listen event to the event loop - ril_event_set(&listenEvent, listenFd, false, listenCb, this); - rilEventAddWakeup_helper(&listenEvent); - return ret; -} - -void RilSocket::sSocketListener(int fd, short flags, void *param) { - RilSocket *theSocket = (RilSocket *) param; - MySocketListenParam listenParam; - listenParam.socket = theSocket; - listenParam.sListenParam.type = RIL_SAP_SOCKET; - - listenCallback_helper(fd, flags, (void*)&listenParam); -} - -void RilSocket::onNewCommandConnect() { - pthread_attr_t attr; - PthreadPtr pptr = ril_socket_process_requests_loop; - int result; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - //Start socket request processing loop thread - result = pthread_create(&socketThreadId, &attr, pptr, this); - if(result < 0) { - RLOGE("pthread_create failed with result:%d",result); - } - - RLOGE("New socket command connected and socket request thread started"); -} - -void RilSocket::sSocketRequestsHandler(int fd, short flags, void *param) { - socketClient *sc = (socketClient *) param; - RilSocket *theSocket = sc->socketPtr; - RecordStream *rs = sc->rs; - - theSocket->socketRequestsHandler(fd, flags, rs); -} - -void RilSocket::socketRequestsHandler(int fd, short flags, RecordStream *p_rs) { - int ret; - assert(fd == commandFd); - void *p_record; - size_t recordlen; - - for (;;) { - /* loop until EAGAIN/EINTR, end of stream, or other error */ - ret = record_stream_get_next(p_rs, &p_record, &recordlen); - - if (ret == 0 && p_record == NULL) { - /* end-of-stream */ - break; - } else if (ret < 0) { - break; - } else if (ret == 0) { - pushRecord(p_record, recordlen); - } - } - - if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) { - /* fatal error or end-of-stream */ - if (ret != 0) { - RLOGE("error on reading command socket errno:%d\n", errno); - } else { - RLOGW("EOS. Closing command socket."); - } - - close(commandFd); - commandFd = -1; - - ril_event_del(&callbackEvent); - - record_stream_free(p_rs); - - /* start listening for new connections again */ - - rilEventAddWakeup_helper(&listenEvent); - - onCommandsSocketClosed(); - } -} - -void RilSocket::setListenFd(int fd) { - listenFd = fd; -} - -void RilSocket::setCommandFd(int fd) { - commandFd = fd; -} - -int RilSocket::getListenFd(void) { - return listenFd; -} - -int RilSocket::getCommandFd(void) { - return commandFd; -} - -void RilSocket::setListenCb(ril_event_cb cb) { - listenCb = cb; -} - -void RilSocket::setCommandCb(ril_event_cb cb) { - commandCb = cb; -} - -ril_event_cb RilSocket::getListenCb(void) { - return listenCb; -} - -ril_event_cb RilSocket::getCommandCb(void) { - return commandCb; -} - -void RilSocket::setListenEvent(ril_event event) { - listenEvent = event; -} - -void RilSocket::setCallbackEvent(ril_event event) { - callbackEvent = event; -} - -ril_event* RilSocket::getListenEvent(void) { - return &listenEvent; -} - -ril_event* RilSocket::getCallbackEvent(void) { - return &callbackEvent; -} - -extern "C" -void *ril_socket_process_requests_loop(void *arg) { - RilSocket *socket = (RilSocket *)arg; - socket->processRequestsLoop(); - return NULL; -} diff --git a/ril/libril/RilSocket.h b/ril/libril/RilSocket.h index 619401af..53b00c9d 100644 --- a/ril/libril/RilSocket.h +++ b/ril/libril/RilSocket.h @@ -20,10 +20,6 @@ #include "rilSocketQueue.h" #include -using namespace std; - -extern "C" void *ril_socket_process_requests_loop(void *arg); - /** * Abstract socket class representing sockets in rild. *

@@ -46,81 +42,6 @@ class RilSocket { */ RIL_SOCKET_ID id; - /** - * Listen socket file descriptor. - */ - int listenFd = -1; - - /** - * Commands socket file descriptor. - */ - int commandFd = -1; - - /** - * Socket request loop thread id. - */ - pthread_t socketThreadId; - - /** - * Listen event callack. Callback called when the other ends does accept. - */ - ril_event_cb listenCb; - - /** - * Commands event callack.Callback called when there are requests from the other side. - */ - ril_event_cb commandCb; - - /** - * Listen event to be added to eventloop after socket listen. - */ - struct ril_event listenEvent; - - /** - * Commands event to be added to eventloop after accept. - */ - struct ril_event callbackEvent; - - /** - * Static socket listen handler. Chooses the socket to call the listen callback - * from ril.cpp. - * - * @param Listen fd. - * @param flags. - * @param Parameter for the listen handler. - */ - static void sSocketListener(int fd, short flags, void *param); - - /** - * Static socket request handler. Chooses the socket to call the request handler on. - * - * @param Commands fd. - * @param flags. - * @param Parameter for the request handler. - */ - static void sSocketRequestsHandler(int fd, short flags, void *param); - - /** - * Process record from the record stream and push the requests onto the queue. - * - * @param record data. - * @param record length. - */ - virtual void pushRecord(void *record, size_t recordlen) = 0; - - /** - * Socket lock for writing data on the socket. - */ - pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER; - - /** - * The loop to process the incoming requests. - */ - virtual void *processRequestsLoop(void) = 0; - - private: - friend void *::ril_socket_process_requests_loop(void *arg); - public: /** @@ -135,138 +56,15 @@ class RilSocket { } /** - * Clean up function on commands socket close. - */ - virtual void onCommandsSocketClosed(void) = 0; - - /** - * Function called on new commands socket connect. Request loop thread is started here. - */ - void onNewCommandConnect(void); - - /** - * Set listen socket fd. - * - * @param Input fd. - */ - void setListenFd(int listenFd); - - /** - * Set commands socket fd. - * - * @param Input fd. - */ - void setCommandFd(int commandFd); - - /** - * Get listen socket fd. - * - * @return Listen fd. - */ - int getListenFd(void); - - /** - * Get commands socket fd. + * Get socket id. * - * @return Commands fd. + * @return RIL_SOCKET_ID socket id. */ - int getCommandFd(void); - - /** - * Set listen event callback. - * - * @param Input event callback. - */ - void setListenCb(ril_event_cb listenCb); - - /** - * Set command event callback. - * - * @param Input event callback. - */ - void setCommandCb(ril_event_cb commandCb); - - /** - * Get listen event callback. - * - * @return Listen event callback. - */ - ril_event_cb getListenCb(void); - - /** - * Gey command event callback. - * - * @return Command event callback. - */ - ril_event_cb getCommandCb(void); - - /** - * Set listen event. - * - * @param Input event. - */ - void setListenEvent(ril_event listenEvent); - - /** - * Set command callback event. - * - * @param Input event. - */ - void setCallbackEvent(ril_event commandEvent); - - /** - * Get listen event. - * - * @return Listen event. - */ - ril_event* getListenEvent(void); - - /** - * Get commands callback event. - * - * @return Commands callback event. - */ - ril_event* getCallbackEvent(void); + RIL_SOCKET_ID getSocketId(void) { + return id; + } virtual ~RilSocket(){} - - protected: - - /** - * Start listening on the socket and add the socket listen callback event. - * - * @return Result of the socket listen. - */ - int socketInit(void); - - /** - * Socket request handler - * - * @param Commands fd. - * @param flags. - * @param Record stream. - */ - void socketRequestsHandler(int fd, short flags, RecordStream *rs); -}; - -class socketClient { - public: - RilSocket *socketPtr; - RecordStream *rs; - - socketClient(RilSocket *socketPtr, RecordStream *rs) { - this->socketPtr = socketPtr; - this->rs = rs; - } }; -typedef struct MySocketListenParam { - SocketListenParam sListenParam; - RilSocket *socket; -} MySocketListenParam; - -typedef void* (RilSocket::*RilSocketFuncPtr)(void); -typedef void (RilSocket::*RilSocketEventPtr)(int fd,short flags, void *param); -typedef void* (*PthreadPtr)(void*); - #endif diff --git a/ril/libril/include/telephony/ril_commands_vendor.h b/ril/libril/include/telephony/ril_commands_vendor.h deleted file mode 100644 index 91214076..00000000 --- a/ril/libril/include/telephony/ril_commands_vendor.h +++ /dev/null @@ -1,69 +0,0 @@ -/* //device/libs/telephony/ril_commands.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - {10000, NULL, NULL}, - {10001, NULL, NULL}, - {RIL_REQUEST_GET_CELL_BROADCAST_CONFIG, dispatchVoid, responseVoid}, - {10003, NULL, NULL}, - {10004, NULL, NULL}, - {RIL_REQUEST_SEND_ENCODED_USSD, dispatchVoid, responseVoid}, - {RIL_REQUEST_SET_PDA_MEMORY_STATUS, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_PHONEBOOK_STORAGE_INFO, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_PHONEBOOK_ENTRY, dispatchVoid, responseVoid}, - {RIL_REQUEST_ACCESS_PHONEBOOK_ENTRY, dispatchVoid, responseVoid}, - {RIL_REQUEST_DIAL_VIDEO_CALL, dispatchVoid, responseVoid}, - {RIL_REQUEST_CALL_DEFLECTION, dispatchVoid, responseVoid}, - {RIL_REQUEST_READ_SMS_FROM_SIM, dispatchVoid, responseVoid}, - {RIL_REQUEST_USIM_PB_CAPA, dispatchVoid, responseVoid}, - {RIL_REQUEST_LOCK_INFO, dispatchVoid, responseVoid}, - {10015, NULL, NULL}, - {RIL_REQUEST_DIAL_EMERGENCY, dispatchDial, responseVoid}, - {RIL_REQUEST_GET_STOREAD_MSG_COUNT, dispatchVoid, responseVoid}, - {RIL_REQUEST_STK_SIM_INIT_EVENT, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_LINE_ID, dispatchVoid, responseVoid}, - {RIL_REQUEST_SET_LINE_ID, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_SERIAL_NUMBER, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_MANUFACTURE_DATE_NUMBER, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_BARCODE_NUMBER, dispatchVoid, responseVoid}, - {RIL_REQUEST_UICC_GBA_AUTHENTICATE_BOOTSTRAP, dispatchVoid, responseVoid}, - {RIL_REQUEST_UICC_GBA_AUTHENTICATE_NAF, dispatchVoid, responseVoid}, - {RIL_REQUEST_SIM_TRANSMIT_BASIC, dispatchVoid, responseVoid}, - {RIL_REQUEST_SIM_OPEN_CHANNEL, dispatchVoid, responseVoid}, - {RIL_REQUEST_SIM_CLOSE_CHANNEL, dispatchVoid, responseVoid}, - {RIL_REQUEST_SIM_TRANSMIT_CHANNEL, dispatchVoid, responseVoid}, - {RIL_REQUEST_SIM_AUTH, dispatchVoid, responseVoid}, - {RIL_REQUEST_PS_ATTACH, dispatchVoid, responseVoid}, - {RIL_REQUEST_PS_DETACH, dispatchVoid, responseVoid}, - {RIL_REQUEST_ACTIVATE_DATA_CALL, dispatchVoid, responseVoid}, - {RIL_REQUEST_CHANGE_SIM_PERSO, dispatchVoid, responseVoid}, - {RIL_REQUEST_ENTER_SIM_PERSO, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_TIME_INFO, dispatchVoid, responseVoid}, - {RIL_REQUEST_OMADM_SETUP_SESSION, dispatchVoid, responseVoid}, - {RIL_REQUEST_OMADM_SERVER_START_SESSION, dispatchVoid, responseVoid}, - {RIL_REQUEST_OMADM_CLIENT_START_SESSION, dispatchVoid, responseVoid}, - {RIL_REQUEST_OMADM_SEND_DATA, dispatchVoid, responseVoid}, - {RIL_REQUEST_CDMA_GET_DATAPROFILE, dispatchVoid, responseVoid}, - {RIL_REQUEST_CDMA_SET_DATAPROFILE, dispatchVoid, responseVoid}, - {RIL_REQUEST_CDMA_GET_SYSTEMPROPERTIES, dispatchVoid, responseVoid}, - {RIL_REQUEST_CDMA_SET_SYSTEMPROPERTIES, dispatchVoid, responseVoid}, - {RIL_REQUEST_SEND_SMS_COUNT, dispatchVoid, responseVoid}, - {RIL_REQUEST_SEND_SMS_MSG, dispatchVoid, responseVoid}, - {RIL_REQUEST_SEND_SMS_MSG_READ_STATUS, dispatchVoid, responseVoid}, - {RIL_REQUEST_MODEM_HANGUP, dispatchVoid, responseVoid}, - {RIL_REQUEST_SET_SIM_POWER, dispatchVoid, responseVoid}, - {RIL_REQUEST_SET_PREFERRED_NETWORK_LIST, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_PREFERRED_NETWORK_LIST, dispatchVoid, responseVoid}, - {RIL_REQUEST_HANGUP_VT, dispatchVoid, responseVoid}, diff --git a/ril/libril/include/telephony/ril_unsol_commands_vendor.h b/ril/libril/include/telephony/ril_unsol_commands_vendor.h deleted file mode 100644 index 0a9b657e..00000000 --- a/ril/libril/include/telephony/ril_unsol_commands_vendor.h +++ /dev/null @@ -1,55 +0,0 @@ -/* //device/libs/telephony/ril_unsol_commands.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - {SAMSUNG_UNSOL_RESPONSE_BASE, NULL, WAKE_PARTIAL}, - {RIL_UNSOL_RELEASE_COMPLETE_MESSAGE, responseVoid, WAKE_PARTIAL}, // 11001 - {RIL_UNSOL_STK_SEND_SMS_RESULT, responseInts, WAKE_PARTIAL}, // 11002 - {RIL_UNSOL_STK_CALL_CONTROL_RESULT, responseVoid, WAKE_PARTIAL}, // 11003 - {RIL_UNSOL_DUN_CALL_STATUS, responseVoid, WAKE_PARTIAL}, // 11004 - {11005, NULL, WAKE_PARTIAL}, - {11006, NULL, WAKE_PARTIAL}, - {RIL_UNSOL_O2_HOME_ZONE_INFO, responseVoid, WAKE_PARTIAL}, // 11007 - {RIL_UNSOL_DEVICE_READY_NOTI, responseVoid, WAKE_PARTIAL}, // 11008 - {RIL_UNSOL_GPS_NOTI, responseVoid, WAKE_PARTIAL}, // 11009 - {RIL_UNSOL_AM, responseString, WAKE_PARTIAL}, // 11010 - {RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL, responseVoid, WAKE_PARTIAL}, // 11011 - {RIL_UNSOL_DATA_SUSPEND_RESUME, responseInts, WAKE_PARTIAL}, // 11012 - {RIL_UNSOL_SAP, responseVoid, WAKE_PARTIAL}, // 11013 - {11014, NULL, WAKE_PARTIAL}, - {RIL_UNSOL_SIM_SMS_STORAGE_AVAILALE, responseVoid, WAKE_PARTIAL}, // 11015 - {RIL_UNSOL_HSDPA_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, // 11016 - {RIL_UNSOL_WB_AMR_STATE, responseInts, WAKE_PARTIAL}, // 11017 - {RIL_UNSOL_TWO_MIC_STATE, responseInts, WAKE_PARTIAL}, // 11018 - {RIL_UNSOL_DHA_STATE, responseVoid, WAKE_PARTIAL}, // 11019 - {RIL_UNSOL_UART, responseVoid, WAKE_PARTIAL}, // 11020 - {RIL_UNSOL_RESPONSE_HANDOVER, responseVoid, WAKE_PARTIAL}, // 11021 - {RIL_UNSOL_IPV6_ADDR, responseVoid, WAKE_PARTIAL}, // 11022 - {RIL_UNSOL_NWK_INIT_DISC_REQUEST, responseVoid, WAKE_PARTIAL}, // 11023 - {RIL_UNSOL_RTS_INDICATION, responseVoid, WAKE_PARTIAL}, // 11024 - {RIL_UNSOL_OMADM_SEND_DATA, responseVoid, WAKE_PARTIAL}, // 11025 - {RIL_UNSOL_DUN, responseVoid, WAKE_PARTIAL}, // 11026 - {RIL_UNSOL_SYSTEM_REBOOT, responseVoid, WAKE_PARTIAL}, // 11027 - {RIL_UNSOL_VOICE_PRIVACY_CHANGED, responseVoid, WAKE_PARTIAL}, // 11028 - {RIL_UNSOL_UTS_GETSMSCOUNT, responseVoid, WAKE_PARTIAL}, // 11029 - {RIL_UNSOL_UTS_GETSMSMSG, responseVoid, WAKE_PARTIAL}, // 11030 - {RIL_UNSOL_UTS_GET_UNREAD_SMS_STATUS, responseVoid, WAKE_PARTIAL}, // 11031 - {RIL_UNSOL_MIP_CONNECT_STATUS, responseVoid, WAKE_PARTIAL}, // 11032 -#ifdef RIL_UNSOL_SNDMGR_WB_AMR_REPORT - {RIL_UNSOL_SNDMGR_WB_AMR_REPORT, responseInts, WAKE_PARTIAL}, // 20017 -#endif -#ifdef RIL_UNSOL_SNDMGR_CLOCK_CTRL - {RIL_UNSOL_SNDMGR_CLOCK_CTRL, responseInts, WAKE_PARTIAL}, // 20022 -#endif diff --git a/ril/libril/ril.cpp b/ril/libril/ril.cpp old mode 100755 new mode 100644 index 4478ea22..63669201 --- a/ril/libril/ril.cpp +++ b/ril/libril/ril.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -47,6 +46,8 @@ #include #include #include +#include +#include extern "C" void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen); @@ -58,13 +59,6 @@ namespace android { #define PHONE_PROCESS "radio" #define BLUETOOTH_PROCESS "bluetooth" -#define SOCKET_NAME_RIL "rild" -#define SOCKET2_NAME_RIL "rild2" -#define SOCKET3_NAME_RIL "rild3" -#define SOCKET4_NAME_RIL "rild4" - -#define SOCKET_NAME_RIL_DEBUG "rild-debug" - #define ANDROID_WAKE_LOCK_NAME "radio-interface" #define ANDROID_WAKE_LOCK_SECS 0 @@ -82,77 +76,22 @@ namespace android { #define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0]) -#define MIN(a,b) ((a)<(b) ? (a) : (b)) - -/* Constants for response types */ -#define RESPONSE_SOLICITED 0 -#define RESPONSE_UNSOLICITED 1 -#define RESPONSE_SOLICITED_ACK 2 -#define RESPONSE_SOLICITED_ACK_EXP 3 -#define RESPONSE_UNSOLICITED_ACK_EXP 4 - /* Negative values for private RIL errno's */ -#define RIL_ERRNO_INVALID_RESPONSE -1 -#define RIL_ERRNO_NO_MEMORY -12 +#define RIL_ERRNO_INVALID_RESPONSE (-1) +#define RIL_ERRNO_NO_MEMORY (-12) // request, response, and unsolicited msg print macro #define PRINTBUF_SIZE 8096 -// Enable verbose logging -#define VDBG 0 - -// Enable RILC log -#define RILC_LOG 0 - -#if RILC_LOG - #define startRequest sprintf(printBuf, "(") - #define closeRequest sprintf(printBuf, "%s)", printBuf) - #define printRequest(token, req) \ - RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf) - - #define startResponse sprintf(printBuf, "%s {", printBuf) - #define closeResponse sprintf(printBuf, "%s}", printBuf) - #define printResponse RLOGD("%s", printBuf) - - #define clearPrintBuf printBuf[0] = 0 - #define removeLastChar printBuf[strlen(printBuf)-1] = 0 - #define appendPrintBuf(x...) snprintf(printBuf, PRINTBUF_SIZE, x) -#else - #define startRequest - #define closeRequest - #define printRequest(token, req) - #define startResponse - #define closeResponse - #define printResponse - #define clearPrintBuf - #define removeLastChar - #define appendPrintBuf(x...) -#endif - enum WakeType {DONT_WAKE, WAKE_PARTIAL}; typedef struct { int requestNumber; - void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI); - int(*responseFunction) (Parcel &p, void *response, size_t responselen); -} CommandInfo; - -typedef struct { - int requestNumber; - int (*responseFunction) (Parcel &p, void *response, size_t responselen); + int (*responseFunction) (int slotId, int responseType, int token, + RIL_Errno e, void *response, size_t responselen); WakeType wakeType; } UnsolResponseInfo; -typedef struct RequestInfo { - int32_t token; //this is not RIL_Token - CommandInfo *pCI; - struct RequestInfo *p_next; - char cancelled; - char local; // responses to local commands do not go back to command process - RIL_SOCKET_ID socket_id; - int wasAckSent; // Indicates whether an ack was sent earlier -} RequestInfo; - typedef struct UserCallbackInfo { RIL_TimedCallback p_callback; void *userParam; @@ -160,17 +99,15 @@ typedef struct UserCallbackInfo { struct UserCallbackInfo *p_next; } UserCallbackInfo; -extern "C" const char * requestToString(int request); extern "C" const char * failCauseToString(RIL_Errno); extern "C" const char * callStateToString(RIL_CallState); extern "C" const char * radioStateToString(RIL_RadioState); extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id); extern "C" -char rild[MAX_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL; - -#define RIL_VENDOR_COMMANDS_OFFSET 10000 - +char ril_service_name_base[MAX_SERVICE_NAME_LENGTH] = RIL_SERVICE_NAME_BASE; +extern "C" +char ril_service_name[MAX_SERVICE_NAME_LENGTH] = RIL1_SERVICE_NAME; /*******************************************************************/ RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL}; @@ -188,10 +125,7 @@ static int s_fdWakeupWrite; int s_wakelock_count = 0; -static struct ril_event s_commands_event; static struct ril_event s_wakeupfd_event; -static struct ril_event s_listen_event; -static SocketListenParam s_ril_param_socket; static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER; @@ -199,30 +133,18 @@ static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER; static RequestInfo *s_pendingRequests = NULL; #if (SIM_COUNT >= 2) -static struct ril_event s_commands_event_socket2; -static struct ril_event s_listen_event_socket2; -static SocketListenParam s_ril_param_socket2; - static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t s_writeMutex_socket2 = PTHREAD_MUTEX_INITIALIZER; static RequestInfo *s_pendingRequests_socket2 = NULL; #endif #if (SIM_COUNT >= 3) -static struct ril_event s_commands_event_socket3; -static struct ril_event s_listen_event_socket3; -static SocketListenParam s_ril_param_socket3; - static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t s_writeMutex_socket3 = PTHREAD_MUTEX_INITIALIZER; static RequestInfo *s_pendingRequests_socket3 = NULL; #endif #if (SIM_COUNT >= 4) -static struct ril_event s_commands_event_socket4; -static struct ril_event s_listen_event_socket4; -static SocketListenParam s_ril_param_socket4; - static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t s_writeMutex_socket4 = PTHREAD_MUTEX_INITIALIZER; static RequestInfo *s_pendingRequests_socket4 = NULL; @@ -254,84 +176,10 @@ static size_t s_lastNITZTimeDataSize; #endif /*******************************************************************/ -static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id); - -static void dispatchVoid (Parcel& p, RequestInfo *pRI); -static void dispatchString (Parcel& p, RequestInfo *pRI); -static void dispatchStrings (Parcel& p, RequestInfo *pRI); -static void dispatchInts (Parcel& p, RequestInfo *pRI); -static void dispatchDial (Parcel& p, RequestInfo *pRI); -static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI); -static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI); -static void dispatchCallForward(Parcel& p, RequestInfo *pRI); -static void dispatchRaw(Parcel& p, RequestInfo *pRI); -static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI); -static void dispatchDataCall (Parcel& p, RequestInfo *pRI); -static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI); -static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI); -static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI); - -static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI); -static void dispatchImsSms(Parcel &p, RequestInfo *pRI); -static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef); -static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef); -static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI); -static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI); -static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI); -static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI); -static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI); -static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI); -static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI); -static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI); -static void dispatchDataProfile(Parcel &p, RequestInfo *pRI); -static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI); -static void dispatchCarrierRestrictions(Parcel &p, RequestInfo *pRI); -static int responseInts(Parcel &p, void *response, size_t responselen); -static int responseFailCause(Parcel &p, void *response, size_t responselen); -static int responseStrings(Parcel &p, void *response, size_t responselen); -static int responseString(Parcel &p, void *response, size_t responselen); -static int responseVoid(Parcel &p, void *response, size_t responselen); -static int responseCallList(Parcel &p, void *response, size_t responselen); -static int responseSMS(Parcel &p, void *response, size_t responselen); -static int responseSIM_IO(Parcel &p, void *response, size_t responselen); -static int responseCallForwards(Parcel &p, void *response, size_t responselen); -static int responseDataCallList(Parcel &p, void *response, size_t responselen); -static int responseSetupDataCall(Parcel &p, void *response, size_t responselen); -static int responseRaw(Parcel &p, void *response, size_t responselen); -static int responseSsn(Parcel &p, void *response, size_t responselen); -static int responseSimStatus(Parcel &p, void *response, size_t responselen); -static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen); -static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen); -static int responseCdmaSms(Parcel &p, void *response, size_t responselen); -static int responseCellList(Parcel &p, void *response, size_t responselen); -static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen); -static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen); -static int responseCallRing(Parcel &p, void *response, size_t responselen); -static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen); -static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen); -static int responseSimRefresh(Parcel &p, void *response, size_t responselen); -static int responseCellInfoList(Parcel &p, void *response, size_t responselen); -static int responseHardwareConfig(Parcel &p, void *response, size_t responselen); -static int responseDcRtInfo(Parcel &p, void *response, size_t responselen); -static int responseRadioCapability(Parcel &p, void *response, size_t responselen); -static int responseSSData(Parcel &p, void *response, size_t responselen); -static int responseLceStatus(Parcel &p, void *response, size_t responselen); -static int responseLceData(Parcel &p, void *response, size_t responselen); -static int responseActivityData(Parcel &p, void *response, size_t responselen); - -static int responseCarrierRestrictions(Parcel &p, void *response, size_t responselen); -static int responsePcoData(Parcel &p, void *response, size_t responselen); -static int decodeVoiceRadioTechnology (RIL_RadioState radioState); -static int decodeCdmaSubscriptionSource (RIL_RadioState radioState); -static RIL_RadioState processRadioState(RIL_RadioState newRadioState); static void grabPartialWakeLock(); -static void releaseWakeLock(); +void releaseWakeLock(); static void wakeTimeoutCallback(void *); -static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType); - -static bool isDebuggable(); - #ifdef RIL_SHLIB #if defined(ANDROID_MULTI_SIM) extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, @@ -344,12 +192,8 @@ extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, #if defined(ANDROID_MULTI_SIM) #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d)) -#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e)) -#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a) #else #define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c)) -#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d)) -#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest() #endif static UserCallbackInfo * internalRequestTimedCallback @@ -365,170 +209,26 @@ static UnsolResponseInfo s_unsolResponses[] = { #include "ril_unsol_commands.h" }; -static CommandInfo s_commands_v[] = { -#include -}; - -static UnsolResponseInfo s_unsolResponses_v[] = { -#include -}; - -/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and - RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from - radio state message and store it. Every time there is a change in Radio State - check to see if voice radio tech changes and notify telephony - */ -int voiceRadioTech = -1; - -/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE - and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription - source from radio state and store it. Every time there is a change in Radio State - check to see if subscription source changed and notify telephony - */ -int cdmaSubscriptionSource = -1; - -/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the - SIM/RUIM state from radio state and store it. Every time there is a change in Radio State, - check to see if SIM/RUIM status changed and notify telephony - */ -int simRuimStatus = -1; - -static char * RIL_getRilSocketName() { - return rild; +char * RIL_getServiceName() { + return ril_service_name; } extern "C" -void RIL_setRilSocketName(const char * s) { - strncpy(rild, s, MAX_SOCKET_NAME_LENGTH); -} - -static char * -strdupReadString(Parcel &p) { - size_t stringlen; - const char16_t *s16; - - s16 = p.readString16Inplace(&stringlen); - - return strndup16to8(s16, stringlen); -} - -static status_t -readStringFromParcelInplace(Parcel &p, char *str, size_t maxLen) { - size_t s16Len; - const char16_t *s16; - - s16 = p.readString16Inplace(&s16Len); - if (s16 == NULL) { - return NO_MEMORY; - } - size_t strLen = strnlen16to8(s16, s16Len); - if ((strLen + 1) > maxLen) { - return NO_MEMORY; - } - if (strncpy16to8(str, s16, strLen) == NULL) { - return NO_MEMORY; - } else { - return NO_ERROR; - } -} - -static void writeStringToParcel(Parcel &p, const char *s) { - char16_t *s16; - size_t s16_len; - s16 = strdup8to16(s, &s16_len); - p.writeString16(s16, s16_len); - free(s16); -} - - -static void -memsetString (char *s) { - if (s != NULL) { - memset (s, 0, strlen(s)); - } -} - -void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize, - const size_t* objects, size_t objectsSize, - void* cookie) { - // do nothing -- the data reference lives longer than the Parcel object -} - -/** - * To be called from dispatch thread - * Issue a single local request, ensuring that the response - * is not sent back up to the command process - */ -static void -issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) { - RequestInfo *pRI; - int ret; - /* Hook for current context */ - /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ - pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; - /* pendingRequestsHook refer to &s_pendingRequests */ - RequestInfo** pendingRequestsHook = &s_pendingRequests; - -#if (SIM_COUNT == 2) - if (socket_id == RIL_SOCKET_2) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; - pendingRequestsHook = &s_pendingRequests_socket2; - } -#endif - - pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); - if (pRI == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(request)); - return; - } - - pRI->local = 1; - pRI->token = 0xffffffff; // token is not used in this context - - pRI->pCI = &(s_commands[request]); - pRI->socket_id = socket_id; - - /* Hack to include Samsung requests */ - if (request > RIL_VENDOR_COMMANDS_OFFSET) { - pRI->pCI = &(s_commands_v[request - RIL_VENDOR_COMMANDS_OFFSET]); - } - - ret = pthread_mutex_lock(pendingRequestsMutexHook); - assert (ret == 0); - - pRI->p_next = *pendingRequestsHook; - *pendingRequestsHook = pRI; - - ret = pthread_mutex_unlock(pendingRequestsMutexHook); - assert (ret == 0); - - RLOGD("C[locl]> %s", requestToString(request)); - - CALL_ONREQUEST(request, data, len, pRI, pRI->socket_id); +void RIL_setServiceName(const char * s) { + strncpy(ril_service_name, s, MAX_SERVICE_NAME_LENGTH); } - - -static int -processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) { - Parcel p; - status_t status; - int32_t request; - int32_t token; +RequestInfo * +addRequestToList(int serial, int slotId, int request) { RequestInfo *pRI; int ret; + RIL_SOCKET_ID socket_id = (RIL_SOCKET_ID) slotId; /* Hook for current context */ /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; /* pendingRequestsHook refer to &s_pendingRequests */ RequestInfo** pendingRequestsHook = &s_pendingRequests; - p.setData((uint8_t *) buffer, buflen); - - // status checked at end - status = p.readInt32(&request); - status = p.readInt32 (&token); - #if (SIM_COUNT >= 2) if (socket_id == RIL_SOCKET_2) { pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; @@ -548,4372 +248,105 @@ processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) { #endif #endif - if (status != NO_ERROR) { - RLOGE("invalid request block"); - return 0; - } - - CommandInfo *pCI = NULL; - if (request > RIL_VENDOR_COMMANDS_OFFSET) { - int index = request - RIL_VENDOR_COMMANDS_OFFSET; - RLOGD("processCommandBuffer: samsung request=%d, index=%d", - request, index); - if (index < (int32_t)NUM_ELEMS(s_commands_v)) - pCI = &(s_commands_v[index]); - } else { - if (request < (int32_t)NUM_ELEMS(s_commands)) - pCI = &(s_commands[request]); - } - - // Received an Ack for the previous result sent to RIL.java, - // so release wakelock and exit - if (request == RIL_RESPONSE_ACKNOWLEDGEMENT) { - releaseWakeLock(); - return 0; - } - - if (pCI == NULL) { - Parcel pErr; - RLOGE("unsupported request code %d token %d", request, token); - // FIXME this should perhaps return a response - pErr.writeInt32 (RESPONSE_SOLICITED); - pErr.writeInt32 (token); - pErr.writeInt32 (RIL_E_GENERIC_FAILURE); - - sendResponse(pErr, socket_id); - return 0; - } - pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); if (pRI == NULL) { RLOGE("Memory allocation failed for request %s", requestToString(request)); - return 0; + return NULL; } - pRI->token = token; - pRI->pCI = pCI; + pRI->token = serial; + pRI->pCI = &(s_commands[request]); pRI->socket_id = socket_id; ret = pthread_mutex_lock(pendingRequestsMutexHook); assert (ret == 0); - pRI->p_next = *pendingRequestsHook; - *pendingRequestsHook = pRI; - - ret = pthread_mutex_unlock(pendingRequestsMutexHook); - assert (ret == 0); - -/* sLastDispatchedToken = token; */ - - pRI->pCI->dispatchFunction(p, pRI); - - return 0; -} - -static void -invalidCommandBlock (RequestInfo *pRI) { - RLOGE("invalid command block for token %d request %s", - pRI->token, requestToString(pRI->pCI->requestNumber)); -} - -/** Callee expects NULL */ -static void -dispatchVoid (Parcel& p, RequestInfo *pRI) { - clearPrintBuf; - printRequest(pRI->token, pRI->pCI->requestNumber); - CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id); -} - -/** Callee expects const char * */ -static void -dispatchString (Parcel& p, RequestInfo *pRI) { - status_t status; - size_t datalen; - size_t stringlen; - char *string8 = NULL; - - string8 = strdupReadString(p); - - startRequest; - appendPrintBuf("%s%s", printBuf, string8); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, string8, - sizeof(char *), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString(string8); -#endif - - free(string8); - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -/** Callee expects const char ** */ -static void -dispatchStrings (Parcel &p, RequestInfo *pRI) { - int32_t countStrings; - status_t status; - size_t datalen; - char **pStrings; - - status = p.readInt32 (&countStrings); - - if (status != NO_ERROR) { - goto invalid; - } - - startRequest; - if (countStrings == 0) { - // just some non-null pointer - pStrings = (char **)calloc(1, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - closeRequest; - return; - } - - datalen = 0; - } else if (countStrings < 0) { - pStrings = NULL; - datalen = 0; - } else { - datalen = sizeof(char *) * countStrings; - - pStrings = (char **)calloc(countStrings, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - closeRequest; - return; - } - - for (int i = 0 ; i < countStrings ; i++) { - pStrings[i] = strdupReadString(p); - appendPrintBuf("%s%s,", printBuf, pStrings[i]); - } - } - removeLastChar; - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id); - - if (pStrings != NULL) { - for (int i = 0 ; i < countStrings ; i++) { -#ifdef MEMSET_FREED - memsetString (pStrings[i]); -#endif - free(pStrings[i]); - } - -#ifdef MEMSET_FREED - memset(pStrings, 0, datalen); -#endif - free(pStrings); - } - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -/** Callee expects const int * */ -static void -dispatchInts (Parcel &p, RequestInfo *pRI) { - int32_t count; - status_t status; - size_t datalen; - int *pInts; - - status = p.readInt32 (&count); - - if (status != NO_ERROR || count <= 0) { - goto invalid; - } - - datalen = sizeof(int) * count; - pInts = (int *)calloc(count, sizeof(int)); - if (pInts == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber)); - return; - } - - startRequest; - for (int i = 0 ; i < count ; i++) { - int32_t t; - - status = p.readInt32(&t); - pInts[i] = (int)t; - appendPrintBuf("%s%d,", printBuf, t); - - if (status != NO_ERROR) { - free(pInts); - goto invalid; - } - } - removeLastChar; - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast(pInts), - datalen, pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(pInts, 0, datalen); -#endif - free(pInts); - return; -invalid: - invalidCommandBlock(pRI); - return; -} - - -/** - * Callee expects const RIL_SMS_WriteArgs * - * Payload is: - * int32_t status - * String pdu - */ -static void -dispatchSmsWrite (Parcel &p, RequestInfo *pRI) { - RIL_SMS_WriteArgs args; - int32_t t; - status_t status; - - RLOGD("dispatchSmsWrite"); - memset (&args, 0, sizeof(args)); - - status = p.readInt32(&t); - args.status = (int)t; - - args.pdu = strdupReadString(p); - - if (status != NO_ERROR || args.pdu == NULL) { - goto invalid; - } - - args.smsc = strdupReadString(p); - - startRequest; - appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status, - (char*)args.pdu, (char*)args.smsc); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString (args.pdu); -#endif - - free (args.pdu); - -#ifdef MEMSET_FREED - memset(&args, 0, sizeof(args)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -/** - * Callee expects const RIL_Dial * - * Payload is: - * String address - * int32_t clir - */ -static void -dispatchDial (Parcel &p, RequestInfo *pRI) { - RIL_Dial dial; - RIL_UUS_Info uusInfo; - int32_t sizeOfDial; - int32_t t; - int32_t uusPresent; -#ifdef SAMSUNG_NEXT_GEN_MODEM - char *csv; -#endif - status_t status; - - RLOGD("dispatchDial"); - memset (&dial, 0, sizeof(dial)); - - dial.address = strdupReadString(p); - - status = p.readInt32(&t); - dial.clir = (int)t; - - if (status != NO_ERROR || dial.address == NULL) { - goto invalid; - } - -#ifdef SAMSUNG_NEXT_GEN_MODEM - /* CallDetails.call_type */ - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - /* CallDetails.call_domain */ - p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - /* CallDetails.getCsvFromExtra */ - csv = strdupReadString(p); - if (csv == NULL) { - goto invalid; - } - free(csv); -#endif - - if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3 - uusPresent = 0; - sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *); - } else { - status = p.readInt32(&uusPresent); - - if (status != NO_ERROR) { - goto invalid; - } - - if (uusPresent == 0) { -#if defined(MODEM_TYPE_XMM6262) || defined(SAMSUNG_NEXT_GEN_MODEM) - dial.uusInfo = NULL; -#elif defined(MODEM_TYPE_XMM6260) - /* Samsung hack */ - memset(&uusInfo, 0, sizeof(RIL_UUS_Info)); - uusInfo.uusType = (RIL_UUS_Type) 0; - uusInfo.uusDcs = (RIL_UUS_DCS) 0; - uusInfo.uusData = NULL; - uusInfo.uusLength = 0; - dial.uusInfo = &uusInfo; -#endif - } else { - int32_t len; - - memset(&uusInfo, 0, sizeof(RIL_UUS_Info)); - - status = p.readInt32(&t); - uusInfo.uusType = (RIL_UUS_Type) t; - - status = p.readInt32(&t); - uusInfo.uusDcs = (RIL_UUS_DCS) t; - - status = p.readInt32(&len); - if (status != NO_ERROR) { - goto invalid; - } - - // The java code writes -1 for null arrays - if (((int) len) == -1) { - uusInfo.uusData = NULL; - len = 0; - } else { - uusInfo.uusData = (char*) p.readInplace(len); - } - - uusInfo.uusLength = len; - dial.uusInfo = &uusInfo; - } - sizeOfDial = sizeof(dial); - } - - startRequest; - appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir); - if (uusPresent) { - appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf, - dial.uusInfo->uusType, dial.uusInfo->uusDcs, - dial.uusInfo->uusLength); - } - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString (dial.address); -#endif - - free (dial.address); - -#ifdef MEMSET_FREED - memset(&uusInfo, 0, sizeof(RIL_UUS_Info)); - memset(&dial, 0, sizeof(dial)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -/** - * Callee expects const RIL_SIM_IO * - * Payload is: - * int32_t command - * int32_t fileid - * String path - * int32_t p1, p2, p3 - * String data - * String pin2 - * String aidPtr - */ -static void -dispatchSIM_IO (Parcel &p, RequestInfo *pRI) { - union RIL_SIM_IO { - RIL_SIM_IO_v6 v6; - RIL_SIM_IO_v5 v5; - } simIO; - - int32_t t; - int size; - status_t status; - -#if VDBG - RLOGD("dispatchSIM_IO"); -#endif - memset (&simIO, 0, sizeof(simIO)); - - // note we only check status at the end - - status = p.readInt32(&t); - simIO.v6.command = (int)t; - - status = p.readInt32(&t); - simIO.v6.fileid = (int)t; - - simIO.v6.path = strdupReadString(p); - - status = p.readInt32(&t); - simIO.v6.p1 = (int)t; - - status = p.readInt32(&t); - simIO.v6.p2 = (int)t; - - status = p.readInt32(&t); - simIO.v6.p3 = (int)t; - - simIO.v6.data = strdupReadString(p); - simIO.v6.pin2 = strdupReadString(p); - simIO.v6.aidPtr = strdupReadString(p); - - startRequest; - appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf, - simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path, - simIO.v6.p1, simIO.v6.p2, simIO.v6.p3, - (char*)simIO.v6.data, (char*)simIO.v6.pin2, simIO.v6.aidPtr); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - if (status != NO_ERROR) { - goto invalid; - } - - size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6); - CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString (simIO.v6.path); - memsetString (simIO.v6.data); - memsetString (simIO.v6.pin2); - memsetString (simIO.v6.aidPtr); -#endif - - free (simIO.v6.path); - free (simIO.v6.data); - free (simIO.v6.pin2); - free (simIO.v6.aidPtr); - -#ifdef MEMSET_FREED - memset(&simIO, 0, sizeof(simIO)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -/** - * Callee expects const RIL_SIM_APDU * - * Payload is: - * int32_t sessionid - * int32_t cla - * int32_t instruction - * int32_t p1, p2, p3 - * String data - */ -static void -dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) { - int32_t t; - status_t status; - RIL_SIM_APDU apdu; - -#if VDBG - RLOGD("dispatchSIM_APDU"); -#endif - memset (&apdu, 0, sizeof(RIL_SIM_APDU)); - - // Note we only check status at the end. Any single failure leads to - // subsequent reads filing. - status = p.readInt32(&t); - apdu.sessionid = (int)t; - - status = p.readInt32(&t); - apdu.cla = (int)t; - - status = p.readInt32(&t); - apdu.instruction = (int)t; - - status = p.readInt32(&t); - apdu.p1 = (int)t; - - status = p.readInt32(&t); - apdu.p2 = (int)t; - - status = p.readInt32(&t); - apdu.p3 = (int)t; - - apdu.data = strdupReadString(p); - - startRequest; - appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s", - printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2, - apdu.p3, (char*)apdu.data); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - if (status != NO_ERROR) { - goto invalid; - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString(apdu.data); -#endif - free(apdu.data); - -#ifdef MEMSET_FREED - memset(&apdu, 0, sizeof(RIL_SIM_APDU)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - - -/** - * Callee expects const RIL_CallForwardInfo * - * Payload is: - * int32_t status/action - * int32_t reason - * int32_t serviceCode - * int32_t toa - * String number (0 length -> null) - * int32_t timeSeconds - */ -static void -dispatchCallForward(Parcel &p, RequestInfo *pRI) { - RIL_CallForwardInfo cff; - int32_t t; - status_t status; - - RLOGD("dispatchCallForward"); - memset (&cff, 0, sizeof(cff)); - - // note we only check status at the end - - status = p.readInt32(&t); - cff.status = (int)t; - - status = p.readInt32(&t); - cff.reason = (int)t; - - status = p.readInt32(&t); - cff.serviceClass = (int)t; - - status = p.readInt32(&t); - cff.toa = (int)t; - - cff.number = strdupReadString(p); - - status = p.readInt32(&t); - cff.timeSeconds = (int)t; - - if (status != NO_ERROR) { - goto invalid; - } - - // special case: number 0-length fields is null - - if (cff.number != NULL && strlen (cff.number) == 0) { - cff.number = NULL; - } - - startRequest; - appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf, - cff.status, cff.reason, cff.serviceClass, cff.toa, - (char*)cff.number, cff.timeSeconds); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString(cff.number); -#endif - - free (cff.number); - -#ifdef MEMSET_FREED - memset(&cff, 0, sizeof(cff)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - - -static void -dispatchRaw(Parcel &p, RequestInfo *pRI) { - int32_t len; - status_t status; - const void *data; - - status = p.readInt32(&len); - - if (status != NO_ERROR) { - goto invalid; - } - - // The java code writes -1 for null arrays - if (((int)len) == -1) { - data = NULL; - len = 0; - } - - data = p.readInplace(len); - - startRequest; - appendPrintBuf("%sraw_size=%d", printBuf, len); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast(data), len, pRI, pRI->socket_id); - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -static status_t -constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) { - int32_t t; - uint8_t ut; - status_t status; - int32_t digitCount; - int digitLimit; - - memset(&rcsm, 0, sizeof(rcsm)); - - status = p.readInt32(&t); - rcsm.uTeleserviceID = (int) t; - - status = p.read(&ut,sizeof(ut)); - rcsm.bIsServicePresent = (uint8_t) ut; - - status = p.readInt32(&t); - rcsm.uServicecategory = (int) t; - - status = p.readInt32(&t); - rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t; - - status = p.readInt32(&t); - rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t; - - status = p.readInt32(&t); - rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t; - - status = p.readInt32(&t); - rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t; - - status = p.read(&ut,sizeof(ut)); - rcsm.sAddress.number_of_digits= (uint8_t) ut; - - digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); - for(digitCount =0 ; digitCount < digitLimit; digitCount ++) { - status = p.read(&ut,sizeof(ut)); - rcsm.sAddress.digits[digitCount] = (uint8_t) ut; - } - - status = p.readInt32(&t); - rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t; - - status = p.read(&ut,sizeof(ut)); - rcsm.sSubAddress.odd = (uint8_t) ut; - - status = p.read(&ut,sizeof(ut)); - rcsm.sSubAddress.number_of_digits = (uint8_t) ut; - - digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); - for(digitCount =0 ; digitCount < digitLimit; digitCount ++) { - status = p.read(&ut,sizeof(ut)); - rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut; - } - - status = p.readInt32(&t); - rcsm.uBearerDataLen = (int) t; - - digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); - for(digitCount =0 ; digitCount < digitLimit; digitCount ++) { - status = p.read(&ut, sizeof(ut)); - rcsm.aBearerData[digitCount] = (uint8_t) ut; - } - - if (status != NO_ERROR) { - return status; - } - - startRequest; - appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \ - sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ", - printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory, - rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type); - closeRequest; - - printRequest(pRI->token, pRI->pCI->requestNumber); - - return status; -} - -static void -dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { - RIL_CDMA_SMS_Message rcsm; - - RLOGD("dispatchCdmaSms"); - if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) { - goto invalid; - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(&rcsm, 0, sizeof(rcsm)); -#endif - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void -dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) { - RIL_IMS_SMS_Message rism; - RIL_CDMA_SMS_Message rcsm; - - RLOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef); - - if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) { - goto invalid; - } - memset(&rism, 0, sizeof(rism)); - rism.tech = RADIO_TECH_3GPP2; - rism.retry = retry; - rism.messageRef = messageRef; - rism.message.cdmaMessage = &rcsm; - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, - sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) - +sizeof(rcsm),pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(&rcsm, 0, sizeof(rcsm)); - memset(&rism, 0, sizeof(rism)); -#endif - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void -dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) { - RIL_IMS_SMS_Message rism; - int32_t countStrings; - status_t status; - size_t datalen; - char **pStrings; - RLOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef); - - status = p.readInt32 (&countStrings); - - if (status != NO_ERROR) { - goto invalid; - } - - memset(&rism, 0, sizeof(rism)); - rism.tech = RADIO_TECH_3GPP; - rism.retry = retry; - rism.messageRef = messageRef; - - startRequest; - appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf, - (int)rism.tech, (int)rism.retry, rism.messageRef); - if (countStrings == 0) { - // just some non-null pointer - pStrings = (char **)calloc(1, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - closeRequest; - return; - } - - datalen = 0; - } else if (countStrings < 0) { - pStrings = NULL; - datalen = 0; - } else { - if ((size_t)countStrings > (INT_MAX/sizeof(char *))) { - RLOGE("Invalid value of countStrings: \n"); - closeRequest; - return; - } - datalen = sizeof(char *) * countStrings; - - pStrings = (char **)calloc(countStrings, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - closeRequest; - return; - } - - for (int i = 0 ; i < countStrings ; i++) { - pStrings[i] = strdupReadString(p); - appendPrintBuf("%s%s,", printBuf, pStrings[i]); - } - } - removeLastChar; - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - rism.message.gsmMessage = pStrings; - CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, - sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) - +datalen, pRI, pRI->socket_id); - - if (pStrings != NULL) { - for (int i = 0 ; i < countStrings ; i++) { -#ifdef MEMSET_FREED - memsetString (pStrings[i]); -#endif - free(pStrings[i]); - } - -#ifdef MEMSET_FREED - memset(pStrings, 0, datalen); -#endif - free(pStrings); - } - -#ifdef MEMSET_FREED - memset(&rism, 0, sizeof(rism)); -#endif - return; -invalid: - ALOGE("dispatchImsGsmSms invalid block"); - invalidCommandBlock(pRI); - return; -} - -static void -dispatchImsSms(Parcel &p, RequestInfo *pRI) { - int32_t t; - status_t status = p.readInt32(&t); - RIL_RadioTechnologyFamily format; - uint8_t retry; - int32_t messageRef; - - RLOGD("dispatchImsSms"); - if (status != NO_ERROR) { - goto invalid; - } - format = (RIL_RadioTechnologyFamily) t; - - // read retry field - status = p.read(&retry,sizeof(retry)); - if (status != NO_ERROR) { - goto invalid; - } - // read messageRef field - status = p.read(&messageRef,sizeof(messageRef)); - if (status != NO_ERROR) { - goto invalid; - } - - if (RADIO_TECH_3GPP == format) { - dispatchImsGsmSms(p, pRI, retry, messageRef); - } else if (RADIO_TECH_3GPP2 == format) { - dispatchImsCdmaSms(p, pRI, retry, messageRef); - } else { - ALOGE("requestImsSendSMS invalid format value =%d", format); - } - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void -dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) { - RIL_CDMA_SMS_Ack rcsa; - int32_t t; - status_t status; - int32_t digitCount; - - RLOGD("dispatchCdmaSmsAck"); - memset(&rcsa, 0, sizeof(rcsa)); - - status = p.readInt32(&t); - rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t; - - status = p.readInt32(&t); - rcsa.uSMSCauseCode = (int) t; - - if (status != NO_ERROR) { - goto invalid; - } - - startRequest; - appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ", - printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode); - closeRequest; - - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(&rcsa, 0, sizeof(rcsa)); -#endif - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void -dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) { - int32_t t; - status_t status; - int32_t num; - - status = p.readInt32(&num); - if (status != NO_ERROR) { - goto invalid; - } - - { - RIL_GSM_BroadcastSmsConfigInfo gsmBci[num]; - RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num]; - - startRequest; - for (int i = 0 ; i < num ; i++ ) { - gsmBciPtrs[i] = &gsmBci[i]; - - status = p.readInt32(&t); - gsmBci[i].fromServiceId = (int) t; - - status = p.readInt32(&t); - gsmBci[i].toServiceId = (int) t; - - status = p.readInt32(&t); - gsmBci[i].fromCodeScheme = (int) t; - - status = p.readInt32(&t); - gsmBci[i].toCodeScheme = (int) t; - - status = p.readInt32(&t); - gsmBci[i].selected = (uint8_t) t; - - appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \ - fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i, - gsmBci[i].fromServiceId, gsmBci[i].toServiceId, - gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme, - gsmBci[i].selected); - } - closeRequest; - - if (status != NO_ERROR) { - goto invalid; - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, - gsmBciPtrs, - num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), - pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo)); - memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *)); -#endif - } - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void -dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) { - int32_t t; - status_t status; - int32_t num; - - status = p.readInt32(&num); - if (status != NO_ERROR) { - goto invalid; - } - - { - RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num]; - RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num]; - - startRequest; - for (int i = 0 ; i < num ; i++ ) { - cdmaBciPtrs[i] = &cdmaBci[i]; - - status = p.readInt32(&t); - cdmaBci[i].service_category = (int) t; - - status = p.readInt32(&t); - cdmaBci[i].language = (int) t; - - status = p.readInt32(&t); - cdmaBci[i].selected = (uint8_t) t; - - appendPrintBuf("%s [%d: service_category=%d, language =%d, \ - entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category, - cdmaBci[i].language, cdmaBci[i].selected); - } - closeRequest; - - if (status != NO_ERROR) { - goto invalid; - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, - cdmaBciPtrs, - num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), - pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo)); - memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *)); -#endif - } - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) { - RIL_CDMA_SMS_WriteArgs rcsw; - int32_t t; - uint32_t ut; - uint8_t uct; - status_t status; - int32_t digitCount; - int32_t digitLimit; - - memset(&rcsw, 0, sizeof(rcsw)); - - status = p.readInt32(&t); - rcsw.status = t; - - status = p.readInt32(&t); - rcsw.message.uTeleserviceID = (int) t; - - status = p.read(&uct,sizeof(uct)); - rcsw.message.bIsServicePresent = (uint8_t) uct; - - status = p.readInt32(&t); - rcsw.message.uServicecategory = (int) t; - - status = p.readInt32(&t); - rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t; - - status = p.readInt32(&t); - rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t; - - status = p.readInt32(&t); - rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t; - - status = p.readInt32(&t); - rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t; - - status = p.read(&uct,sizeof(uct)); - rcsw.message.sAddress.number_of_digits = (uint8_t) uct; - - digitLimit = MIN((rcsw.message.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); - - for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) { - status = p.read(&uct,sizeof(uct)); - rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct; - } - - status = p.readInt32(&t); - rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t; - - status = p.read(&uct,sizeof(uct)); - rcsw.message.sSubAddress.odd = (uint8_t) uct; - - status = p.read(&uct,sizeof(uct)); - rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct; - - digitLimit = MIN((rcsw.message.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); - - for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) { - status = p.read(&uct,sizeof(uct)); - rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct; - } - - status = p.readInt32(&t); - rcsw.message.uBearerDataLen = (int) t; - - digitLimit = MIN((rcsw.message.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); - - for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) { - status = p.read(&uct, sizeof(uct)); - rcsw.message.aBearerData[digitCount] = (uint8_t) uct; - } - - if (status != NO_ERROR) { - goto invalid; - } - - startRequest; - appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \ - message.uServicecategory=%d, message.sAddress.digit_mode=%d, \ - message.sAddress.number_mode=%d, \ - message.sAddress.number_type=%d, ", - printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent, - rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode, - rcsw.message.sAddress.number_mode, - rcsw.message.sAddress.number_type); - closeRequest; - - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(&rcsw, 0, sizeof(rcsw)); -#endif - - return; - -invalid: - invalidCommandBlock(pRI); - return; - -} - -// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL. -// Version 4 of the RIL interface adds a new PDP type parameter to support -// IPv6 and dual-stack PDP contexts. When dealing with a previous version of -// RIL, remove the parameter from the request. -static void dispatchDataCall(Parcel& p, RequestInfo *pRI) { - // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters. - const int numParamsRilV3 = 6; - - // The first bytes of the RIL parcel contain the request number and the - // serial number - see processCommandBuffer(). Copy them over too. - int pos = p.dataPosition(); - - int numParams = p.readInt32(); - if (s_callbacks.version < 4 && numParams > numParamsRilV3) { - Parcel p2; - p2.appendFrom(&p, 0, pos); - p2.writeInt32(numParamsRilV3); - for(int i = 0; i < numParamsRilV3; i++) { - p2.writeString16(p.readString16()); - } - p2.setDataPosition(pos); - dispatchStrings(p2, pRI); - } else { - p.setDataPosition(pos); - dispatchStrings(p, pRI); - } -} - -// For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH. -// When all RILs handle this request, this function can be removed and -// the request can be sent directly to the RIL using dispatchVoid. -static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) { - RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id); - - if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) { - RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - } - - // RILs that support RADIO_STATE_ON should support this request. - if (RADIO_STATE_ON == state) { - dispatchVoid(p, pRI); - return; - } - - // For Older RILs, that do not support RADIO_STATE_ON, assume that they - // will not support this new request either and decode Voice Radio Technology - // from Radio State - voiceRadioTech = decodeVoiceRadioTechnology(state); - - if (voiceRadioTech < 0) - RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0); - else - RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int)); -} - -// For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:. -// When all RILs handle this request, this function can be removed and -// the request can be sent directly to the RIL using dispatchVoid. -static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) { - RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id); - - if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) { - RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - } - - // RILs that support RADIO_STATE_ON should support this request. - if (RADIO_STATE_ON == state) { - dispatchVoid(p, pRI); - return; - } - - // For Older RILs, that do not support RADIO_STATE_ON, assume that they - // will not support this new request either and decode CDMA Subscription Source - // from Radio State - cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state); - - if (cdmaSubscriptionSource < 0) - RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0); - else - RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int)); -} - -static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI) -{ - RIL_InitialAttachApn pf; - int32_t t; - status_t status; - - memset(&pf, 0, sizeof(pf)); - - pf.apn = strdupReadString(p); - pf.protocol = strdupReadString(p); - - status = p.readInt32(&t); - pf.authtype = (int) t; - - pf.username = strdupReadString(p); - pf.password = strdupReadString(p); - - startRequest; - appendPrintBuf("%sapn=%s, protocol=%s, authtype=%d, username=%s, password=%s", - printBuf, pf.apn, pf.protocol, pf.authtype, pf.username, pf.password); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - if (status != NO_ERROR) { - goto invalid; - } - CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString(pf.apn); - memsetString(pf.protocol); - memsetString(pf.username); - memsetString(pf.password); -#endif - - free(pf.apn); - free(pf.protocol); - free(pf.username); - free(pf.password); - -#ifdef MEMSET_FREED - memset(&pf, 0, sizeof(pf)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) { - RIL_NV_ReadItem nvri; - int32_t t; - status_t status; - - memset(&nvri, 0, sizeof(nvri)); - - status = p.readInt32(&t); - nvri.itemID = (RIL_NV_Item) t; - - if (status != NO_ERROR) { - goto invalid; - } - - startRequest; - appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID); - closeRequest; - - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(&nvri, 0, sizeof(nvri)); -#endif - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) { - RIL_NV_WriteItem nvwi; - int32_t t; - status_t status; - - memset(&nvwi, 0, sizeof(nvwi)); - - status = p.readInt32(&t); - nvwi.itemID = (RIL_NV_Item) t; - - nvwi.value = strdupReadString(p); - - if (status != NO_ERROR || nvwi.value == NULL) { - goto invalid; - } - - startRequest; - appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID, - nvwi.value); - closeRequest; - - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString(nvwi.value); -#endif - - free(nvwi.value); - -#ifdef MEMSET_FREED - memset(&nvwi, 0, sizeof(nvwi)); -#endif - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - - -static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) { - RIL_SelectUiccSub uicc_sub; - status_t status; - int32_t t; - memset(&uicc_sub, 0, sizeof(uicc_sub)); - - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - uicc_sub.slot = (int) t; - - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - uicc_sub.app_index = (int) t; - - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - uicc_sub.sub_type = (RIL_SubscriptionType) t; - - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - uicc_sub.act_status = (RIL_UiccSubActStatus) t; - - startRequest; - appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index, - uicc_sub.act_status); - RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, - uicc_sub.app_index, uicc_sub.act_status); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(&uicc_sub, 0, sizeof(uicc_sub)); -#endif - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI) -{ - RIL_SimAuthentication pf; - int32_t t; - status_t status; - - memset(&pf, 0, sizeof(pf)); - - status = p.readInt32(&t); - pf.authContext = (int) t; - pf.authData = strdupReadString(p); - pf.aid = strdupReadString(p); - - startRequest; - appendPrintBuf("authContext=%s, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid); - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - if (status != NO_ERROR) { - goto invalid; - } - CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memsetString(pf.authData); - memsetString(pf.aid); -#endif - - free(pf.authData); - free(pf.aid); - -#ifdef MEMSET_FREED - memset(&pf, 0, sizeof(pf)); -#endif - - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) { - int32_t t; - status_t status; - int32_t num; - - status = p.readInt32(&num); - if (status != NO_ERROR || num < 0) { - goto invalid; - } - - { - RIL_DataProfileInfo *dataProfiles = - (RIL_DataProfileInfo *)calloc(num, sizeof(RIL_DataProfileInfo)); - if (dataProfiles == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - return; - } - RIL_DataProfileInfo **dataProfilePtrs = - (RIL_DataProfileInfo **)calloc(num, sizeof(RIL_DataProfileInfo *)); - if (dataProfilePtrs == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - free(dataProfiles); - return; - } - - startRequest; - for (int i = 0 ; i < num ; i++ ) { - dataProfilePtrs[i] = &dataProfiles[i]; - - status = p.readInt32(&t); - dataProfiles[i].profileId = (int) t; - - dataProfiles[i].apn = strdupReadString(p); - dataProfiles[i].protocol = strdupReadString(p); - status = p.readInt32(&t); - dataProfiles[i].authType = (int) t; - - dataProfiles[i].user = strdupReadString(p); - dataProfiles[i].password = strdupReadString(p); - - status = p.readInt32(&t); - dataProfiles[i].type = (int) t; - - status = p.readInt32(&t); - dataProfiles[i].maxConnsTime = (int) t; - status = p.readInt32(&t); - dataProfiles[i].maxConns = (int) t; - status = p.readInt32(&t); - dataProfiles[i].waitTime = (int) t; - - status = p.readInt32(&t); - dataProfiles[i].enabled = (int) t; - - appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \ - user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \ - waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId, - dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType, - dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type, - dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns, - dataProfiles[i].waitTime, dataProfiles[i].enabled); - } - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - if (status != NO_ERROR) { - free(dataProfiles); - free(dataProfilePtrs); - goto invalid; - } - CALL_ONREQUEST(pRI->pCI->requestNumber, - dataProfilePtrs, - num * sizeof(RIL_DataProfileInfo *), - pRI, pRI->socket_id); - -#ifdef MEMSET_FREED - memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo)); - memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *)); -#endif - free(dataProfiles); - free(dataProfilePtrs); - } - - return; - -invalid: - invalidCommandBlock(pRI); - return; -} - -static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){ - RIL_RadioCapability rc; - int32_t t; - status_t status; - - memset (&rc, 0, sizeof(RIL_RadioCapability)); - - status = p.readInt32(&t); - rc.version = (int)t; - if (status != NO_ERROR) { - goto invalid; - } - - status = p.readInt32(&t); - rc.session= (int)t; - if (status != NO_ERROR) { - goto invalid; - } - - status = p.readInt32(&t); - rc.phase= (int)t; - if (status != NO_ERROR) { - goto invalid; - } - - status = p.readInt32(&t); - rc.rat = (int)t; - if (status != NO_ERROR) { - goto invalid; - } - - status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid)); - if (status != NO_ERROR) { - goto invalid; - } - - status = p.readInt32(&t); - rc.status = (int)t; - - if (status != NO_ERROR) { - goto invalid; - } - - startRequest; - appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \ - logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session, - rc.phase, rc.rat, rc.logicalModemUuid, rc.session); - - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, - &rc, - sizeof(RIL_RadioCapability), - pRI, pRI->socket_id); - return; -invalid: - invalidCommandBlock(pRI); - return; -} - -/** - * Callee expects const RIL_CarrierRestrictions * - */ -static void dispatchCarrierRestrictions(Parcel &p, RequestInfo *pRI) { - RIL_CarrierRestrictions cr; - RIL_Carrier * allowed_carriers = NULL; - RIL_Carrier * excluded_carriers = NULL; - int32_t t; - status_t status; - - memset(&cr, 0, sizeof(RIL_CarrierRestrictions)); - - if (s_callbacks.version < 14) { - RLOGE("Unsuppoted RIL version %d, min version expected %d", - s_callbacks.version, 14); - RIL_onRequestComplete(pRI, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); - return; - } - - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - allowed_carriers = (RIL_Carrier *)calloc(t, sizeof(RIL_Carrier)); - if (allowed_carriers == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber)); - goto exit; - } - cr.len_allowed_carriers = t; - cr.allowed_carriers = allowed_carriers; - - status = p.readInt32(&t); - if (status != NO_ERROR) { - goto invalid; - } - excluded_carriers = (RIL_Carrier *)calloc(t, sizeof(RIL_Carrier)); - if (excluded_carriers == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber)); - goto exit; - } - cr.len_excluded_carriers = t; - cr.excluded_carriers = excluded_carriers; - - startRequest; - appendPrintBuf("%s len_allowed_carriers:%d, len_excluded_carriers:%d,", - printBuf, cr.len_allowed_carriers, cr.len_excluded_carriers); - - appendPrintBuf("%s allowed_carriers:", printBuf); - for (int32_t i = 0; i < cr.len_allowed_carriers; i++) { - RIL_Carrier *p_cr = allowed_carriers + i; - p_cr->mcc = strdupReadString(p); - p_cr->mnc = strdupReadString(p); - status = p.readInt32(&t); - p_cr->match_type = static_cast(t); - if (status != NO_ERROR) { - goto invalid; - } - p_cr->match_data = strdupReadString(p); - appendPrintBuf("%s [%d mcc:%s, mnc:%s, match_type:%d, match_data:%s],", - printBuf, i, p_cr->mcc, p_cr->mnc, p_cr->match_type, p_cr->match_data); - } - - for (int32_t i = 0; i < cr.len_excluded_carriers; i++) { - RIL_Carrier *p_cr = excluded_carriers + i; - p_cr->mcc = strdupReadString(p); - p_cr->mnc = strdupReadString(p); - status = p.readInt32(&t); - p_cr->match_type = static_cast(t); - if (status != NO_ERROR) { - goto invalid; - } - p_cr->match_data = strdupReadString(p); - appendPrintBuf("%s [%d mcc:%s, mnc:%s, match_type:%d, match_data:%s],", - printBuf, i, p_cr->mcc, p_cr->mnc, p_cr->match_type, p_cr->match_data); - } - - closeRequest; - printRequest(pRI->token, pRI->pCI->requestNumber); - - CALL_ONREQUEST(pRI->pCI->requestNumber, - &cr, - sizeof(RIL_CarrierRestrictions), - pRI, pRI->socket_id); - - goto exit; - -invalid: - invalidCommandBlock(pRI); - RIL_onRequestComplete(pRI, RIL_E_INVALID_ARGUMENTS, NULL, 0); -exit: - if (allowed_carriers != NULL) { - free(allowed_carriers); - } - if (excluded_carriers != NULL) { - free(excluded_carriers); - } - return; -} - -static int -blockingWrite(int fd, const void *buffer, size_t len) { - size_t writeOffset = 0; - const uint8_t *toWrite; - - toWrite = (const uint8_t *)buffer; - - while (writeOffset < len) { - ssize_t written; - do { - written = write (fd, toWrite + writeOffset, - len - writeOffset); - } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN))); - - if (written >= 0) { - writeOffset += written; - } else { // written < 0 - RLOGE ("RIL Response: unexpected error on write errno:%d", errno); - close(fd); - return -1; - } - } -#if VDBG - RLOGE("RIL Response bytes written:%d", writeOffset); -#endif - return 0; -} - -static int -sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) { - int fd = s_ril_param_socket.fdCommand; - int ret; - uint32_t header; - pthread_mutex_t * writeMutexHook = &s_writeMutex; - -#if VDBG - RLOGE("Send Response to %s", rilSocketIdToString(socket_id)); -#endif - -#if (SIM_COUNT >= 2) - if (socket_id == RIL_SOCKET_2) { - fd = s_ril_param_socket2.fdCommand; - writeMutexHook = &s_writeMutex_socket2; - } -#if (SIM_COUNT >= 3) - else if (socket_id == RIL_SOCKET_3) { - fd = s_ril_param_socket3.fdCommand; - writeMutexHook = &s_writeMutex_socket3; - } -#endif -#if (SIM_COUNT >= 4) - else if (socket_id == RIL_SOCKET_4) { - fd = s_ril_param_socket4.fdCommand; - writeMutexHook = &s_writeMutex_socket4; - } -#endif -#endif - if (fd < 0) { - return -1; - } - - if (dataSize > MAX_COMMAND_BYTES) { - RLOGE("RIL: packet larger than %u (%u)", - MAX_COMMAND_BYTES, (unsigned int )dataSize); - - return -1; - } - - pthread_mutex_lock(writeMutexHook); - - header = htonl(dataSize); - - ret = blockingWrite(fd, (void *)&header, sizeof(header)); - - if (ret < 0) { - pthread_mutex_unlock(writeMutexHook); - return ret; - } - - ret = blockingWrite(fd, data, dataSize); - - if (ret < 0) { - pthread_mutex_unlock(writeMutexHook); - return ret; - } - - pthread_mutex_unlock(writeMutexHook); - - return 0; -} - -static int -sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) { - printResponse; - return sendResponseRaw(p.data(), p.dataSize(), socket_id); -} - -/** response is an int* pointing to an array of ints */ - -static int -responseInts(Parcel &p, void *response, size_t responselen) { - int numInts; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - if (responselen % sizeof(int) != 0) { - RLOGE("responseInts: invalid response length %d expected multiple of %d\n", - (int)responselen, (int)sizeof(int)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - int *p_int = (int *) response; - - numInts = responselen / sizeof(int); - p.writeInt32 (numInts); - - /* each int*/ - startResponse; - for (int i = 0 ; i < numInts ; i++) { - appendPrintBuf("%s%d,", printBuf, p_int[i]); - p.writeInt32(p_int[i]); - } - removeLastChar; - closeResponse; - - return 0; -} - -// Response is an int or RIL_LastCallFailCauseInfo. -// Currently, only Shamu plans to use RIL_LastCallFailCauseInfo. -// TODO(yjl): Let all implementations use RIL_LastCallFailCauseInfo. -static int responseFailCause(Parcel &p, void *response, size_t responselen) { - int numInts; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - if (responselen == sizeof(int)) { - startResponse; - int *p_int = (int *) response; - appendPrintBuf("%s%d,", printBuf, p_int[0]); - p.writeInt32(p_int[0]); - removeLastChar; - closeResponse; - } else if (responselen == sizeof(RIL_LastCallFailCauseInfo)) { - startResponse; - RIL_LastCallFailCauseInfo *p_fail_cause_info = (RIL_LastCallFailCauseInfo *) response; - appendPrintBuf("%s[cause_code=%d,vendor_cause=%s]", printBuf, p_fail_cause_info->cause_code, - p_fail_cause_info->vendor_cause); - p.writeInt32(p_fail_cause_info->cause_code); - writeStringToParcel(p, p_fail_cause_info->vendor_cause); - removeLastChar; - closeResponse; - } else { - RLOGE("responseFailCause: invalid response length %d expected an int or " - "RIL_LastCallFailCauseInfo", (int)responselen); - return RIL_ERRNO_INVALID_RESPONSE; - } - - return 0; -} - -/** response is a char **, pointing to an array of char *'s - The parcel will begin with the version */ -static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) { - p.writeInt32(version); - return responseStrings(p, response, responselen); -} - -/** response is a char **, pointing to an array of char *'s */ -static int responseStrings(Parcel &p, void *response, size_t responselen) { - int numStrings; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - if (responselen % sizeof(char *) != 0) { - RLOGE("responseStrings: invalid response length %d expected multiple of %d\n", - (int)responselen, (int)sizeof(char *)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (response == NULL) { - p.writeInt32 (0); - } else { - char **p_cur = (char **) response; - - numStrings = responselen / sizeof(char *); - p.writeInt32 (numStrings); - - /* each string*/ - startResponse; - for (int i = 0 ; i < numStrings ; i++) { - appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]); - writeStringToParcel (p, p_cur[i]); - } - removeLastChar; - closeResponse; - } - return 0; -} - - -/** - * NULL strings are accepted - * FIXME currently ignores responselen - */ -static int responseString(Parcel &p, void *response, size_t responselen) { - /* one string only */ - startResponse; - appendPrintBuf("%s%s", printBuf, (char*)response); - closeResponse; - - writeStringToParcel(p, (const char *)response); - - return 0; -} - -static int responseVoid(Parcel &p, void *response, size_t responselen) { - startResponse; - removeLastChar; - return 0; -} - -static int responseCallList(Parcel &p, void *response, size_t responselen) { - int num; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof (RIL_Call *) != 0) { - RLOGE("responseCallList: invalid response length %d expected multiple of %d\n", - (int)responselen, (int)sizeof (RIL_Call *)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - startResponse; - /* number of call info's */ - num = responselen / sizeof(RIL_Call *); - p.writeInt32(num); - - for (int i = 0 ; i < num ; i++) { - RIL_Call *p_cur = ((RIL_Call **) response)[i]; - /* each call info */ - p.writeInt32(p_cur->state); - p.writeInt32(p_cur->index); - p.writeInt32(p_cur->toa); - p.writeInt32(p_cur->isMpty); - p.writeInt32(p_cur->isMT); - p.writeInt32(p_cur->als); - p.writeInt32(p_cur->isVoice); - -#ifdef NEEDS_VIDEO_CALL_FIELD - p.writeInt32(p_cur->isVideo); -#endif - -#ifdef SAMSUNG_NEXT_GEN_MODEM - /* Pass CallDetails */ - p.writeInt32(0); - p.writeInt32(0); - writeStringToParcel(p, ""); -#endif - - p.writeInt32(p_cur->isVoicePrivacy); - writeStringToParcel(p, p_cur->number); - p.writeInt32(p_cur->numberPresentation); - writeStringToParcel(p, p_cur->name); - p.writeInt32(p_cur->namePresentation); - // Remove when partners upgrade to version 3 - if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) { - p.writeInt32(0); /* UUS Information is absent */ - } else { - RIL_UUS_Info *uusInfo = p_cur->uusInfo; - p.writeInt32(1); /* UUS Information is present */ - p.writeInt32(uusInfo->uusType); - p.writeInt32(uusInfo->uusDcs); - p.writeInt32(uusInfo->uusLength); - p.write(uusInfo->uusData, uusInfo->uusLength); - } - appendPrintBuf("%s[id=%d,%s,toa=%d,", - printBuf, - p_cur->index, - callStateToString(p_cur->state), - p_cur->toa); - appendPrintBuf("%s%s,%s,als=%d,%s,%s,", - printBuf, - (p_cur->isMpty)?"conf":"norm", - (p_cur->isMT)?"mt":"mo", - p_cur->als, - (p_cur->isVoice)?"voc":"nonvoc", - (p_cur->isVoicePrivacy)?"evp":"noevp"); -#ifdef SAMSUNG_NEXT_GEN_MODEM - appendPrintBuf("%s,%s,", - printBuf, - (p_cur->isVideo) ? "vid" : "novid"); -#endif - appendPrintBuf("%s%s,cli=%d,name='%s',%d]", - printBuf, - p_cur->number, - p_cur->numberPresentation, - p_cur->name, - p_cur->namePresentation); - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseSMS(Parcel &p, void *response, size_t responselen) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof (RIL_SMS_Response) ) { - RLOGE("invalid response length %d expected %d", - (int)responselen, (int)sizeof (RIL_SMS_Response)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response; - - p.writeInt32(p_cur->messageRef); - writeStringToParcel(p, p_cur->ackPDU); - p.writeInt32(p_cur->errorCode); - - startResponse; - appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef, - (char*)p_cur->ackPDU, p_cur->errorCode); - closeResponse; - - return 0; -} - -static int responseDataCallListV4(Parcel &p, void *response, size_t responselen) -{ - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) { - RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - // Write version - p.writeInt32(4); - - int num = responselen / sizeof(RIL_Data_Call_Response_v4); - p.writeInt32(num); - - RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response; - startResponse; - int i; - for (i = 0; i < num; i++) { - p.writeInt32(p_cur[i].cid); - p.writeInt32(p_cur[i].active); - writeStringToParcel(p, p_cur[i].type); - // apn is not used, so don't send. - writeStringToParcel(p, p_cur[i].address); - appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf, - p_cur[i].cid, - (p_cur[i].active==0)?"down":"up", - (char*)p_cur[i].type, - (char*)p_cur[i].address); - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseDataCallListV6(Parcel &p, void *response, size_t responselen) -{ - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) { - RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - // Write version - p.writeInt32(6); - - int num = responselen / sizeof(RIL_Data_Call_Response_v6); - p.writeInt32(num); - - RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response; - startResponse; - int i; - for (i = 0; i < num; i++) { - p.writeInt32((int)p_cur[i].status); - p.writeInt32(p_cur[i].suggestedRetryTime); - p.writeInt32(p_cur[i].cid); - p.writeInt32(p_cur[i].active); - writeStringToParcel(p, p_cur[i].type); - writeStringToParcel(p, p_cur[i].ifname); - writeStringToParcel(p, p_cur[i].addresses); - writeStringToParcel(p, p_cur[i].dnses); -#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM6260) - writeStringToParcel(p, p_cur[i].addresses); -#else - writeStringToParcel(p, p_cur[i].gateways); -#endif - appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf, - p_cur[i].status, - p_cur[i].suggestedRetryTime, - p_cur[i].cid, - (p_cur[i].active==0)?"down":"up", - (char*)p_cur[i].type, - (char*)p_cur[i].ifname, - (char*)p_cur[i].addresses, - (char*)p_cur[i].dnses, -#if defined(MODEM_TYPE_XMM6262) || defined(MODEM_TYPE_XMM6260) - (char*)p_cur[i].addresses -#else - (char*)p_cur[i].gateways -#endif - ); - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseDataCallListV9(Parcel &p, void *response, size_t responselen) -{ - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) { - RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - // Write version - p.writeInt32(10); - - int num = responselen / sizeof(RIL_Data_Call_Response_v9); - p.writeInt32(num); - - RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response; - startResponse; - int i; - for (i = 0; i < num; i++) { - p.writeInt32((int)p_cur[i].status); - p.writeInt32(p_cur[i].suggestedRetryTime); - p.writeInt32(p_cur[i].cid); - p.writeInt32(p_cur[i].active); - writeStringToParcel(p, p_cur[i].type); - writeStringToParcel(p, p_cur[i].ifname); - writeStringToParcel(p, p_cur[i].addresses); - writeStringToParcel(p, p_cur[i].dnses); - writeStringToParcel(p, p_cur[i].gateways); - writeStringToParcel(p, p_cur[i].pcscf); - appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf, - p_cur[i].status, - p_cur[i].suggestedRetryTime, - p_cur[i].cid, - (p_cur[i].active==0)?"down":"up", - (char*)p_cur[i].type, - (char*)p_cur[i].ifname, - (char*)p_cur[i].addresses, - (char*)p_cur[i].dnses, - (char*)p_cur[i].gateways, - (char*)p_cur[i].pcscf); - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseDataCallListV11(Parcel &p, void *response, size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) { - RLOGE("invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - // Write version - p.writeInt32(11); - - int num = responselen / sizeof(RIL_Data_Call_Response_v11); - p.writeInt32(num); - - RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response; - startResponse; - int i; - for (i = 0; i < num; i++) { - p.writeInt32((int)p_cur[i].status); - p.writeInt32(p_cur[i].suggestedRetryTime); - p.writeInt32(p_cur[i].cid); - p.writeInt32(p_cur[i].active); - writeStringToParcel(p, p_cur[i].type); - writeStringToParcel(p, p_cur[i].ifname); - writeStringToParcel(p, p_cur[i].addresses); - writeStringToParcel(p, p_cur[i].dnses); - writeStringToParcel(p, p_cur[i].gateways); - writeStringToParcel(p, p_cur[i].pcscf); - p.writeInt32(p_cur[i].mtu); - appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf, - p_cur[i].status, - p_cur[i].suggestedRetryTime, - p_cur[i].cid, - (p_cur[i].active==0)?"down":"up", - (char*)p_cur[i].type, - (char*)p_cur[i].ifname, - (char*)p_cur[i].addresses, - (char*)p_cur[i].dnses, - (char*)p_cur[i].gateways, - (char*)p_cur[i].pcscf, - p_cur[i].mtu); - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseDataCallList(Parcel &p, void *response, size_t responselen) -{ - if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) { - if (s_callbacks.version < 5) { - RLOGD("responseDataCallList: v4"); - return responseDataCallListV4(p, response, responselen); - } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) { - return responseDataCallListV6(p, response, responselen); - } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) { - return responseDataCallListV9(p, response, responselen); - } else { - return responseDataCallListV11(p, response, responselen); - } - } else { // RIL version >= 13 - if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) { - RLOGE("Data structure expected is RIL_Data_Call_Response_v11"); - if (!isDebuggable()) { - return RIL_ERRNO_INVALID_RESPONSE; - } else { - assert(0); - } - } - return responseDataCallListV11(p, response, responselen); - } -} - -static int responseSetupDataCall(Parcel &p, void *response, size_t responselen) -{ - if (s_callbacks.version < 5) { - return responseStringsWithVersion(s_callbacks.version, p, response, responselen); - } else { - return responseDataCallList(p, response, responselen); - } -} - -static int responseRaw(Parcel &p, void *response, size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL with responselen != 0"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - // The java code reads -1 size as null byte array - if (response == NULL) { - p.writeInt32(-1); - } else { - p.writeInt32(responselen); - p.write(response, responselen); - } - - return 0; -} - - -static int responseSIM_IO(Parcel &p, void *response, size_t responselen) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof (RIL_SIM_IO_Response) ) { - RLOGE("invalid response length was %d expected %d", - (int)responselen, (int)sizeof (RIL_SIM_IO_Response)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response; - p.writeInt32(p_cur->sw1); - p.writeInt32(p_cur->sw2); - writeStringToParcel(p, p_cur->simResponse); - - startResponse; - appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2, - (char*)p_cur->simResponse); - closeResponse; - - - return 0; -} - -static int responseCallForwards(Parcel &p, void *response, size_t responselen) { - int num; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_CallForwardInfo *) != 0) { - RLOGE("responseCallForwards: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_CallForwardInfo *)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - /* number of call info's */ - num = responselen / sizeof(RIL_CallForwardInfo *); - p.writeInt32(num); - - startResponse; - for (int i = 0 ; i < num ; i++) { - RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i]; - - p.writeInt32(p_cur->status); - p.writeInt32(p_cur->reason); - p.writeInt32(p_cur->serviceClass); - p.writeInt32(p_cur->toa); - writeStringToParcel(p, p_cur->number); - p.writeInt32(p_cur->timeSeconds); - appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf, - (p_cur->status==1)?"enable":"disable", - p_cur->reason, p_cur->serviceClass, p_cur->toa, - (char*)p_cur->number, - p_cur->timeSeconds); - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseSsn(Parcel &p, void *response, size_t responselen) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof(RIL_SuppSvcNotification)) { - RLOGE("invalid response length was %d expected %d", - (int)responselen, (int)sizeof (RIL_SuppSvcNotification)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response; - p.writeInt32(p_cur->notificationType); - p.writeInt32(p_cur->code); - p.writeInt32(p_cur->index); - p.writeInt32(p_cur->type); - writeStringToParcel(p, p_cur->number); - - startResponse; - appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf, - (p_cur->notificationType==0)?"mo":"mt", - p_cur->code, p_cur->index, p_cur->type, - (char*)p_cur->number); - closeResponse; - - return 0; -} - -static int responseCellList(Parcel &p, void *response, size_t responselen) { - int num; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof (RIL_NeighboringCell *) != 0) { - RLOGE("responseCellList: invalid response length %d expected multiple of %d\n", - (int)responselen, (int)sizeof (RIL_NeighboringCell *)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - startResponse; - /* number of records */ - num = responselen / sizeof(RIL_NeighboringCell *); - p.writeInt32(num); - - for (int i = 0 ; i < num ; i++) { - RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i]; - - p.writeInt32(p_cur->rssi); - writeStringToParcel (p, p_cur->cid); - - appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf, - p_cur->cid, p_cur->rssi); - } - removeLastChar; - closeResponse; - - return 0; -} - -/** - * Marshall the signalInfoRecord into the parcel if it exists. - */ -static void marshallSignalInfoRecord(Parcel &p, - RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) { - p.writeInt32(p_signalInfoRecord.isPresent); - p.writeInt32(p_signalInfoRecord.signalType); - p.writeInt32(p_signalInfoRecord.alertPitch); - p.writeInt32(p_signalInfoRecord.signal); -} - -static int responseCdmaInformationRecords(Parcel &p, - void *response, size_t responselen) { - int num; - char* string8 = NULL; - int buffer_lenght; - RIL_CDMA_InformationRecord *infoRec; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof (RIL_CDMA_InformationRecords)) { - RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n", - (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_CDMA_InformationRecords *p_cur = - (RIL_CDMA_InformationRecords *) response; - num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); - - startResponse; - p.writeInt32(num); - - for (int i = 0 ; i < num ; i++) { - infoRec = &p_cur->infoRec[i]; - p.writeInt32(infoRec->name); - switch (infoRec->name) { - case RIL_CDMA_DISPLAY_INFO_REC: - case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: - if (infoRec->rec.display.alpha_len > - CDMA_ALPHA_INFO_BUFFER_LENGTH) { - RLOGE("invalid display info response length %d \ - expected not more than %d\n", - (int)infoRec->rec.display.alpha_len, - CDMA_ALPHA_INFO_BUFFER_LENGTH); - return RIL_ERRNO_INVALID_RESPONSE; - } - string8 = (char*) calloc(infoRec->rec.display.alpha_len + 1, sizeof(char)); - if (string8 == NULL) { - RLOGE("Memory allocation failed for responseCdmaInformationRecords"); - closeRequest; - return RIL_ERRNO_NO_MEMORY; - } - for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) { - string8[i] = infoRec->rec.display.alpha_buf[i]; - } - string8[(int)infoRec->rec.display.alpha_len] = '\0'; - writeStringToParcel(p, (const char*)string8); - free(string8); - string8 = NULL; - break; - case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: - case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: - case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: - if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) { - RLOGE("invalid display info response length %d \ - expected not more than %d\n", - (int)infoRec->rec.number.len, - CDMA_NUMBER_INFO_BUFFER_LENGTH); - return RIL_ERRNO_INVALID_RESPONSE; - } - string8 = (char*) calloc(infoRec->rec.number.len + 1, sizeof(char)); - if (string8 == NULL) { - RLOGE("Memory allocation failed for responseCdmaInformationRecords"); - closeRequest; - return RIL_ERRNO_NO_MEMORY; - } - for (int i = 0 ; i < infoRec->rec.number.len; i++) { - string8[i] = infoRec->rec.number.buf[i]; - } - string8[(int)infoRec->rec.number.len] = '\0'; - writeStringToParcel(p, (const char*)string8); - free(string8); - string8 = NULL; - p.writeInt32(infoRec->rec.number.number_type); - p.writeInt32(infoRec->rec.number.number_plan); - p.writeInt32(infoRec->rec.number.pi); - p.writeInt32(infoRec->rec.number.si); - break; - case RIL_CDMA_SIGNAL_INFO_REC: - p.writeInt32(infoRec->rec.signal.isPresent); - p.writeInt32(infoRec->rec.signal.signalType); - p.writeInt32(infoRec->rec.signal.alertPitch); - p.writeInt32(infoRec->rec.signal.signal); - - appendPrintBuf("%sisPresent=%X, signalType=%X, \ - alertPitch=%X, signal=%X, ", - printBuf, (int)infoRec->rec.signal.isPresent, - (int)infoRec->rec.signal.signalType, - (int)infoRec->rec.signal.alertPitch, - (int)infoRec->rec.signal.signal); - removeLastChar; - break; - case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: - if (infoRec->rec.redir.redirectingNumber.len > - CDMA_NUMBER_INFO_BUFFER_LENGTH) { - RLOGE("invalid display info response length %d \ - expected not more than %d\n", - (int)infoRec->rec.redir.redirectingNumber.len, - CDMA_NUMBER_INFO_BUFFER_LENGTH); - return RIL_ERRNO_INVALID_RESPONSE; - } - string8 = (char*) calloc(infoRec->rec.redir.redirectingNumber.len + 1, - sizeof(char)); - if (string8 == NULL) { - RLOGE("Memory allocation failed for responseCdmaInformationRecords"); - closeRequest; - return RIL_ERRNO_NO_MEMORY; - } - for (int i = 0; - i < infoRec->rec.redir.redirectingNumber.len; - i++) { - string8[i] = infoRec->rec.redir.redirectingNumber.buf[i]; - } - string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0'; - writeStringToParcel(p, (const char*)string8); - free(string8); - string8 = NULL; - p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type); - p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan); - p.writeInt32(infoRec->rec.redir.redirectingNumber.pi); - p.writeInt32(infoRec->rec.redir.redirectingNumber.si); - p.writeInt32(infoRec->rec.redir.redirectingReason); - break; - case RIL_CDMA_LINE_CONTROL_INFO_REC: - p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded); - p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle); - p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse); - p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial); - - appendPrintBuf("%slineCtrlPolarityIncluded=%d, \ - lineCtrlToggle=%d, lineCtrlReverse=%d, \ - lineCtrlPowerDenial=%d, ", printBuf, - (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded, - (int)infoRec->rec.lineCtrl.lineCtrlToggle, - (int)infoRec->rec.lineCtrl.lineCtrlReverse, - (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial); - removeLastChar; - break; - case RIL_CDMA_T53_CLIR_INFO_REC: - p.writeInt32((int)(infoRec->rec.clir.cause)); - - appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause); - removeLastChar; - break; - case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: - p.writeInt32(infoRec->rec.audioCtrl.upLink); - p.writeInt32(infoRec->rec.audioCtrl.downLink); - - appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf, - infoRec->rec.audioCtrl.upLink, - infoRec->rec.audioCtrl.downLink); - removeLastChar; - break; - case RIL_CDMA_T53_RELEASE_INFO_REC: - // TODO(Moto): See David Krause, he has the answer:) - RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE"); - return RIL_ERRNO_INVALID_RESPONSE; - default: - RLOGE("Incorrect name value"); - return RIL_ERRNO_INVALID_RESPONSE; - } - } - closeResponse; - - return 0; -} - -static void responseRilSignalStrengthV5(Parcel &p, RIL_SignalStrength_v10 *p_cur) { - int gsmSignalStrength; - int cdmaDbm; - int evdoDbm; - - gsmSignalStrength = p_cur->GW_SignalStrength.signalStrength & 0xFF; - -#ifdef MODEM_TYPE_XMM6260 - if (gsmSignalStrength < 0 || - (gsmSignalStrength > 31 && p_cur->GW_SignalStrength.signalStrength != 99)) { - gsmSignalStrength = p_cur->CDMA_SignalStrength.dbm; - } -#else - if (gsmSignalStrength < 0) { - gsmSignalStrength = 99; - } else if (gsmSignalStrength > 31 && gsmSignalStrength != 99) { - gsmSignalStrength = 31; - } -#endif - -#if defined(MODEM_TYPE_XMM6262) || defined(SAMSUNG_NEXT_GEN_MODEM) - cdmaDbm = p_cur->CDMA_SignalStrength.dbm & 0xFF; - if (cdmaDbm < 0) { - cdmaDbm = 99; - } else if (cdmaDbm > 31 && cdmaDbm != 99) { - cdmaDbm = 31; - } -#else - cdmaDbm = p_cur->CDMA_SignalStrength.dbm; -#endif - -#if defined(MODEM_TYPE_XMM6262) || defined(SAMSUNG_NEXT_GEN_MODEM) - evdoDbm = p_cur->EVDO_SignalStrength.dbm & 0xFF; - if (evdoDbm < 0) { - evdoDbm = 99; - } else if (evdoDbm > 31 && evdoDbm != 99) { - evdoDbm = 31; - } -#else - evdoDbm = p_cur->EVDO_SignalStrength.dbm; -#endif - - p.writeInt32(gsmSignalStrength); - p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate); - p.writeInt32(cdmaDbm); - p.writeInt32(p_cur->CDMA_SignalStrength.ecio); - p.writeInt32(evdoDbm); - p.writeInt32(p_cur->EVDO_SignalStrength.ecio); - p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio); -} - -static void responseRilSignalStrengthV6Extra(Parcel &p, RIL_SignalStrength_v10 *p_cur) { - /* - * Fixup LTE for backwards compatibility - */ - // signalStrength: -1 -> 99 - if (p_cur->LTE_SignalStrength.signalStrength == -1) { - p_cur->LTE_SignalStrength.signalStrength = 99; - } - // rsrp: -1 -> INT_MAX all other negative value to positive. - // So remap here - if (p_cur->LTE_SignalStrength.rsrp == -1) { - p_cur->LTE_SignalStrength.rsrp = INT_MAX; - } else if (p_cur->LTE_SignalStrength.rsrp < -1) { - p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp; - } - // rsrq: -1 -> INT_MAX - if (p_cur->LTE_SignalStrength.rsrq == -1) { - p_cur->LTE_SignalStrength.rsrq = INT_MAX; - } - // Not remapping rssnr is already using INT_MAX - - // cqi: -1 -> INT_MAX - if (p_cur->LTE_SignalStrength.cqi == -1) { - p_cur->LTE_SignalStrength.cqi = INT_MAX; - } - - p.writeInt32(p_cur->LTE_SignalStrength.signalStrength); - p.writeInt32(p_cur->LTE_SignalStrength.rsrp); - p.writeInt32(p_cur->LTE_SignalStrength.rsrq); - p.writeInt32(p_cur->LTE_SignalStrength.rssnr); - p.writeInt32(p_cur->LTE_SignalStrength.cqi); -} - -static void responseRilSignalStrengthV10(Parcel &p, RIL_SignalStrength_v10 *p_cur) { - responseRilSignalStrengthV5(p, p_cur); - responseRilSignalStrengthV6Extra(p, p_cur); - p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp); -} - -static int responseRilSignalStrength(Parcel &p, - void *response, size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_SignalStrength_v10 *p_cur; - if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) { - if (responselen >= sizeof (RIL_SignalStrength_v5)) { - p_cur = ((RIL_SignalStrength_v10 *) response); - - responseRilSignalStrengthV5(p, p_cur); - - if (responselen >= sizeof (RIL_SignalStrength_v6)) { - responseRilSignalStrengthV6Extra(p, p_cur); - if (responselen >= sizeof (RIL_SignalStrength_v10)) { - p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp); - } else { - p.writeInt32(INT_MAX); - } - } else { - p.writeInt32(99); - p.writeInt32(INT_MAX); - p.writeInt32(INT_MAX); - p.writeInt32(INT_MAX); - p.writeInt32(INT_MAX); - p.writeInt32(INT_MAX); - } - } else { - RLOGE("invalid response length"); - return RIL_ERRNO_INVALID_RESPONSE; - } - } else { // RIL version >= 13 - if (responselen % sizeof(RIL_SignalStrength_v10) != 0) { - RLOGE("Data structure expected is RIL_SignalStrength_v10"); - if (!isDebuggable()) { - return RIL_ERRNO_INVALID_RESPONSE; - } else { - assert(0); - } - } - p_cur = ((RIL_SignalStrength_v10 *) response); - responseRilSignalStrengthV10(p, p_cur); - } - startResponse; - appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\ - CDMA_SS.dbm=%d,CDMA_SSecio=%d,\ - EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\ - EVDO_SS.signalNoiseRatio=%d,\ - LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\ - LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]", - printBuf, - gsmSignalStrength, - p_cur->GW_SignalStrength.bitErrorRate, - cdmaDbm, - p_cur->CDMA_SignalStrength.ecio, - evdoDbm, - p_cur->EVDO_SignalStrength.ecio, - p_cur->EVDO_SignalStrength.signalNoiseRatio, - p_cur->LTE_SignalStrength.signalStrength, - p_cur->LTE_SignalStrength.rsrp, - p_cur->LTE_SignalStrength.rsrq, - p_cur->LTE_SignalStrength.rssnr, - p_cur->LTE_SignalStrength.cqi, - p_cur->TD_SCDMA_SignalStrength.rscp); - closeResponse; - return 0; -} - -static int responseCallRing(Parcel &p, void *response, size_t responselen) { - if ((response == NULL) || (responselen == 0)) { - return responseVoid(p, response, responselen); - } else { - return responseCdmaSignalInfoRecord(p, response, responselen); - } -} - -static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) { - if (response == NULL || responselen == 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) { - RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n", - (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - startResponse; - - RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response); - marshallSignalInfoRecord(p, *p_cur); - - appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\ - signal=%d]", - printBuf, - p_cur->isPresent, - p_cur->signalType, - p_cur->alertPitch, - p_cur->signal); - - closeResponse; - return 0; -} - -static int responseCdmaCallWaiting(Parcel &p, void *response, - size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) { - RLOGW("Upgrade to ril version %d\n", RIL_VERSION); - } - - RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response); - - writeStringToParcel(p, p_cur->number); - p.writeInt32(p_cur->numberPresentation); - writeStringToParcel(p, p_cur->name); - marshallSignalInfoRecord(p, p_cur->signalInfoRecord); - - if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) { - if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) { - p.writeInt32(p_cur->number_type); - p.writeInt32(p_cur->number_plan); - } else { - p.writeInt32(0); - p.writeInt32(0); - } - } else { // RIL version >= 13 - if (responselen % sizeof(RIL_CDMA_CallWaiting_v6) != 0) { - RLOGE("Data structure expected is RIL_CDMA_CallWaiting_v6"); - if (!isDebuggable()) { - return RIL_ERRNO_INVALID_RESPONSE; - } else { - assert(0); - } - } - p.writeInt32(p_cur->number_type); - p.writeInt32(p_cur->number_plan); - } - - startResponse; - appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\ - signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\ - signal=%d,number_type=%d,number_plan=%d]", - printBuf, - p_cur->number, - p_cur->numberPresentation, - p_cur->name, - p_cur->signalInfoRecord.isPresent, - p_cur->signalInfoRecord.signalType, - p_cur->signalInfoRecord.alertPitch, - p_cur->signalInfoRecord.signal, - p_cur->number_type, - p_cur->number_plan); - closeResponse; - - return 0; -} - -static void responseSimRefreshV7(Parcel &p, void *response) { - RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response); - p.writeInt32(p_cur->result); - p.writeInt32(p_cur->ef_id); - writeStringToParcel(p, p_cur->aid); - - appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s", - printBuf, - p_cur->result, - p_cur->ef_id, - p_cur->aid); - -} - -static int responseSimRefresh(Parcel &p, void *response, size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("responseSimRefresh: invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - startResponse; - if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) { - if (s_callbacks.version >= 7) { - responseSimRefreshV7(p, response); - } else { - int *p_cur = ((int *) response); - p.writeInt32(p_cur[0]); - p.writeInt32(p_cur[1]); - writeStringToParcel(p, NULL); - - appendPrintBuf("%sresult=%d, ef_id=%d", - printBuf, - p_cur[0], - p_cur[1]); - } - } else { // RIL version >= 13 - if (responselen % sizeof(RIL_SimRefreshResponse_v7) != 0) { - RLOGE("Data structure expected is RIL_SimRefreshResponse_v7"); - if (!isDebuggable()) { - return RIL_ERRNO_INVALID_RESPONSE; - } else { - assert(0); - } - } - responseSimRefreshV7(p, response); - - } - closeResponse; - - return 0; -} - -static int responseCellInfoListV6(Parcel &p, void *response, size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_CellInfo) != 0) { - RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_CellInfo)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - int num = responselen / sizeof(RIL_CellInfo); - p.writeInt32(num); - - RIL_CellInfo *p_cur = (RIL_CellInfo *) response; - startResponse; - int i; - for (i = 0; i < num; i++) { - appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i, - p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp); - p.writeInt32((int)p_cur->cellInfoType); - p.writeInt32(p_cur->registered); - p.writeInt32(p_cur->timeStampType); - p.writeInt64(p_cur->timeStamp); - switch(p_cur->cellInfoType) { - case RIL_CELL_INFO_TYPE_GSM: { - appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf, - p_cur->CellInfo.gsm.cellIdentityGsm.mcc, - p_cur->CellInfo.gsm.cellIdentityGsm.mnc, - p_cur->CellInfo.gsm.cellIdentityGsm.lac, - p_cur->CellInfo.gsm.cellIdentityGsm.cid); - appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf, - p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength, - p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate); - - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid); - p.writeInt32(INT_MAX); /* skip arfcn */ - p.writeInt32(INT_MAX); /* skip bsic */ - p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength); - p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate); - break; - } - case RIL_CELL_INFO_TYPE_WCDMA: { - appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf, - p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.lac, - p_cur->CellInfo.wcdma.cellIdentityWcdma.cid, - p_cur->CellInfo.wcdma.cellIdentityWcdma.psc); - appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf, - p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength, - p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate); - - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc); - p.writeInt32(INT_MAX); /* skip uarfcn */ - p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength); - p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate); - break; - } - case RIL_CELL_INFO_TYPE_CDMA: { - appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf, - p_cur->CellInfo.cdma.cellIdentityCdma.networkId, - p_cur->CellInfo.cdma.cellIdentityCdma.systemId, - p_cur->CellInfo.cdma.cellIdentityCdma.basestationId, - p_cur->CellInfo.cdma.cellIdentityCdma.longitude, - p_cur->CellInfo.cdma.cellIdentityCdma.latitude); - - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude); - - appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf, - p_cur->CellInfo.cdma.signalStrengthCdma.dbm, - p_cur->CellInfo.cdma.signalStrengthCdma.ecio, - p_cur->CellInfo.cdma.signalStrengthEvdo.dbm, - p_cur->CellInfo.cdma.signalStrengthEvdo.ecio, - p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio); - - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio); - break; - } - case RIL_CELL_INFO_TYPE_LTE: { - appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf, - p_cur->CellInfo.lte.cellIdentityLte.mcc, - p_cur->CellInfo.lte.cellIdentityLte.mnc, - p_cur->CellInfo.lte.cellIdentityLte.ci, - p_cur->CellInfo.lte.cellIdentityLte.pci, - p_cur->CellInfo.lte.cellIdentityLte.tac); - - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac); - p.writeInt32(INT_MAX); /* skip earfcn */ - - appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf, - p_cur->CellInfo.lte.signalStrengthLte.signalStrength, - p_cur->CellInfo.lte.signalStrengthLte.rsrp, - p_cur->CellInfo.lte.signalStrengthLte.rsrq, - p_cur->CellInfo.lte.signalStrengthLte.rssnr, - p_cur->CellInfo.lte.signalStrengthLte.cqi, - p_cur->CellInfo.lte.signalStrengthLte.timingAdvance); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance); - break; - } - case RIL_CELL_INFO_TYPE_TD_SCDMA: { - appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid); - appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf, - p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp); - - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid); - p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp); - break; - } - } - p_cur += 1; - } - removeLastChar; - closeResponse; - - return 0; -} - -static int responseCellInfoListV12(Parcel &p, void *response, size_t responselen) { - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_CellInfo_v12) != 0) { - RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_CellInfo_v12)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - int num = responselen / sizeof(RIL_CellInfo_v12); - p.writeInt32(num); - - RIL_CellInfo_v12 *p_cur = (RIL_CellInfo_v12 *) response; - startResponse; - int i; - for (i = 0; i < num; i++) { - appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i, - p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp); - RLOGE("[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", i, - p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp); - p.writeInt32((int)p_cur->cellInfoType); - p.writeInt32(p_cur->registered); - p.writeInt32(p_cur->timeStampType); - p.writeInt64(p_cur->timeStamp); - switch(p_cur->cellInfoType) { - case RIL_CELL_INFO_TYPE_GSM: { - appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,arfcn=%d,bsic=%x", printBuf, - p_cur->CellInfo.gsm.cellIdentityGsm.mcc, - p_cur->CellInfo.gsm.cellIdentityGsm.mnc, - p_cur->CellInfo.gsm.cellIdentityGsm.lac, - p_cur->CellInfo.gsm.cellIdentityGsm.cid, - p_cur->CellInfo.gsm.cellIdentityGsm.arfcn, - p_cur->CellInfo.gsm.cellIdentityGsm.bsic); - RLOGE("GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,arfcn=%d,bsic=%x", - p_cur->CellInfo.gsm.cellIdentityGsm.mcc, - p_cur->CellInfo.gsm.cellIdentityGsm.mnc, - p_cur->CellInfo.gsm.cellIdentityGsm.lac, - p_cur->CellInfo.gsm.cellIdentityGsm.cid, - p_cur->CellInfo.gsm.cellIdentityGsm.arfcn, - p_cur->CellInfo.gsm.cellIdentityGsm.bsic); - RLOGE("gsmSS: ss=%d,ber=%d, ta=%d],", - p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength, - p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate, - p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance); - appendPrintBuf("%s gsmSS: ss=%d,ber=%d, ta=%d],", printBuf, - p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength, - p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate, - p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance); - - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.arfcn); - p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.bsic); - p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength); - p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate); - p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance); - break; - } - case RIL_CELL_INFO_TYPE_WCDMA: { - RLOGE("WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,uarfcn=%d", - p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.lac, - p_cur->CellInfo.wcdma.cellIdentityWcdma.cid, - p_cur->CellInfo.wcdma.cellIdentityWcdma.psc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn); - RLOGE("wcdmaSS: ss=%d,ber=%d],", - p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength, - p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate); - appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,uarfcn=%d", printBuf, - p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.lac, - p_cur->CellInfo.wcdma.cellIdentityWcdma.cid, - p_cur->CellInfo.wcdma.cellIdentityWcdma.psc, - p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn); - appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf, - p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength, - p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate); - - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc); - p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn); - p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength); - p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate); - break; - } - case RIL_CELL_INFO_TYPE_CDMA: { - RLOGE("CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", - p_cur->CellInfo.cdma.cellIdentityCdma.networkId, - p_cur->CellInfo.cdma.cellIdentityCdma.systemId, - p_cur->CellInfo.cdma.cellIdentityCdma.basestationId, - p_cur->CellInfo.cdma.cellIdentityCdma.longitude, - p_cur->CellInfo.cdma.cellIdentityCdma.latitude); - - appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf, - p_cur->CellInfo.cdma.cellIdentityCdma.networkId, - p_cur->CellInfo.cdma.cellIdentityCdma.systemId, - p_cur->CellInfo.cdma.cellIdentityCdma.basestationId, - p_cur->CellInfo.cdma.cellIdentityCdma.longitude, - p_cur->CellInfo.cdma.cellIdentityCdma.latitude); - - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude); - p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude); - - RLOGE("cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", - p_cur->CellInfo.cdma.signalStrengthCdma.dbm, - p_cur->CellInfo.cdma.signalStrengthCdma.ecio, - p_cur->CellInfo.cdma.signalStrengthEvdo.dbm, - p_cur->CellInfo.cdma.signalStrengthEvdo.ecio, - p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio); - - appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf, - p_cur->CellInfo.cdma.signalStrengthCdma.dbm, - p_cur->CellInfo.cdma.signalStrengthCdma.ecio, - p_cur->CellInfo.cdma.signalStrengthEvdo.dbm, - p_cur->CellInfo.cdma.signalStrengthEvdo.ecio, - p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio); - - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio); - p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio); - break; - } - case RIL_CELL_INFO_TYPE_LTE: { - RLOGE("LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d,earfcn=%d", - p_cur->CellInfo.lte.cellIdentityLte.mcc, - p_cur->CellInfo.lte.cellIdentityLte.mnc, - p_cur->CellInfo.lte.cellIdentityLte.ci, - p_cur->CellInfo.lte.cellIdentityLte.pci, - p_cur->CellInfo.lte.cellIdentityLte.tac, - p_cur->CellInfo.lte.cellIdentityLte.earfcn); - - appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d,earfcn=%d", printBuf, - p_cur->CellInfo.lte.cellIdentityLte.mcc, - p_cur->CellInfo.lte.cellIdentityLte.mnc, - p_cur->CellInfo.lte.cellIdentityLte.ci, - p_cur->CellInfo.lte.cellIdentityLte.pci, - p_cur->CellInfo.lte.cellIdentityLte.tac, - p_cur->CellInfo.lte.cellIdentityLte.earfcn); - - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac); - p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.earfcn); - - RLOGE("lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", - p_cur->CellInfo.lte.signalStrengthLte.signalStrength, - p_cur->CellInfo.lte.signalStrengthLte.rsrp, - p_cur->CellInfo.lte.signalStrengthLte.rsrq, - p_cur->CellInfo.lte.signalStrengthLte.rssnr, - p_cur->CellInfo.lte.signalStrengthLte.cqi, - p_cur->CellInfo.lte.signalStrengthLte.timingAdvance); - appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf, - p_cur->CellInfo.lte.signalStrengthLte.signalStrength, - p_cur->CellInfo.lte.signalStrengthLte.rsrp, - p_cur->CellInfo.lte.signalStrengthLte.rsrq, - p_cur->CellInfo.lte.signalStrengthLte.rssnr, - p_cur->CellInfo.lte.signalStrengthLte.cqi, - p_cur->CellInfo.lte.signalStrengthLte.timingAdvance); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi); - p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance); - break; - } - case RIL_CELL_INFO_TYPE_TD_SCDMA: { - appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid, - p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid); - appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf, - p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp); - - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid); - p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid); - p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp); - break; - } - } - p_cur += 1; - } - removeLastChar; - closeResponse; - return 0; -} - -static int responseCellInfoList(Parcel &p, void *response, size_t responselen) -{ - if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) { - if (s_callbacks.version < 12) { - RLOGD("responseCellInfoList: v6"); - return responseCellInfoListV6(p, response, responselen); - } else { - RLOGD("responseCellInfoList: v12"); - return responseCellInfoListV12(p, response, responselen); - } - } else { // RIL version >= 13 - if (responselen % sizeof(RIL_CellInfo_v12) != 0) { - RLOGE("Data structure expected is RIL_CellInfo_v12"); - if (!isDebuggable()) { - return RIL_ERRNO_INVALID_RESPONSE; - } else { - assert(0); - } - } - return responseCellInfoListV12(p, response, responselen); - } - - return 0; -} - -static int responseHardwareConfig(Parcel &p, void *response, size_t responselen) -{ - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen % sizeof(RIL_HardwareConfig) != 0) { - RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_HardwareConfig)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - int num = responselen / sizeof(RIL_HardwareConfig); - int i; - RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response; - - p.writeInt32(num); - - startResponse; - for (i = 0; i < num; i++) { - switch (p_cur[i].type) { - case RIL_HARDWARE_CONFIG_MODEM: { - writeStringToParcel(p, p_cur[i].uuid); - p.writeInt32((int)p_cur[i].state); - p.writeInt32(p_cur[i].cfg.modem.rat); - p.writeInt32(p_cur[i].cfg.modem.maxVoice); - p.writeInt32(p_cur[i].cfg.modem.maxData); - p.writeInt32(p_cur[i].cfg.modem.maxStandby); - - appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf, - p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat, - p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby); - break; - } - case RIL_HARDWARE_CONFIG_SIM: { - writeStringToParcel(p, p_cur[i].uuid); - p.writeInt32((int)p_cur[i].state); - writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid); - - appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf, - p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid); - break; - } - } - } - removeLastChar; - closeResponse; - return 0; -} - -static int responseRadioCapability(Parcel &p, void *response, size_t responselen) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof (RIL_RadioCapability) ) { - RLOGE("invalid response length was %d expected %d", - (int)responselen, (int)sizeof (RIL_SIM_IO_Response)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response; - p.writeInt32(p_cur->version); - p.writeInt32(p_cur->session); - p.writeInt32(p_cur->phase); - p.writeInt32(p_cur->rat); - writeStringToParcel(p, p_cur->logicalModemUuid); - p.writeInt32(p_cur->status); - - startResponse; - appendPrintBuf("%s[version=%d,session=%d,phase=%d,\ - rat=%s,logicalModemUuid=%s,status=%d]", - printBuf, - p_cur->version, - p_cur->session, - p_cur->phase, - p_cur->rat, - p_cur->logicalModemUuid, - p_cur->status); - closeResponse; - return 0; -} - -static int responseSSData(Parcel &p, void *response, size_t responselen) { - RLOGD("In responseSSData"); - int num; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response length was %d expected %d", - (int)responselen, (int)sizeof (RIL_SIM_IO_Response)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) { - RLOGE("invalid response length %d, expected %d", - (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - startResponse; - RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response; - p.writeInt32(p_cur->serviceType); - p.writeInt32(p_cur->requestType); - p.writeInt32(p_cur->teleserviceType); - p.writeInt32(p_cur->serviceClass); - p.writeInt32(p_cur->result); - - if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) { - RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes); - if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) { - RLOGE("numValidIndexes is greater than max value %d, " - "truncating it to max value", NUM_SERVICE_CLASSES); - p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES; - } - /* number of call info's */ - p.writeInt32(p_cur->cfData.numValidIndexes); - - for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) { - RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i]; - - p.writeInt32(cf.status); - p.writeInt32(cf.reason); - p.writeInt32(cf.serviceClass); - p.writeInt32(cf.toa); - writeStringToParcel(p, cf.number); - p.writeInt32(cf.timeSeconds); - appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf, - (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa, - (char*)cf.number, cf.timeSeconds); - RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status, - cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds); - } - } else { - p.writeInt32 (SS_INFO_MAX); - - /* each int*/ - for (int i = 0; i < SS_INFO_MAX; i++) { - appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]); - RLOGD("Data: %d",p_cur->ssInfo[i]); - p.writeInt32(p_cur->ssInfo[i]); - } - } - removeLastChar; - closeResponse; - - return 0; -} - -static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) { - if ((reqType == SS_INTERROGATION) && - (serType == SS_CFU || - serType == SS_CF_BUSY || - serType == SS_CF_NO_REPLY || - serType == SS_CF_NOT_REACHABLE || - serType == SS_CF_ALL || - serType == SS_CF_ALL_CONDITIONAL)) { - return true; - } - return false; -} - -static void triggerEvLoop() { - int ret; - if (!pthread_equal(pthread_self(), s_tid_dispatch)) { - /* trigger event loop to wakeup. No reason to do this, - * if we're in the event loop thread */ - do { - ret = write (s_fdWakeupWrite, " ", 1); - } while (ret < 0 && errno == EINTR); - } -} - -static void rilEventAddWakeup(struct ril_event *ev) { - ril_event_add(ev); - triggerEvLoop(); -} - -static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) { - p.writeInt32(num_apps); - startResponse; - for (int i = 0; i < num_apps; i++) { - p.writeInt32(appStatus[i].app_type); - p.writeInt32(appStatus[i].app_state); - p.writeInt32(appStatus[i].perso_substate); - writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr)); - writeStringToParcel(p, (const char*) - (appStatus[i].app_label_ptr)); - p.writeInt32(appStatus[i].pin1_replaced); - p.writeInt32(appStatus[i].pin1); - p.writeInt32(appStatus[i].pin2); - appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\ - aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],", - printBuf, - appStatus[i].app_type, - appStatus[i].app_state, - appStatus[i].perso_substate, - appStatus[i].aid_ptr, - appStatus[i].app_label_ptr, - appStatus[i].pin1_replaced, - appStatus[i].pin1, - appStatus[i].pin2); - } - closeResponse; -} - -static void responseSimStatusV5(Parcel &p, void *response) { - RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response); - - p.writeInt32(p_cur->card_state); - p.writeInt32(p_cur->universal_pin_state); - p.writeInt32(p_cur->gsm_umts_subscription_app_index); - p.writeInt32(p_cur->cdma_subscription_app_index); - p.writeInt32(-1); - - sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications); -} - -static void responseSimStatusV6(Parcel &p, void *response) { - RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response); - - p.writeInt32(p_cur->card_state); - p.writeInt32(p_cur->universal_pin_state); - p.writeInt32(p_cur->gsm_umts_subscription_app_index); - p.writeInt32(p_cur->cdma_subscription_app_index); - p.writeInt32(p_cur->ims_subscription_app_index); - - sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications); -} - -static int responseSimStatus(Parcel &p, void *response, size_t responselen) { - int i; - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) { - if (responselen == sizeof (RIL_CardStatus_v6)) { - responseSimStatusV6(p, response); - } else if (responselen == sizeof (RIL_CardStatus_v5)) { - responseSimStatusV5(p, response); - } else { - RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n"); - return RIL_ERRNO_INVALID_RESPONSE; - } - } else { // RIL version >= 13 - if (responselen % sizeof(RIL_CardStatus_v6) != 0) { - RLOGE("Data structure expected is RIL_CardStatus_v6"); - if (!isDebuggable()) { - return RIL_ERRNO_INVALID_RESPONSE; - } else { - assert(0); - } - } - responseSimStatusV6(p, response); - } - - return 0; -} - -static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) { - int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *); - p.writeInt32(num); - - startResponse; - RIL_GSM_BroadcastSmsConfigInfo **p_cur = - (RIL_GSM_BroadcastSmsConfigInfo **) response; - for (int i = 0; i < num; i++) { - p.writeInt32(p_cur[i]->fromServiceId); - p.writeInt32(p_cur[i]->toServiceId); - p.writeInt32(p_cur[i]->fromCodeScheme); - p.writeInt32(p_cur[i]->toCodeScheme); - p.writeInt32(p_cur[i]->selected); - - appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \ - fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", - printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId, - p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme, - p_cur[i]->selected); - } - closeResponse; - - return 0; -} - -static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) { - RIL_CDMA_BroadcastSmsConfigInfo **p_cur = - (RIL_CDMA_BroadcastSmsConfigInfo **) response; - - int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *); - p.writeInt32(num); - - startResponse; - for (int i = 0 ; i < num ; i++ ) { - p.writeInt32(p_cur[i]->service_category); - p.writeInt32(p_cur[i]->language); - p.writeInt32(p_cur[i]->selected); - - appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \ - selected =%d], ", - printBuf, i, p_cur[i]->service_category, p_cur[i]->language, - p_cur[i]->selected); - } - closeResponse; - - return 0; -} - -static int responseCdmaSms(Parcel &p, void *response, size_t responselen) { - int num; - int digitCount; - int digitLimit; - uint8_t uct; - void* dest; - - RLOGD("Inside responseCdmaSms"); - - if (response == NULL && responselen != 0) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - - if (responselen != sizeof(RIL_CDMA_SMS_Message)) { - RLOGE("invalid response length was %d expected %d", - (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response; - p.writeInt32(p_cur->uTeleserviceID); - p.write(&(p_cur->bIsServicePresent),sizeof(uct)); - p.writeInt32(p_cur->uServicecategory); - p.writeInt32(p_cur->sAddress.digit_mode); - p.writeInt32(p_cur->sAddress.number_mode); - p.writeInt32(p_cur->sAddress.number_type); - p.writeInt32(p_cur->sAddress.number_plan); - p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct)); - digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); - for(digitCount =0 ; digitCount < digitLimit; digitCount ++) { - p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct)); - } - - p.writeInt32(p_cur->sSubAddress.subaddressType); - p.write(&(p_cur->sSubAddress.odd),sizeof(uct)); - p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct)); - digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); - for(digitCount =0 ; digitCount < digitLimit; digitCount ++) { - p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct)); - } - - digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); - p.writeInt32(p_cur->uBearerDataLen); - for(digitCount =0 ; digitCount < digitLimit; digitCount ++) { - p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct)); - } - - startResponse; - appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \ - sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ", - printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory, - p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type); - closeResponse; - - return 0; -} - -static int responseDcRtInfo(Parcel &p, void *response, size_t responselen) -{ - int num = responselen / sizeof(RIL_DcRtInfo); - if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) { - RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_DcRtInfo)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - startResponse; - RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response; - p.writeInt64(pDcRtInfo->time); - p.writeInt32(pDcRtInfo->powerState); - appendPrintBuf("%s[time=%d,powerState=%d]", printBuf, - pDcRtInfo->time, - pDcRtInfo->powerState); - closeResponse; - - return 0; -} - -static int responseLceStatus(Parcel &p, void *response, size_t responselen) { - if (response == NULL || responselen != sizeof(RIL_LceStatusInfo)) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - } - else { - RLOGE("responseLceStatus: invalid response length %u expecting len: %u", - (unsigned)sizeof(RIL_LceStatusInfo), (unsigned)responselen); - } - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_LceStatusInfo *p_cur = (RIL_LceStatusInfo *)response; - p.write((void *)p_cur, 1); // p_cur->lce_status takes one byte. - p.writeInt32(p_cur->actual_interval_ms); - - startResponse; - appendPrintBuf("LCE Status: %d, actual_interval_ms: %d", - p_cur->lce_status, p_cur->actual_interval_ms); - closeResponse; - - return 0; -} - -static int responseLceData(Parcel &p, void *response, size_t responselen) { - if (response == NULL || responselen != sizeof(RIL_LceDataInfo)) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - } - else { - RLOGE("responseLceData: invalid response length %u expecting len: %u", - (unsigned)sizeof(RIL_LceDataInfo), (unsigned)responselen); - } - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_LceDataInfo *p_cur = (RIL_LceDataInfo *)response; - p.writeInt32(p_cur->last_hop_capacity_kbps); - - /* p_cur->confidence_level and p_cur->lce_suspended take 1 byte each.*/ - p.write((void *)&(p_cur->confidence_level), 1); - p.write((void *)&(p_cur->lce_suspended), 1); - - startResponse; - appendPrintBuf("LCE info received: capacity %d confidence level %d \ - and suspended %d", - p_cur->last_hop_capacity_kbps, p_cur->confidence_level, - p_cur->lce_suspended); - closeResponse; - - return 0; -} - -static int responseActivityData(Parcel &p, void *response, size_t responselen) { - if (response == NULL || responselen != sizeof(RIL_ActivityStatsInfo)) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - } - else { - RLOGE("responseActivityData: invalid response length %u expecting len: %u", - (unsigned)sizeof(RIL_ActivityStatsInfo), (unsigned)responselen); - } - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_ActivityStatsInfo *p_cur = (RIL_ActivityStatsInfo *)response; - p.writeInt32(p_cur->sleep_mode_time_ms); - p.writeInt32(p_cur->idle_mode_time_ms); - for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) { - p.writeInt32(p_cur->tx_mode_time_ms[i]); - } - p.writeInt32(p_cur->rx_mode_time_ms); - - startResponse; - appendPrintBuf("Modem activity info received: sleep_mode_time_ms %d idle_mode_time_ms %d \ - tx_mode_time_ms %d %d %d %d %d and rx_mode_time_ms %d", - p_cur->sleep_mode_time_ms, p_cur->idle_mode_time_ms, p_cur->tx_mode_time_ms[0], - p_cur->tx_mode_time_ms[1], p_cur->tx_mode_time_ms[2], p_cur->tx_mode_time_ms[3], - p_cur->tx_mode_time_ms[4], p_cur->rx_mode_time_ms); - closeResponse; - - return 0; -} - -static int responseCarrierRestrictions(Parcel &p, void *response, size_t responselen) { - if (response == NULL) { - RLOGE("invalid response: NULL"); - return RIL_ERRNO_INVALID_RESPONSE; - } - if (responselen != sizeof(RIL_CarrierRestrictions)) { - RLOGE("responseCarrierRestrictions: invalid response length %u expecting len: %u", - (unsigned)responselen, (unsigned)sizeof(RIL_CarrierRestrictions)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_CarrierRestrictions *p_cr = (RIL_CarrierRestrictions *)response; - startResponse; - - p.writeInt32(p_cr->len_allowed_carriers); - p.writeInt32(p_cr->len_excluded_carriers); - appendPrintBuf(" %s len_allowed_carriers: %d, len_excluded_carriers: %d,", printBuf, - p_cr->len_allowed_carriers,p_cr->len_excluded_carriers); - - appendPrintBuf(" %s allowed_carriers:", printBuf); - for(int32_t i = 0; i < p_cr->len_allowed_carriers; i++) { - RIL_Carrier *carrier = p_cr->allowed_carriers + i; - writeStringToParcel(p, carrier->mcc); - writeStringToParcel(p, carrier->mnc); - p.writeInt32(carrier->match_type); - writeStringToParcel(p, carrier->match_data); - appendPrintBuf(" %s [%d mcc: %s, mnc: %s, match_type: %d, match_data: %s],", printBuf, - i, carrier->mcc, carrier->mnc, carrier->match_type, carrier->match_data); - } - - appendPrintBuf(" %s excluded_carriers:", printBuf); - for(int32_t i = 0; i < p_cr->len_excluded_carriers; i++) { - RIL_Carrier *carrier = p_cr->excluded_carriers + i; - writeStringToParcel(p, carrier->mcc); - writeStringToParcel(p, carrier->mnc); - p.writeInt32(carrier->match_type); - writeStringToParcel(p, carrier->match_data); - appendPrintBuf(" %s [%d mcc: %s, mnc: %s, match_type: %d, match_data: %s],", printBuf, - i, carrier->mcc, carrier->mnc, carrier->match_type, carrier->match_data); - } - - closeResponse; - - return 0; -} - -static int responsePcoData(Parcel &p, void *response, size_t responselen) { - if (response == NULL) { - RLOGE("responsePcoData: invalid NULL response"); - return RIL_ERRNO_INVALID_RESPONSE; - } - if (responselen != sizeof(RIL_PCO_Data)) { - RLOGE("responsePcoData: invalid response length %u, expecting %u", - (unsigned)responselen, (unsigned)sizeof(RIL_PCO_Data)); - return RIL_ERRNO_INVALID_RESPONSE; - } - - RIL_PCO_Data *p_cur = (RIL_PCO_Data *)response; - p.writeInt32(p_cur->cid); - writeStringToParcel(p, p_cur->bearer_proto); - p.writeInt32(p_cur->pco_id); - p.writeInt32(p_cur->contents_length); - p.write(p_cur->contents, p_cur->contents_length); - - startResponse; - appendPrintBuf("PCO data received: cid %d, id %d, length %d", - p_cur->cid, p_cur->pco_id, p_cur->contents_length); - closeResponse; - - return 0; -} - -/** - * A write on the wakeup fd is done just to pop us out of select() - * We empty the buffer here and then ril_event will reset the timers on the - * way back down - */ -static void processWakeupCallback(int fd, short flags, void *param) { - char buff[16]; - int ret; - - RLOGV("processWakeupCallback"); - - /* empty our wakeup socket out */ - do { - ret = read(s_fdWakeupRead, &buff, sizeof(buff)); - } while (ret > 0 || (ret < 0 && errno == EINTR)); -} - -static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) { - int ret; - RequestInfo *p_cur; - /* Hook for current context - pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ - pthread_mutex_t * pendingRequestsMutexHook = &s_pendingRequestsMutex; - /* pendingRequestsHook refer to &s_pendingRequests */ - RequestInfo ** pendingRequestsHook = &s_pendingRequests; - -#if (SIM_COUNT >= 2) - if (socket_id == RIL_SOCKET_2) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; - pendingRequestsHook = &s_pendingRequests_socket2; - } -#if (SIM_COUNT >= 3) - else if (socket_id == RIL_SOCKET_3) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3; - pendingRequestsHook = &s_pendingRequests_socket3; - } -#endif -#if (SIM_COUNT >= 4) - else if (socket_id == RIL_SOCKET_4) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4; - pendingRequestsHook = &s_pendingRequests_socket4; - } -#endif -#endif - /* mark pending requests as "cancelled" so we dont report responses */ - ret = pthread_mutex_lock(pendingRequestsMutexHook); - assert (ret == 0); - - p_cur = *pendingRequestsHook; - - for (p_cur = *pendingRequestsHook - ; p_cur != NULL - ; p_cur = p_cur->p_next - ) { - p_cur->cancelled = 1; - } - - ret = pthread_mutex_unlock(pendingRequestsMutexHook); - assert (ret == 0); -} - -static void processCommandsCallback(int fd, short flags, void *param) { - RecordStream *p_rs; - void *p_record; - size_t recordlen; - int ret; - SocketListenParam *p_info = (SocketListenParam *)param; - - assert(fd == p_info->fdCommand); - - p_rs = p_info->p_rs; - - for (;;) { - /* loop until EAGAIN/EINTR, end of stream, or other error */ - ret = record_stream_get_next(p_rs, &p_record, &recordlen); - - if (ret == 0 && p_record == NULL) { - /* end-of-stream */ - break; - } else if (ret < 0) { - break; - } else if (ret == 0) { /* && p_record != NULL */ - processCommandBuffer(p_record, recordlen, p_info->socket_id); - } - } - - if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) { - /* fatal error or end-of-stream */ - if (ret != 0) { - RLOGE("error on reading command socket errno:%d\n", errno); - } else { - RLOGW("EOS. Closing command socket."); - } - - close(fd); - p_info->fdCommand = -1; - - ril_event_del(p_info->commands_event); - - record_stream_free(p_rs); - - /* start listening for new connections again */ - rilEventAddWakeup(&s_listen_event); - - onCommandsSocketClosed(p_info->socket_id); - } -} - - -static void onNewCommandConnect(RIL_SOCKET_ID socket_id) { - // Inform we are connected and the ril version - int rilVer = s_callbacks.version; - RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED, - &rilVer, sizeof(rilVer), socket_id); - - // implicit radio state changed - RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, - NULL, 0, socket_id); - - // Send last NITZ time data, in case it was missed - if (s_lastNITZTimeData != NULL) { - sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id); - - free(s_lastNITZTimeData); - s_lastNITZTimeData = NULL; - } - - // Get version string - if (s_callbacks.getVersion != NULL) { - const char *version; - version = s_callbacks.getVersion(); - RLOGI("RIL Daemon version: %s\n", version); - - property_set(PROPERTY_RIL_IMPL, version); - } else { - RLOGI("RIL Daemon version: unavailable\n"); - property_set(PROPERTY_RIL_IMPL, "unavailable"); - } - -} - -static void listenCallback (int fd, short flags, void *param) { - int ret; - int err; - int is_phone_socket; - int fdCommand = -1; - const char* processName; - RecordStream *p_rs; - MySocketListenParam* listenParam; - RilSocket *sapSocket = NULL; - socketClient *sClient = NULL; - - SocketListenParam *p_info = (SocketListenParam *)param; - - if(RIL_SAP_SOCKET == p_info->type) { - listenParam = (MySocketListenParam *)param; - sapSocket = listenParam->socket; - } - - struct sockaddr_un peeraddr; - socklen_t socklen = sizeof (peeraddr); - - struct ucred creds; - socklen_t szCreds = sizeof(creds); - - struct passwd *pwd = NULL; - - if(NULL == sapSocket) { - assert (*p_info->fdCommand < 0); - assert (fd == *p_info->fdListen); - processName = PHONE_PROCESS; - } else { - assert (sapSocket->commandFd < 0); - assert (fd == sapSocket->listenFd); - processName = BLUETOOTH_PROCESS; - } - - - fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen); - - if (fdCommand < 0 ) { - RLOGE("Error on accept() errno:%d", errno); - /* start listening for new connections again */ - if(NULL == sapSocket) { - rilEventAddWakeup(p_info->listen_event); - } else { - rilEventAddWakeup(sapSocket->getListenEvent()); - } - return; - } - - /* check the credential of the other side and only accept socket from - * phone process - */ - errno = 0; - is_phone_socket = 0; - - err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); - - if (err == 0 && szCreds > 0) { - errno = 0; - pwd = getpwuid(creds.uid); - if (pwd != NULL) { - if (strcmp(pwd->pw_name, processName) == 0) { - is_phone_socket = 1; - } else { - RLOGE("RILD can't accept socket from process %s", pwd->pw_name); - } - } else { - RLOGE("Error on getpwuid() errno: %d", errno); - } - } else { - RLOGD("Error on getsockopt() errno: %d", errno); - } - - if (!is_phone_socket) { - RLOGE("RILD must accept socket from %s", processName); - - close(fdCommand); - fdCommand = -1; - - if(NULL == sapSocket) { - onCommandsSocketClosed(p_info->socket_id); - - /* start listening for new connections again */ - rilEventAddWakeup(p_info->listen_event); - } else { - sapSocket->onCommandsSocketClosed(); - - /* start listening for new connections again */ - rilEventAddWakeup(sapSocket->getListenEvent()); - } - - return; - } - - ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK); - - if (ret < 0) { - RLOGE ("Error setting O_NONBLOCK errno:%d", errno); - } - - if(NULL == sapSocket) { - RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id)); - - p_info->fdCommand = fdCommand; - p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES); - p_info->p_rs = p_rs; - - ril_event_set (p_info->commands_event, p_info->fdCommand, 1, - p_info->processCommandsCallback, p_info); - rilEventAddWakeup (p_info->commands_event); + pRI->p_next = *pendingRequestsHook; + *pendingRequestsHook = pRI; - onNewCommandConnect(p_info->socket_id); - } else { - RLOGI("libril: new connection"); + ret = pthread_mutex_unlock(pendingRequestsMutexHook); + assert (ret == 0); - sapSocket->setCommandFd(fdCommand); - p_rs = record_stream_new(sapSocket->getCommandFd(), MAX_COMMAND_BYTES); - sClient = new socketClient(sapSocket,p_rs); - ril_event_set (sapSocket->getCallbackEvent(), sapSocket->getCommandFd(), 1, - sapSocket->getCommandCb(), sClient); + return pRI; +} - rilEventAddWakeup(sapSocket->getCallbackEvent()); - sapSocket->onNewCommandConnect(); +static void triggerEvLoop() { + int ret; + if (!pthread_equal(pthread_self(), s_tid_dispatch)) { + /* trigger event loop to wakeup. No reason to do this, + * if we're in the event loop thread */ + do { + ret = write (s_fdWakeupWrite, " ", 1); + } while (ret < 0 && errno == EINTR); } } -static void freeDebugCallbackArgs(int number, char **args) { - for (int i = 0; i < number; i++) { - if (args[i] != NULL) { - free(args[i]); - } - } - free(args); +static void rilEventAddWakeup(struct ril_event *ev) { + ril_event_add(ev); + triggerEvLoop(); } -static void debugCallback (int fd, short flags, void *param) { - int acceptFD, option; - struct sockaddr_un peeraddr; - socklen_t socklen = sizeof (peeraddr); - int data; - unsigned int qxdm_data[6]; - const char *deactData[1] = {"1"}; - char *actData[1]; - RIL_Dial dialData; - int hangupData[1] = {1}; - int number; - char **args; - RIL_SOCKET_ID socket_id = RIL_SOCKET_1; - int sim_id = 0; +/** + * A write on the wakeup fd is done just to pop us out of select() + * We empty the buffer here and then ril_event will reset the timers on the + * way back down + */ +static void processWakeupCallback(int fd, short flags, void *param) { + char buff[16]; + int ret; - RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id)); + RLOGV("processWakeupCallback"); - acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen); + /* empty our wakeup socket out */ + do { + ret = read(s_fdWakeupRead, &buff, sizeof(buff)); + } while (ret > 0 || (ret < 0 && errno == EINTR)); +} - if (acceptFD < 0) { - RLOGE ("error accepting on debug port: %d\n", errno); - return; +static void resendLastNITZTimeData(RIL_SOCKET_ID socket_id) { + if (s_lastNITZTimeData != NULL) { + int responseType = (s_callbacks.version >= 13) + ? RESPONSE_UNSOLICITED_ACK_EXP + : RESPONSE_UNSOLICITED; + int ret = radio::nitzTimeReceivedInd( + (int)socket_id, responseType, 0, + RIL_E_SUCCESS, s_lastNITZTimeData, s_lastNITZTimeDataSize); + if (ret == 0) { + free(s_lastNITZTimeData); + s_lastNITZTimeData = NULL; + } } +} - if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) { - RLOGE ("error reading on socket: number of Args: \n"); - close(acceptFD); - return; - } +void onNewCommandConnect(RIL_SOCKET_ID socket_id) { + // Inform we are connected and the ril version + int rilVer = s_callbacks.version; + RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED, + &rilVer, sizeof(rilVer), socket_id); - if (number < 0) { - RLOGE ("Invalid number of arguments: \n"); - close(acceptFD); - return; - } + // implicit radio state changed + RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, + NULL, 0, socket_id); - args = (char **) calloc(number, sizeof(char*)); - if (args == NULL) { - RLOGE("Memory allocation failed for debug args"); - close(acceptFD); - return; + // Send last NITZ time data, in case it was missed + if (s_lastNITZTimeData != NULL) { + resendLastNITZTimeData(socket_id); } - for (int i = 0; i < number; i++) { - int len; - if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) { - RLOGE ("error reading on socket: Len of Args: \n"); - freeDebugCallbackArgs(i, args); - close(acceptFD); - return; - } - - if (len == INT_MAX || len < 0) { - RLOGE("Invalid value of len: \n"); - freeDebugCallbackArgs(i, args); - close(acceptFD); - return; - } + // Get version string + if (s_callbacks.getVersion != NULL) { + const char *version; + version = s_callbacks.getVersion(); + RLOGI("RIL Daemon version: %s\n", version); - // +1 for null-term - args[i] = (char *) calloc(len + 1, sizeof(char)); - if (args[i] == NULL) { - RLOGE("Memory allocation failed for debug args"); - freeDebugCallbackArgs(i, args); - close(acceptFD); - return; - } - if (recv(acceptFD, args[i], sizeof(char) * len, 0) - != (int)sizeof(char) * len) { - RLOGE ("error reading on socket: Args[%d] \n", i); - freeDebugCallbackArgs(i, args); - close(acceptFD); - return; - } - char * buf = args[i]; - buf[len] = 0; - if ((i+1) == number) { - /* The last argument should be sim id 0(SIM1)~3(SIM4) */ - sim_id = atoi(args[i]); - switch (sim_id) { - case 0: - socket_id = RIL_SOCKET_1; - break; - #if (SIM_COUNT >= 2) - case 1: - socket_id = RIL_SOCKET_2; - break; - #endif - #if (SIM_COUNT >= 3) - case 2: - socket_id = RIL_SOCKET_3; - break; - #endif - #if (SIM_COUNT >= 4) - case 3: - socket_id = RIL_SOCKET_4; - break; - #endif - default: - socket_id = RIL_SOCKET_1; - break; - } - } + property_set(PROPERTY_RIL_IMPL, version); + } else { + RLOGI("RIL Daemon version: unavailable\n"); + property_set(PROPERTY_RIL_IMPL, "unavailable"); } - switch (atoi(args[0])) { - case 0: - RLOGI ("Connection on debug port: issuing reset."); - issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id); - break; - case 1: - RLOGI ("Connection on debug port: issuing radio power off."); - data = 0; - issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id); - // Close the socket - if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) { - close(s_ril_param_socket.fdCommand); - s_ril_param_socket.fdCommand = -1; - } - #if (SIM_COUNT == 2) - else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) { - close(s_ril_param_socket2.fdCommand); - s_ril_param_socket2.fdCommand = -1; - } - #endif - break; - case 2: - RLOGI ("Debug port: issuing unsolicited voice network change."); - RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id); - break; - case 3: - RLOGI ("Debug port: QXDM log enable."); - qxdm_data[0] = 65536; // head.func_tag - qxdm_data[1] = 16; // head.len - qxdm_data[2] = 1; // mode: 1 for 'start logging' - qxdm_data[3] = 32; // log_file_size: 32megabytes - qxdm_data[4] = 0; // log_mask - qxdm_data[5] = 8; // log_max_fileindex - issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data, - 6 * sizeof(int), socket_id); - break; - case 4: - RLOGI ("Debug port: QXDM log disable."); - qxdm_data[0] = 65536; - qxdm_data[1] = 16; - qxdm_data[2] = 0; // mode: 0 for 'stop logging' - qxdm_data[3] = 32; - qxdm_data[4] = 0; - qxdm_data[5] = 8; - issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data, - 6 * sizeof(int), socket_id); - break; - case 5: - RLOGI("Debug port: Radio On"); - data = 1; - issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id); - sleep(2); - // Set network selection automatic. - issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id); - break; - case 6: - RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]); - actData[0] = args[1]; - issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData, - sizeof(actData), socket_id); - break; - case 7: - RLOGI("Debug port: Deactivate Data Call"); - issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData, - sizeof(deactData), socket_id); - break; - case 8: - RLOGI("Debug port: Dial Call"); - dialData.clir = 0; - dialData.address = args[1]; - issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id); - break; - case 9: - RLOGI("Debug port: Answer Call"); - issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id); - break; - case 10: - RLOGI("Debug port: End Call"); - issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData, - sizeof(hangupData), socket_id); - break; - default: - RLOGE ("Invalid request"); - break; - } - freeDebugCallbackArgs(number, args); - close(acceptFD); } - static void userTimerCallback (int fd, short flags, void *param) { UserCallbackInfo *p_info; @@ -5000,61 +433,6 @@ extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) { memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); } -static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) { - int fdListen = -1; - int ret; - char socket_name[10]; - - memset(socket_name, 0, sizeof(char)*10); - - switch(socket_id) { - case RIL_SOCKET_1: - strncpy(socket_name, RIL_getRilSocketName(), 9); - break; - #if (SIM_COUNT >= 2) - case RIL_SOCKET_2: - strncpy(socket_name, SOCKET2_NAME_RIL, 9); - break; - #endif - #if (SIM_COUNT >= 3) - case RIL_SOCKET_3: - strncpy(socket_name, SOCKET3_NAME_RIL, 9); - break; - #endif - #if (SIM_COUNT >= 4) - case RIL_SOCKET_4: - strncpy(socket_name, SOCKET4_NAME_RIL, 9); - break; - #endif - default: - RLOGE("Socket id is wrong!!"); - return; - } - - RLOGI("Start to listen %s", rilSocketIdToString(socket_id)); - - fdListen = android_get_control_socket(socket_name); - if (fdListen < 0) { - RLOGE("Failed to get socket %s", socket_name); - exit(-1); - } - - ret = listen(fdListen, 4); - - if (ret < 0) { - RLOGE("Failed to listen on control socket '%d': %s", - fdListen, strerror(errno)); - exit(-1); - } - socket_listen_p->fdListen = fdListen; - - /* note: non-persistent so we can accept only one connection at a time */ - ril_event_set (socket_listen_p->listen_event, fdListen, false, - listenCallback, socket_listen_p); - - rilEventAddWakeup (socket_listen_p->listen_event); -} - extern "C" void RIL_register (const RIL_RadioFunctions *callbacks) { int ret; @@ -5082,62 +460,6 @@ RIL_register (const RIL_RadioFunctions *callbacks) { memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); - /* Initialize socket1 parameters */ - s_ril_param_socket = { - RIL_SOCKET_1, /* socket_id */ - -1, /* fdListen */ - -1, /* fdCommand */ - PHONE_PROCESS, /* processName */ - &s_commands_event, /* commands_event */ - &s_listen_event, /* listen_event */ - processCommandsCallback, /* processCommandsCallback */ - NULL, /* p_rs */ - RIL_TELEPHONY_SOCKET /* type */ - }; - -#if (SIM_COUNT >= 2) - s_ril_param_socket2 = { - RIL_SOCKET_2, /* socket_id */ - -1, /* fdListen */ - -1, /* fdCommand */ - PHONE_PROCESS, /* processName */ - &s_commands_event_socket2, /* commands_event */ - &s_listen_event_socket2, /* listen_event */ - processCommandsCallback, /* processCommandsCallback */ - NULL, /* p_rs */ - RIL_TELEPHONY_SOCKET /* type */ - }; -#endif - -#if (SIM_COUNT >= 3) - s_ril_param_socket3 = { - RIL_SOCKET_3, /* socket_id */ - -1, /* fdListen */ - -1, /* fdCommand */ - PHONE_PROCESS, /* processName */ - &s_commands_event_socket3, /* commands_event */ - &s_listen_event_socket3, /* listen_event */ - processCommandsCallback, /* processCommandsCallback */ - NULL, /* p_rs */ - RIL_TELEPHONY_SOCKET /* type */ - }; -#endif - -#if (SIM_COUNT >= 4) - s_ril_param_socket4 = { - RIL_SOCKET_4, /* socket_id */ - -1, /* fdListen */ - -1, /* fdCommand */ - PHONE_PROCESS, /* processName */ - &s_commands_event_socket4, /* commands_event */ - &s_listen_event_socket4, /* listen_event */ - processCommandsCallback, /* processCommandsCallback */ - NULL, /* p_rs */ - RIL_TELEPHONY_SOCKET /* type */ - }; -#endif - - s_registerCalled = 1; RLOGI("s_registerCalled flag set, %d", s_started); @@ -5147,83 +469,19 @@ RIL_register (const RIL_RadioFunctions *callbacks) { assert(i == s_commands[i].requestNumber); } - for (int i = 0; i < (int)NUM_ELEMS(s_commands_v); i++) { - assert(i + RIL_VENDOR_COMMANDS_OFFSET == s_commands[i].requestNumber); - } - for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) { assert(i + RIL_UNSOL_RESPONSE_BASE == s_unsolResponses[i].requestNumber); } - for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses_v); i++) { - assert(i + RIL_UNSOL_RESPONSE_BASE + RIL_VENDOR_COMMANDS_OFFSET - == s_unsolResponses[i].requestNumber); - } - - // New rild impl calls RIL_startEventLoop() first - // old standalone impl wants it here. - - if (s_started == 0) { - RIL_startEventLoop(); - } - - // start listen socket1 - startListen(RIL_SOCKET_1, &s_ril_param_socket); - -#if (SIM_COUNT >= 2) - // start listen socket2 - startListen(RIL_SOCKET_2, &s_ril_param_socket2); -#endif /* (SIM_COUNT == 2) */ - -#if (SIM_COUNT >= 3) - // start listen socket3 - startListen(RIL_SOCKET_3, &s_ril_param_socket3); -#endif /* (SIM_COUNT == 3) */ - -#if (SIM_COUNT >= 4) - // start listen socket4 - startListen(RIL_SOCKET_4, &s_ril_param_socket4); -#endif /* (SIM_COUNT == 4) */ - - -#if 1 - // start debug interface socket - - char *inst = NULL; - if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) { - inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL); - } - - char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG; - if (inst != NULL) { - strlcat(rildebug, inst, MAX_DEBUG_SOCKET_NAME_LENGTH); - } - - s_fdDebug = android_get_control_socket(rildebug); - if (s_fdDebug < 0) { - RLOGE("Failed to get socket : %s errno:%d", rildebug, errno); - exit(-1); - } - - ret = listen(s_fdDebug, 4); - - if (ret < 0) { - RLOGE("Failed to listen on ril debug socket '%d': %s", - s_fdDebug, strerror(errno)); - exit(-1); - } - - ril_event_set (&s_debug_event, s_fdDebug, true, - debugCallback, NULL); - - rilEventAddWakeup (&s_debug_event); -#endif + radio::registerService(&s_callbacks, s_commands); + RLOGI("RILHIDL called registerService"); } extern "C" void -RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **),RIL_SOCKET_TYPE socketType, int argc, char **argv) { +RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **), + RIL_SOCKET_TYPE socketType, int argc, char **argv) { RIL_RadioFunctions* UimFuncs = NULL; @@ -5232,22 +490,25 @@ RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, ch switch(socketType) { case RIL_SAP_SOCKET: - RilSapSocket::initSapSocket("sap_uim_socket1", UimFuncs); + RilSapSocket::initSapSocket(RIL1_SERVICE_NAME, UimFuncs); #if (SIM_COUNT >= 2) - RilSapSocket::initSapSocket("sap_uim_socket2", UimFuncs); + RilSapSocket::initSapSocket(RIL2_SERVICE_NAME, UimFuncs); #endif #if (SIM_COUNT >= 3) - RilSapSocket::initSapSocket("sap_uim_socket3", UimFuncs); + RilSapSocket::initSapSocket(RIL3_SERVICE_NAME, UimFuncs); #endif #if (SIM_COUNT >= 4) - RilSapSocket::initSapSocket("sap_uim_socket4", UimFuncs); + RilSapSocket::initSapSocket(RIL4_SERVICE_NAME, UimFuncs); #endif break; default:; } + + RLOGI("RIL_register_socket: calling registerService"); + sap::registerService(UimFuncs); } } @@ -5309,30 +570,10 @@ checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) { return ret; } -static int findFd(int socket_id) { - int fd = s_ril_param_socket.fdCommand; -#if (SIM_COUNT >= 2) - if (socket_id == RIL_SOCKET_2) { - fd = s_ril_param_socket2.fdCommand; - } -#if (SIM_COUNT >= 3) - if (socket_id == RIL_SOCKET_3) { - fd = s_ril_param_socket3.fdCommand; - } -#endif -#if (SIM_COUNT >= 4) - if (socket_id == RIL_SOCKET_4) { - fd = s_ril_param_socket4.fdCommand; - } -#endif -#endif - return fd; -} - extern "C" void RIL_onRequestAck(RIL_Token t) { RequestInfo *pRI; - int ret, fd; + int ret; size_t errorOffset; RIL_SOCKET_ID socket_id = RIL_SOCKET_1; @@ -5345,7 +586,6 @@ RIL_onRequestAck(RIL_Token t) { } socket_id = pRI->socket_id; - fd = findFd(socket_id); #if VDBG RLOGD("Request Ack, %s", rilSocketIdToString(socket_id)); @@ -5354,24 +594,21 @@ RIL_onRequestAck(RIL_Token t) { appendPrintBuf("Ack [%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber)); if (pRI->cancelled == 0) { - Parcel p; - - p.writeInt32 (RESPONSE_SOLICITED_ACK); - p.writeInt32 (pRI->token); + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock( + (int) socket_id); + int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); - if (fd < 0) { - RLOGD ("RIL onRequestComplete: Command channel closed"); - } + radio::acknowledgeRequest((int) socket_id, pRI->token); - sendResponse(p, socket_id); + rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); } } - extern "C" void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) { RequestInfo *pRI; int ret; - int fd; size_t errorOffset; RIL_SOCKET_ID socket_id = RIL_SOCKET_1; @@ -5383,8 +620,6 @@ RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responsel } socket_id = pRI->socket_id; - fd = findFd(socket_id); - #if VDBG RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id)); #endif @@ -5394,51 +629,39 @@ RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responsel // response does not go back up the command socket RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber)); - goto done; + free(pRI); + return; } appendPrintBuf("[%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber)); if (pRI->cancelled == 0) { - Parcel p; - + int responseType; if (s_callbacks.version >= 13 && pRI->wasAckSent == 1) { // If ack was already sent, then this call is an asynchronous response. So we need to // send id indicating that we expect an ack from RIL.java as we acquire wakelock here. - p.writeInt32 (RESPONSE_SOLICITED_ACK_EXP); + responseType = RESPONSE_SOLICITED_ACK_EXP; grabPartialWakeLock(); } else { - p.writeInt32 (RESPONSE_SOLICITED); + responseType = RESPONSE_SOLICITED; } - p.writeInt32 (pRI->token); - errorOffset = p.dataPosition(); - p.writeInt32 (e); - - if (response != NULL) { - // there is a response payload, no matter success or not. - ret = pRI->pCI->responseFunction(p, response, responselen); + // there is a response payload, no matter success or not. +#if VDBG + RLOGE ("Calling responseFunction() for token %d", pRI->token); +#endif - /* if an error occurred, rewind and mark it */ - if (ret != 0) { - RLOGE ("responseFunction error, ret %d", ret); - p.setDataPosition(errorOffset); - p.writeInt32 (ret); - } - } + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock((int) socket_id); + int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); - if (e != RIL_E_SUCCESS) { - appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e)); - } + ret = pRI->pCI->responseFunction((int) socket_id, + responseType, pRI->token, e, response, responselen); - if (fd < 0) { - RLOGD ("RIL onRequestComplete: Command channel closed"); - } - sendResponse(p, socket_id); + rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); } - -done: free(pRI); } @@ -5468,7 +691,7 @@ grabPartialWakeLock() { } } -static void +void releaseWakeLock() { if (s_callbacks.version >= 13) { int ret; @@ -5515,124 +738,6 @@ wakeTimeoutCallback (void *param) { } } -static int -decodeVoiceRadioTechnology (RIL_RadioState radioState) { - switch (radioState) { - case RADIO_STATE_SIM_NOT_READY: - case RADIO_STATE_SIM_LOCKED_OR_ABSENT: - case RADIO_STATE_SIM_READY: - return RADIO_TECH_UMTS; - - case RADIO_STATE_RUIM_NOT_READY: - case RADIO_STATE_RUIM_READY: - case RADIO_STATE_RUIM_LOCKED_OR_ABSENT: - case RADIO_STATE_NV_NOT_READY: - case RADIO_STATE_NV_READY: - return RADIO_TECH_1xRTT; - - default: - RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState"); - return -1; - } -} - -static int -decodeCdmaSubscriptionSource (RIL_RadioState radioState) { - switch (radioState) { - case RADIO_STATE_SIM_NOT_READY: - case RADIO_STATE_SIM_LOCKED_OR_ABSENT: - case RADIO_STATE_SIM_READY: - case RADIO_STATE_RUIM_NOT_READY: - case RADIO_STATE_RUIM_READY: - case RADIO_STATE_RUIM_LOCKED_OR_ABSENT: - return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM; - - case RADIO_STATE_NV_NOT_READY: - case RADIO_STATE_NV_READY: - return CDMA_SUBSCRIPTION_SOURCE_NV; - - default: - RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState"); - return -1; - } -} - -static int -decodeSimStatus (RIL_RadioState radioState) { - switch (radioState) { - case RADIO_STATE_SIM_NOT_READY: - case RADIO_STATE_RUIM_NOT_READY: - case RADIO_STATE_NV_NOT_READY: - case RADIO_STATE_NV_READY: - return -1; - case RADIO_STATE_SIM_LOCKED_OR_ABSENT: - case RADIO_STATE_SIM_READY: - case RADIO_STATE_RUIM_READY: - case RADIO_STATE_RUIM_LOCKED_OR_ABSENT: - return radioState; - default: - RLOGD("decodeSimStatus: Invoked with incorrect RadioState"); - return -1; - } -} - -static bool is3gpp2(int radioTech) { - switch (radioTech) { - case RADIO_TECH_IS95A: - case RADIO_TECH_IS95B: - case RADIO_TECH_1xRTT: - case RADIO_TECH_EVDO_0: - case RADIO_TECH_EVDO_A: - case RADIO_TECH_EVDO_B: - case RADIO_TECH_EHRPD: - return true; - default: - return false; - } -} - -/* If RIL sends SIM states or RUIM states, store the voice radio - * technology and subscription source information so that they can be - * returned when telephony framework requests them - */ -static RIL_RadioState -processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) { - - if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) { - int newVoiceRadioTech; - int newCdmaSubscriptionSource; - int newSimStatus; - - /* This is old RIL. Decode Subscription source and Voice Radio Technology - from Radio State and send change notifications if there has been a change */ - newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState); - if(newVoiceRadioTech != voiceRadioTech) { - voiceRadioTech = newVoiceRadioTech; - RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, - &voiceRadioTech, sizeof(voiceRadioTech), socket_id); - } - if(is3gpp2(newVoiceRadioTech)) { - newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState); - if(newCdmaSubscriptionSource != cdmaSubscriptionSource) { - cdmaSubscriptionSource = newCdmaSubscriptionSource; - RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, - &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id); - } - } - newSimStatus = decodeSimStatus(newRadioState); - if(newSimStatus != simRuimStatus) { - simRuimStatus = newSimStatus; - RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id); - } - - /* Send RADIO_ON to telephony */ - newRadioState = RADIO_STATE_ON; - } - - return newRadioState; -} - - #if defined(ANDROID_MULTI_SIM) extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, @@ -5645,12 +750,8 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, { int unsolResponseIndex; int ret; - int64_t timeReceived = 0; bool shouldScheduleTimeout = false; - RIL_RadioState newState; RIL_SOCKET_ID soc_id = RIL_SOCKET_1; - UnsolResponseInfo *pRI = NULL; - int32_t pRI_elements; #if defined(ANDROID_MULTI_SIM) soc_id = socket_id; @@ -5664,40 +765,9 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, } unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE; - pRI = s_unsolResponses; - pRI_elements = (int32_t)NUM_ELEMS(s_unsolResponses); - - /* Hack to include Samsung responses */ - if (unsolResponse > RIL_VENDOR_COMMANDS_OFFSET + RIL_UNSOL_RESPONSE_BASE) { - pRI = s_unsolResponses_v; - pRI_elements = (int32_t)NUM_ELEMS(s_unsolResponses_v); - - /* - * Some of the vendor response codes cannot be found by calculating their index anymore, - * because they have an even higher offset and are not ordered in the array. - * Example: RIL_UNSOL_SNDMGR_WB_AMR_REPORT = 20017, but it's at index 33 in the vendor - * response array. - * Thus, look through all the vendor URIs (Unsol Response Info) and pick the correct index. - * This has a cost of O(N). - */ - int pRI_index; - for (pRI_index = 0; pRI_index < pRI_elements; pRI_index++) { - if (pRI[pRI_index].requestNumber == unsolResponse) { - unsolResponseIndex = pRI_index; - } - } - - RLOGD("SAMSUNG: unsolResponse=%d, unsolResponseIndex=%d", unsolResponse, unsolResponseIndex); - } - if (unsolResponseIndex >= 0 && unsolResponseIndex < pRI_elements) { - pRI = &pRI[unsolResponseIndex]; - } else { - RLOGE("could not map unsolResponse=%d to %s response array (index=%d)", unsolResponse, - pRI == s_unsolResponses ? "AOSP" : "Samsung", unsolResponseIndex); - } - - if (pRI == NULL || pRI->responseFunction == NULL) { + if ((unsolResponseIndex < 0) + || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) { RLOGE("unsupported unsolicited response code %d", unsolResponse); return; } @@ -5705,7 +775,7 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, // Grab a wake lock if needed for this reponse, // as we exit we'll either release it immediately // or set a timer to release it later. - switch (pRI->wakeType) { + switch (s_unsolResponses[unsolResponseIndex].wakeType) { case WAKE_PARTIAL: grabPartialWakeLock(); shouldScheduleTimeout = true; @@ -5718,51 +788,26 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, break; } - // Mark the time this was received, doing this - // after grabing the wakelock incase getting - // the elapsedRealTime might cause us to goto - // sleep. - if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { - timeReceived = elapsedRealtime(); - } - appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse)); - Parcel p; + int responseType; if (s_callbacks.version >= 13 - && pRI->wakeType == WAKE_PARTIAL) { - p.writeInt32 (RESPONSE_UNSOLICITED_ACK_EXP); + && s_unsolResponses[unsolResponseIndex].wakeType == WAKE_PARTIAL) { + responseType = RESPONSE_UNSOLICITED_ACK_EXP; } else { - p.writeInt32 (RESPONSE_UNSOLICITED); - } - p.writeInt32 (unsolResponse); - - ret = pRI->responseFunction(p, const_cast(data), datalen); - - if (ret != 0) { - // Problem with the response. Don't continue; - goto error_exit; + responseType = RESPONSE_UNSOLICITED; } - // some things get more payload - switch(unsolResponse) { - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: - newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id); - p.writeInt32(newState); - appendPrintBuf("%s {%s}", printBuf, - radioStateToString(CALL_ONSTATEREQUEST(soc_id))); - break; + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock((int) soc_id); + int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + ret = s_unsolResponses[unsolResponseIndex].responseFunction( + (int) soc_id, responseType, 0, RIL_E_SUCCESS, const_cast(data), + datalen); - case RIL_UNSOL_NITZ_TIME_RECEIVED: - // Store the time that this was received so the - // handler of this message can account for - // the time it takes to arrive and process. In - // particular the system has been known to sleep - // before this message can be processed. - p.writeInt64(timeReceived); - break; - } + rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); if (s_callbacks.version < 13) { if (shouldScheduleTimeout) { @@ -5782,28 +827,28 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, } #if VDBG - RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize()); + RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), + requestToString(unsolResponse), datalen); #endif - ret = sendResponse(p, soc_id); - if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { + if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { // Unfortunately, NITZ time is not poll/update like everything // else in the system. So, if the upstream client isn't connected, // keep a copy of the last NITZ response (with receive time noted // above) around so we can deliver it when it is connected if (s_lastNITZTimeData != NULL) { - free (s_lastNITZTimeData); + free(s_lastNITZTimeData); s_lastNITZTimeData = NULL; } - s_lastNITZTimeData = calloc(p.dataSize(), 1); + s_lastNITZTimeData = calloc(datalen, 1); if (s_lastNITZTimeData == NULL) { - RLOGE("Memory allocation failed in RIL_onUnsolicitedResponse"); - goto error_exit; + RLOGE("Memory allocation failed in RIL_onUnsolicitedResponse"); + goto error_exit; } - s_lastNITZTimeDataSize = p.dataSize(); - memcpy(s_lastNITZTimeData, p.data(), p.dataSize()); + s_lastNITZTimeDataSize = datalen; + memcpy(s_lastNITZTimeData, data, datalen); } // Normal exit @@ -5921,6 +966,7 @@ failCauseToString(RIL_Errno e) { case RIL_E_NO_NETWORK_FOUND: return "E_NO_NETWORK_FOUND"; case RIL_E_DEVICE_IN_USE: return "E_DEVICE_IN_USE"; case RIL_E_ABORTED: return "E_ABORTED"; + case RIL_E_INVALID_RESPONSE: return "INVALID_RESPONSE"; case RIL_E_OEM_ERROR_1: return "E_OEM_ERROR_1"; case RIL_E_OEM_ERROR_2: return "E_OEM_ERROR_2"; case RIL_E_OEM_ERROR_3: return "E_OEM_ERROR_3"; @@ -5955,14 +1001,6 @@ radioStateToString(RIL_RadioState s) { switch(s) { case RADIO_STATE_OFF: return "RADIO_OFF"; case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE"; - case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY"; - case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT"; - case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY"; - case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY"; - case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY"; - case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT"; - case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY"; - case RADIO_STATE_NV_READY:return"RADIO_NV_READY"; case RADIO_STATE_ON:return"RADIO_ON"; default: return ""; } @@ -6042,23 +1080,23 @@ requestToString(int request) { case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE"; case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC"; case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL"; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS "; + case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: return "QUERY_AVAILABLE_NETWORKS"; case RIL_REQUEST_DTMF_START: return "DTMF_START"; case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP"; case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION"; case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION"; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS"; case RIL_REQUEST_SET_MUTE: return "SET_MUTE"; case RIL_REQUEST_GET_MUTE: return "GET_MUTE"; case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP"; case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE"; case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST"; - case RIL_REQUEST_NV_RESET_CONFIG: return "NV_RESET_CONFIG"; case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO"; case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW"; case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS"; + case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; + case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION"; + case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; + case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM"; case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE"; case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE"; case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE"; @@ -6066,27 +1104,30 @@ requestToString(int request) { case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND"; case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE"; case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM"; - case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER"; + case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE"; + case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE"; + case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS"; case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES"; - case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE"; - case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE"; - case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE"; - case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE"; - case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE"; - case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE"; - case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE"; - case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH"; - case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF"; - case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS"; - case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE"; - case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION"; - case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY"; - case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION"; + case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "CDMA_SET_SUBSCRIPTION_SOURCE"; + case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "CDMA_SET_ROAMING_PREFERENCE"; + case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "CDMA_QUERY_ROAMING_PREFERENCE"; + case RIL_REQUEST_SET_TTY_MODE: return "SET_TTY_MODE"; + case RIL_REQUEST_QUERY_TTY_MODE: return "QUERY_TTY_MODE"; + case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE"; + case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE"; + case RIL_REQUEST_CDMA_FLASH: return "CDMA_FLASH"; + case RIL_REQUEST_CDMA_BURST_DTMF: return "CDMA_BURST_DTMF"; + case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "CDMA_VALIDATE_AND_WRITE_AKEY"; + case RIL_REQUEST_CDMA_SEND_SMS: return "CDMA_SEND_SMS"; + case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "CDMA_SMS_ACKNOWLEDGE"; + case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG: return "GSM_GET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG: return "GSM_SET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION: return "GSM_SMS_BROADCAST_ACTIVATION"; + case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG: return "CDMA_GET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG: return "CDMA_SET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION: return "CDMA_SMS_BROADCAST_ACTIVATION"; + case RIL_REQUEST_CDMA_SUBSCRIPTION: return "CDMA_SUBSCRIPTION"; case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM"; case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM"; case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY"; @@ -6097,21 +1138,22 @@ requestToString(int request) { case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING"; case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE"; case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION"; - case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU"; - case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS"; + case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU"; + case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "STK_SEND_ENVELOPE_WITH_STATUS"; case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH"; - case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; - case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST"; - case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE"; - case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN"; + case RIL_REQUEST_GET_CELL_INFO_LIST: return "GET_CELL_INFO_LIST"; + case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return "SET_UNSOL_CELL_INFO_LIST_RATE"; + case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "SET_INITIAL_ATTACH_APN"; case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE"; case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS"; case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC"; case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL"; case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL"; case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL"; - case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY"; - case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY"; + case RIL_REQUEST_NV_READ_ITEM: return "NV_READ_ITEM"; + case RIL_REQUEST_NV_WRITE_ITEM: return "NV_WRITE_ITEM"; + case RIL_REQUEST_NV_WRITE_CDMA_PRL: return "NV_WRITE_CDMA_PRL"; + case RIL_REQUEST_NV_RESET_CONFIG: return "NV_RESET_CONFIG"; case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION"; case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA"; case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG"; @@ -6119,8 +1161,16 @@ requestToString(int request) { case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO"; case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE"; case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE"; + case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN"; + case RIL_REQUEST_GET_RADIO_CAPABILITY: return "GET_RADIO_CAPABILITY"; + case RIL_REQUEST_SET_RADIO_CAPABILITY: return "SET_RADIO_CAPABILITY"; + case RIL_REQUEST_START_LCE: return "START_LCE"; + case RIL_REQUEST_STOP_LCE: return "STOP_LCE"; + case RIL_REQUEST_PULL_LCEDATA: return "PULL_LCEDATA"; + case RIL_REQUEST_GET_ACTIVITY_INFO: return "GET_ACTIVITY_INFO"; case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS"; case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS"; + case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RESPONSE_ACKNOWLEDGEMENT"; case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; @@ -6128,21 +1178,21 @@ requestToString(int request) { case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT"; case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM"; case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD"; - case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)"; + case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST"; case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED"; case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH"; + case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED"; case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION"; case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END"; case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND"; case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY"; case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP"; - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL"; + case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL"; case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH"; - case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED"; case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED"; - case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS"; - case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS"; + case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS"; + case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS"; case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL"; case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED"; case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE"; @@ -6158,17 +1208,17 @@ requestToString(int request) { case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST"; - case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED"; + case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED"; case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED"; case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY"; - case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED"; + case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "UNSOL_HARDWARE_CONFIG_CHANGED"; case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED"; + case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY"; + case RIL_UNSOL_MODEM_RESTART: return "UNSOL_MODEM_RESTART"; case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS"; case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY"; - case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN"; - case RIL_UNSOL_RADIO_CAPABILITY: return "RIL_UNSOL_RADIO_CAPABILITY"; - case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RIL_RESPONSE_ACKNOWLEDGEMENT"; - case RIL_UNSOL_PCO_DATA: return "RIL_UNSOL_PCO_DATA"; + case RIL_UNSOL_LCEDATA_RECV: return "UNSOL_LCEDATA_RECV"; + case RIL_UNSOL_PCO_DATA: return "UNSOL_PCO_DATA"; default: return ""; } } @@ -6196,28 +1246,4 @@ rilSocketIdToString(RIL_SOCKET_ID socket_id) } } -/* - * Returns true for a debuggable build. - */ -static bool isDebuggable() { - char debuggable[PROP_VALUE_MAX]; - property_get("ro.debuggable", debuggable, "0"); - if (strcmp(debuggable, "1") == 0) { - return true; - } - return false; -} - -} /* namespace android */ - -void rilEventAddWakeup_helper(struct ril_event *ev) { - android::rilEventAddWakeup(ev); -} - -void listenCallback_helper(int fd, short flags, void *param) { - android::listenCallback(fd, flags, param); -} - -int blockingWrite_helper(int fd, void *buffer, size_t len) { - return android::blockingWrite(fd, buffer, len); -} +} /* namespace android */ \ No newline at end of file diff --git a/ril/libril/ril_commands.h b/ril/libril/ril_commands.h index bdb179a0..c9ec0cc8 100644 --- a/ril/libril/ril_commands.h +++ b/ril/libril/ril_commands.h @@ -14,149 +14,144 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ - {0, NULL, NULL}, //none - {RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus}, - {RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts}, - {RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts}, - {RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts}, - {RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts}, - {RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts}, - {RIL_REQUEST_CHANGE_SIM_PIN2, dispatchStrings, responseInts}, - {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, dispatchStrings, responseInts}, - {RIL_REQUEST_GET_CURRENT_CALLS, dispatchVoid, responseCallList}, - {RIL_REQUEST_DIAL, dispatchDial, responseVoid}, - {RIL_REQUEST_GET_IMSI, dispatchStrings, responseString}, - {RIL_REQUEST_HANGUP, dispatchInts, responseVoid}, - {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, dispatchVoid, responseVoid}, - {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, dispatchVoid, responseVoid}, - {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, dispatchVoid, responseVoid}, - {RIL_REQUEST_CONFERENCE, dispatchVoid, responseVoid}, - {RIL_REQUEST_UDUB, dispatchVoid, responseVoid}, -#ifndef EXYNOS4_ENHANCEMENTS - {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseFailCause}, -#else - /* - * Exynos4 devices send an extra int for LAST_CALL_FAIL_CAUSE - * which causes responseFailCause to think it's a string and crash. - */ - {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseInts}, -#endif - {RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength}, - {RIL_REQUEST_VOICE_REGISTRATION_STATE, dispatchVoid, responseStrings}, - {RIL_REQUEST_DATA_REGISTRATION_STATE, dispatchVoid, responseStrings}, - {RIL_REQUEST_OPERATOR, dispatchVoid, responseStrings}, - {RIL_REQUEST_RADIO_POWER, dispatchInts, responseVoid}, - {RIL_REQUEST_DTMF, dispatchString, responseVoid}, - {RIL_REQUEST_SEND_SMS, dispatchStrings, responseSMS}, - {RIL_REQUEST_SEND_SMS_EXPECT_MORE, dispatchStrings, responseSMS}, - {RIL_REQUEST_SETUP_DATA_CALL, dispatchDataCall, responseSetupDataCall}, - {RIL_REQUEST_SIM_IO, dispatchSIM_IO, responseSIM_IO}, - {RIL_REQUEST_SEND_USSD, dispatchString, responseVoid}, - {RIL_REQUEST_CANCEL_USSD, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_CLIR, dispatchVoid, responseInts}, - {RIL_REQUEST_SET_CLIR, dispatchInts, responseVoid}, - {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, dispatchCallForward, responseCallForwards}, - {RIL_REQUEST_SET_CALL_FORWARD, dispatchCallForward, responseVoid}, - {RIL_REQUEST_QUERY_CALL_WAITING, dispatchInts, responseInts}, - {RIL_REQUEST_SET_CALL_WAITING, dispatchInts, responseVoid}, - {RIL_REQUEST_SMS_ACKNOWLEDGE, dispatchInts, responseVoid}, - {RIL_REQUEST_GET_IMEI, dispatchVoid, responseString}, - {RIL_REQUEST_GET_IMEISV, dispatchVoid, responseString}, - {RIL_REQUEST_ANSWER,dispatchVoid, responseVoid}, - {RIL_REQUEST_DEACTIVATE_DATA_CALL, dispatchStrings, responseVoid}, - {RIL_REQUEST_QUERY_FACILITY_LOCK, dispatchStrings, responseInts}, - {RIL_REQUEST_SET_FACILITY_LOCK, dispatchStrings, responseInts}, - {RIL_REQUEST_CHANGE_BARRING_PASSWORD, dispatchStrings, responseVoid}, - {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, dispatchVoid, responseInts}, - {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, dispatchVoid, responseVoid}, - {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, dispatchString, responseVoid}, - {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , dispatchVoid, responseStrings}, - {RIL_REQUEST_DTMF_START, dispatchString, responseVoid}, - {RIL_REQUEST_DTMF_STOP, dispatchVoid, responseVoid}, - {RIL_REQUEST_BASEBAND_VERSION, dispatchVoid, responseString}, - {RIL_REQUEST_SEPARATE_CONNECTION, dispatchInts, responseVoid}, - {RIL_REQUEST_SET_MUTE, dispatchInts, responseVoid}, - {RIL_REQUEST_GET_MUTE, dispatchVoid, responseInts}, - {RIL_REQUEST_QUERY_CLIP, dispatchVoid, responseInts}, - {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, dispatchVoid, responseInts}, - {RIL_REQUEST_DATA_CALL_LIST, dispatchVoid, responseDataCallList}, - {RIL_REQUEST_RESET_RADIO, dispatchVoid, responseVoid}, - {RIL_REQUEST_OEM_HOOK_RAW, dispatchRaw, responseRaw}, - {RIL_REQUEST_OEM_HOOK_STRINGS, dispatchStrings, responseStrings}, - {RIL_REQUEST_SCREEN_STATE, dispatchInts, responseVoid}, - {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, dispatchInts, responseVoid}, - {RIL_REQUEST_WRITE_SMS_TO_SIM, dispatchSmsWrite, responseInts}, - {RIL_REQUEST_DELETE_SMS_ON_SIM, dispatchInts, responseVoid}, - {RIL_REQUEST_SET_BAND_MODE, dispatchInts, responseVoid}, - {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, dispatchVoid, responseInts}, - {RIL_REQUEST_STK_GET_PROFILE, dispatchVoid, responseString}, - {RIL_REQUEST_STK_SET_PROFILE, dispatchString, responseVoid}, - {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, dispatchString, responseString}, - {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, dispatchString, responseVoid}, - {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, dispatchInts, responseVoid}, - {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, dispatchVoid, responseVoid}, - {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, dispatchInts, responseVoid}, - {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, dispatchVoid, responseInts}, - {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, dispatchVoid, responseCellList}, - {RIL_REQUEST_SET_LOCATION_UPDATES, dispatchInts, responseVoid}, - {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, dispatchInts, responseVoid}, - {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, dispatchInts, responseVoid}, - {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, dispatchVoid, responseInts}, - {RIL_REQUEST_SET_TTY_MODE, dispatchInts, responseVoid}, - {RIL_REQUEST_QUERY_TTY_MODE, dispatchVoid, responseInts}, - {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, dispatchInts, responseVoid}, - {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, dispatchVoid, responseInts}, - {RIL_REQUEST_CDMA_FLASH, dispatchString, responseVoid}, - {RIL_REQUEST_CDMA_BURST_DTMF, dispatchStrings, responseVoid}, - {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, dispatchString, responseVoid}, - {RIL_REQUEST_CDMA_SEND_SMS, dispatchCdmaSms, responseSMS}, - {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, dispatchCdmaSmsAck, responseVoid}, - {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseGsmBrSmsCnf}, - {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, dispatchGsmBrSmsCnf, responseVoid}, - {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid}, - {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseCdmaBrSmsCnf}, - {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, dispatchCdmaBrSmsCnf, responseVoid}, - {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid}, - {RIL_REQUEST_CDMA_SUBSCRIPTION, dispatchVoid, responseStrings}, - {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, dispatchRilCdmaSmsWriteArgs, responseInts}, - {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, dispatchInts, responseVoid}, - {RIL_REQUEST_DEVICE_IDENTITY, dispatchVoid, responseStrings}, - {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_SMSC_ADDRESS, dispatchVoid, responseString}, - {RIL_REQUEST_SET_SMSC_ADDRESS, dispatchString, responseVoid}, - {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, dispatchInts, responseVoid}, - {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, dispatchVoid, responseVoid}, - {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, dispatchCdmaSubscriptionSource, responseInts}, - {RIL_REQUEST_ISIM_AUTHENTICATION, dispatchString, responseString}, - {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, dispatchStrings, responseVoid}, - {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, dispatchString, responseSIM_IO}, - {RIL_REQUEST_VOICE_RADIO_TECH, dispatchVoiceRadioTech, responseInts}, - {RIL_REQUEST_GET_CELL_INFO_LIST, dispatchVoid, responseCellInfoList}, - {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, dispatchInts, responseVoid}, - {RIL_REQUEST_SET_INITIAL_ATTACH_APN, dispatchSetInitialAttachApn, responseVoid}, - {RIL_REQUEST_IMS_REGISTRATION_STATE, dispatchVoid, responseInts}, - {RIL_REQUEST_IMS_SEND_SMS, dispatchImsSms, responseSMS}, - {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, dispatchSIM_APDU, responseSIM_IO}, - {RIL_REQUEST_SIM_OPEN_CHANNEL, dispatchString, responseInts}, - {RIL_REQUEST_SIM_CLOSE_CHANNEL, dispatchInts, responseVoid}, - {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, dispatchSIM_APDU, responseSIM_IO}, - {RIL_REQUEST_NV_READ_ITEM, dispatchNVReadItem, responseString}, - {RIL_REQUEST_NV_WRITE_ITEM, dispatchNVWriteItem, responseVoid}, - {RIL_REQUEST_NV_WRITE_CDMA_PRL, dispatchRaw, responseVoid}, - {RIL_REQUEST_NV_RESET_CONFIG, dispatchInts, responseVoid}, - {RIL_REQUEST_SET_UICC_SUBSCRIPTION, dispatchUiccSubscripton, responseVoid}, - {RIL_REQUEST_ALLOW_DATA, dispatchInts, responseVoid}, - {RIL_REQUEST_GET_HARDWARE_CONFIG, dispatchVoid, responseHardwareConfig}, - {RIL_REQUEST_SIM_AUTHENTICATION, dispatchSimAuthentication, responseSIM_IO}, - {RIL_REQUEST_GET_DC_RT_INFO, dispatchVoid, responseDcRtInfo}, - {RIL_REQUEST_SET_DC_RT_INFO_RATE, dispatchInts, responseVoid}, - {RIL_REQUEST_SET_DATA_PROFILE, dispatchDataProfile, responseVoid}, - {RIL_REQUEST_SHUTDOWN, dispatchVoid, responseVoid}, - {RIL_REQUEST_GET_RADIO_CAPABILITY, dispatchVoid, responseRadioCapability}, - {RIL_REQUEST_SET_RADIO_CAPABILITY, dispatchRadioCapability, responseRadioCapability}, - {RIL_REQUEST_START_LCE, dispatchInts, responseLceStatus}, - {RIL_REQUEST_STOP_LCE, dispatchVoid, responseLceStatus}, - {RIL_REQUEST_PULL_LCEDATA, dispatchVoid, responseLceData}, - {RIL_REQUEST_GET_ACTIVITY_INFO, dispatchVoid, responseActivityData}, - {RIL_REQUEST_SET_CARRIER_RESTRICTIONS, dispatchCarrierRestrictions, responseInts}, - {RIL_REQUEST_GET_CARRIER_RESTRICTIONS, dispatchVoid, responseCarrierRestrictions}, + {0, NULL}, //none + {RIL_REQUEST_GET_SIM_STATUS, radio::getIccCardStatusResponse}, + {RIL_REQUEST_ENTER_SIM_PIN, radio::supplyIccPinForAppResponse}, + {RIL_REQUEST_ENTER_SIM_PUK, radio::supplyIccPukForAppResponse}, + {RIL_REQUEST_ENTER_SIM_PIN2, radio::supplyIccPin2ForAppResponse}, + {RIL_REQUEST_ENTER_SIM_PUK2, radio::supplyIccPuk2ForAppResponse}, + {RIL_REQUEST_CHANGE_SIM_PIN, radio::changeIccPinForAppResponse}, + {RIL_REQUEST_CHANGE_SIM_PIN2, radio::changeIccPin2ForAppResponse}, + {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, radio::supplyNetworkDepersonalizationResponse}, + {RIL_REQUEST_GET_CURRENT_CALLS, radio::getCurrentCallsResponse}, + {RIL_REQUEST_DIAL, radio::dialResponse}, + {RIL_REQUEST_GET_IMSI, radio::getIMSIForAppResponse}, + {RIL_REQUEST_HANGUP, radio::hangupConnectionResponse}, + {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, radio::hangupWaitingOrBackgroundResponse}, + {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, radio::hangupForegroundResumeBackgroundResponse}, + {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, radio::switchWaitingOrHoldingAndActiveResponse}, + {RIL_REQUEST_CONFERENCE, radio::conferenceResponse}, + {RIL_REQUEST_UDUB, radio::rejectCallResponse}, + {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, radio::getLastCallFailCauseResponse}, + {RIL_REQUEST_SIGNAL_STRENGTH, radio::getSignalStrengthResponse}, + {RIL_REQUEST_VOICE_REGISTRATION_STATE, radio::getVoiceRegistrationStateResponse}, + {RIL_REQUEST_DATA_REGISTRATION_STATE, radio::getDataRegistrationStateResponse}, + {RIL_REQUEST_OPERATOR, radio::getOperatorResponse}, + {RIL_REQUEST_RADIO_POWER, radio::setRadioPowerResponse}, + {RIL_REQUEST_DTMF, radio::sendDtmfResponse}, + {RIL_REQUEST_SEND_SMS, radio::sendSmsResponse}, + {RIL_REQUEST_SEND_SMS_EXPECT_MORE, radio::sendSMSExpectMoreResponse}, + {RIL_REQUEST_SETUP_DATA_CALL, radio::setupDataCallResponse}, + {RIL_REQUEST_SIM_IO, radio::iccIOForAppResponse}, + {RIL_REQUEST_SEND_USSD, radio::sendUssdResponse}, + {RIL_REQUEST_CANCEL_USSD, radio::cancelPendingUssdResponse}, + {RIL_REQUEST_GET_CLIR, radio::getClirResponse}, + {RIL_REQUEST_SET_CLIR, radio::setClirResponse}, + {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, radio::getCallForwardStatusResponse}, + {RIL_REQUEST_SET_CALL_FORWARD, radio::setCallForwardResponse}, + {RIL_REQUEST_QUERY_CALL_WAITING, radio::getCallWaitingResponse}, + {RIL_REQUEST_SET_CALL_WAITING, radio::setCallWaitingResponse}, + {RIL_REQUEST_SMS_ACKNOWLEDGE, radio::acknowledgeLastIncomingGsmSmsResponse}, + {RIL_REQUEST_GET_IMEI, NULL}, + {RIL_REQUEST_GET_IMEISV, NULL}, + {RIL_REQUEST_ANSWER, radio::acceptCallResponse}, + {RIL_REQUEST_DEACTIVATE_DATA_CALL, radio::deactivateDataCallResponse}, + {RIL_REQUEST_QUERY_FACILITY_LOCK, radio::getFacilityLockForAppResponse}, + {RIL_REQUEST_SET_FACILITY_LOCK, radio::setFacilityLockForAppResponse}, + {RIL_REQUEST_CHANGE_BARRING_PASSWORD, radio::setBarringPasswordResponse}, + {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, radio::getNetworkSelectionModeResponse}, + {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, radio::setNetworkSelectionModeAutomaticResponse}, + {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, radio::setNetworkSelectionModeManualResponse}, + {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , radio::getAvailableNetworksResponse}, + {RIL_REQUEST_DTMF_START, radio::startDtmfResponse}, + {RIL_REQUEST_DTMF_STOP, radio::stopDtmfResponse}, + {RIL_REQUEST_BASEBAND_VERSION, radio::getBasebandVersionResponse}, + {RIL_REQUEST_SEPARATE_CONNECTION, radio::separateConnectionResponse}, + {RIL_REQUEST_SET_MUTE, radio::setMuteResponse}, + {RIL_REQUEST_GET_MUTE, radio::getMuteResponse}, + {RIL_REQUEST_QUERY_CLIP, radio::getClipResponse}, + {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, NULL}, + {RIL_REQUEST_DATA_CALL_LIST, radio::getDataCallListResponse}, + {RIL_REQUEST_RESET_RADIO, NULL}, + {RIL_REQUEST_OEM_HOOK_RAW, radio::sendRequestRawResponse}, + {RIL_REQUEST_OEM_HOOK_STRINGS, radio::sendRequestStringsResponse}, + {RIL_REQUEST_SCREEN_STATE, radio::sendDeviceStateResponse}, // Note the response function is different. + {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, radio::setSuppServiceNotificationsResponse}, + {RIL_REQUEST_WRITE_SMS_TO_SIM, radio::writeSmsToSimResponse}, + {RIL_REQUEST_DELETE_SMS_ON_SIM, radio::deleteSmsOnSimResponse}, + {RIL_REQUEST_SET_BAND_MODE, radio::setBandModeResponse}, + {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, radio::getAvailableBandModesResponse}, + {RIL_REQUEST_STK_GET_PROFILE, NULL}, + {RIL_REQUEST_STK_SET_PROFILE, NULL}, + {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, radio::sendEnvelopeResponse}, + {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, radio::sendTerminalResponseToSimResponse}, + {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, radio::handleStkCallSetupRequestFromSimResponse}, + {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, radio::explicitCallTransferResponse}, + {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, radio::setPreferredNetworkTypeResponse}, + {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, radio::getPreferredNetworkTypeResponse}, + {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, radio::getNeighboringCidsResponse}, + {RIL_REQUEST_SET_LOCATION_UPDATES, radio::setLocationUpdatesResponse}, + {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, radio::setCdmaSubscriptionSourceResponse}, + {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, radio::setCdmaRoamingPreferenceResponse}, + {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, radio::getCdmaRoamingPreferenceResponse}, + {RIL_REQUEST_SET_TTY_MODE, radio::setTTYModeResponse}, + {RIL_REQUEST_QUERY_TTY_MODE, radio::getTTYModeResponse}, + {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, radio::setPreferredVoicePrivacyResponse}, + {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, radio::getPreferredVoicePrivacyResponse}, + {RIL_REQUEST_CDMA_FLASH, radio::sendCDMAFeatureCodeResponse}, + {RIL_REQUEST_CDMA_BURST_DTMF, radio::sendBurstDtmfResponse}, + {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, NULL}, + {RIL_REQUEST_CDMA_SEND_SMS, radio::sendCdmaSmsResponse}, + {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, radio::acknowledgeLastIncomingCdmaSmsResponse}, + {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, radio::getGsmBroadcastConfigResponse}, + {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, radio::setGsmBroadcastConfigResponse}, + {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, radio::setGsmBroadcastActivationResponse}, + {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, radio::getCdmaBroadcastConfigResponse}, + {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, radio::setCdmaBroadcastConfigResponse}, + {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, radio::setCdmaBroadcastActivationResponse}, + {RIL_REQUEST_CDMA_SUBSCRIPTION, radio::getCDMASubscriptionResponse}, + {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, radio::writeSmsToRuimResponse}, + {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, radio::deleteSmsOnRuimResponse}, + {RIL_REQUEST_DEVICE_IDENTITY, radio::getDeviceIdentityResponse}, + {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, radio::exitEmergencyCallbackModeResponse}, + {RIL_REQUEST_GET_SMSC_ADDRESS, radio::getSmscAddressResponse}, + {RIL_REQUEST_SET_SMSC_ADDRESS, radio::setSmscAddressResponse}, + {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, radio::reportSmsMemoryStatusResponse}, + {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, radio::reportStkServiceIsRunningResponse}, + {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, radio::getCdmaSubscriptionSourceResponse}, + {RIL_REQUEST_ISIM_AUTHENTICATION, radio::requestIsimAuthenticationResponse}, + {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, radio::acknowledgeIncomingGsmSmsWithPduResponse}, + {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, radio::sendEnvelopeWithStatusResponse}, + {RIL_REQUEST_VOICE_RADIO_TECH, radio::getVoiceRadioTechnologyResponse}, + {RIL_REQUEST_GET_CELL_INFO_LIST, radio::getCellInfoListResponse}, + {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, radio::setCellInfoListRateResponse}, + {RIL_REQUEST_SET_INITIAL_ATTACH_APN, radio::setInitialAttachApnResponse}, + {RIL_REQUEST_IMS_REGISTRATION_STATE, radio::getImsRegistrationStateResponse}, + {RIL_REQUEST_IMS_SEND_SMS, radio::sendImsSmsResponse}, + {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, radio::iccTransmitApduBasicChannelResponse}, + {RIL_REQUEST_SIM_OPEN_CHANNEL, radio::iccOpenLogicalChannelResponse}, + {RIL_REQUEST_SIM_CLOSE_CHANNEL, radio::iccCloseLogicalChannelResponse}, + {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, radio::iccTransmitApduLogicalChannelResponse}, + {RIL_REQUEST_NV_READ_ITEM, radio::nvReadItemResponse}, + {RIL_REQUEST_NV_WRITE_ITEM, radio::nvWriteItemResponse}, + {RIL_REQUEST_NV_WRITE_CDMA_PRL, radio::nvWriteCdmaPrlResponse}, + {RIL_REQUEST_NV_RESET_CONFIG, radio::nvResetConfigResponse}, + {RIL_REQUEST_SET_UICC_SUBSCRIPTION, radio::setUiccSubscriptionResponse}, + {RIL_REQUEST_ALLOW_DATA, radio::setDataAllowedResponse}, + {RIL_REQUEST_GET_HARDWARE_CONFIG, radio::getHardwareConfigResponse}, + {RIL_REQUEST_SIM_AUTHENTICATION, radio::requestIccSimAuthenticationResponse}, + {RIL_REQUEST_GET_DC_RT_INFO, NULL}, + {RIL_REQUEST_SET_DC_RT_INFO_RATE, NULL}, + {RIL_REQUEST_SET_DATA_PROFILE, radio::setDataProfileResponse}, + {RIL_REQUEST_SHUTDOWN, radio::requestShutdownResponse}, + {RIL_REQUEST_GET_RADIO_CAPABILITY, radio::getRadioCapabilityResponse}, + {RIL_REQUEST_SET_RADIO_CAPABILITY, radio::setRadioCapabilityResponse}, + {RIL_REQUEST_START_LCE, radio::startLceServiceResponse}, + {RIL_REQUEST_STOP_LCE, radio::stopLceServiceResponse}, + {RIL_REQUEST_PULL_LCEDATA, radio::pullLceDataResponse}, + {RIL_REQUEST_GET_ACTIVITY_INFO, radio::getModemActivityInfoResponse}, + {RIL_REQUEST_SET_CARRIER_RESTRICTIONS, radio::setAllowedCarriersResponse}, + {RIL_REQUEST_GET_CARRIER_RESTRICTIONS, radio::getAllowedCarriersResponse}, + {RIL_REQUEST_SEND_DEVICE_STATE, radio::sendDeviceStateResponse}, + {RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, radio::setIndicationFilterResponse}, + {RIL_REQUEST_SET_SIM_CARD_POWER, radio::setSimCardPowerResponse}, diff --git a/ril/libril/ril_internal.h b/ril/libril/ril_internal.h new file mode 100644 index 00000000..350791b2 --- /dev/null +++ b/ril/libril/ril_internal.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RIL_INTERNAL_H +#define ANDROID_RIL_INTERNAL_H + +namespace android { + +#define RIL_SERVICE_NAME_BASE "slot" +#define RIL1_SERVICE_NAME "slot1" +#define RIL2_SERVICE_NAME "slot2" +#define RIL3_SERVICE_NAME "slot3" +#define RIL4_SERVICE_NAME "slot4" + +/* Constants for response types */ +#define RESPONSE_SOLICITED 0 +#define RESPONSE_UNSOLICITED 1 +#define RESPONSE_SOLICITED_ACK 2 +#define RESPONSE_SOLICITED_ACK_EXP 3 +#define RESPONSE_UNSOLICITED_ACK_EXP 4 + +// Enable verbose logging +#define VDBG 0 + +#define MIN(a,b) ((a)<(b) ? (a) : (b)) + +// Enable RILC log +#define RILC_LOG 0 + +#if RILC_LOG + #define startRequest sprintf(printBuf, "(") + #define closeRequest sprintf(printBuf, "%s)", printBuf) + #define printRequest(token, req) \ + RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf) + + #define startResponse sprintf(printBuf, "%s {", printBuf) + #define closeResponse sprintf(printBuf, "%s}", printBuf) + #define printResponse RLOGD("%s", printBuf) + + #define clearPrintBuf printBuf[0] = 0 + #define removeLastChar printBuf[strlen(printBuf)-1] = 0 + #define appendPrintBuf(x...) snprintf(printBuf, PRINTBUF_SIZE, x) +#else + #define startRequest + #define closeRequest + #define printRequest(token, req) + #define startResponse + #define closeResponse + #define printResponse + #define clearPrintBuf + #define removeLastChar + #define appendPrintBuf(x...) +#endif + +typedef struct CommandInfo CommandInfo; + +extern "C" const char * requestToString(int request); + +typedef struct RequestInfo { + int32_t token; //this is not RIL_Token + CommandInfo *pCI; + struct RequestInfo *p_next; + char cancelled; + char local; // responses to local commands do not go back to command process + RIL_SOCKET_ID socket_id; + int wasAckSent; // Indicates whether an ack was sent earlier +} RequestInfo; + +typedef struct CommandInfo { + int requestNumber; + int(*responseFunction) (int slotId, int responseType, int token, + RIL_Errno e, void *response, size_t responselen); +} CommandInfo; + +RequestInfo * addRequestToList(int serial, int slotId, int request); + +char * RIL_getServiceName(); + +void releaseWakeLock(); + +void onNewCommandConnect(RIL_SOCKET_ID socket_id); + +} // namespace android + +#endif //ANDROID_RIL_INTERNAL_H diff --git a/ril/libril/ril_service.cpp b/ril/libril/ril_service.cpp new file mode 100644 index 00000000..0c7a2c0f --- /dev/null +++ b/ril/libril/ril_service.cpp @@ -0,0 +1,8240 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "RILC" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define INVALID_HEX_CHAR 16 + +// Enable verbose logging +#define VDBG 0 + +using namespace android::hardware::radio::V1_0; +using namespace android::hardware::radio::deprecated::V1_0; +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; +using ::android::hardware::Return; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_array; +using ::android::hardware::Void; +using android::CommandInfo; +using android::RequestInfo; +using android::requestToString; +using android::sp; + +#define BOOL_TO_INT(x) (x ? 1 : 0) +#define ATOI_NULL_HANDLED(x) (x ? atoi(x) : -1) +#define ATOI_NULL_HANDLED_DEF(x, defaultVal) (x ? atoi(x) : defaultVal) + +#if defined(ANDROID_MULTI_SIM) +#define CALL_ONREQUEST(a, b, c, d, e) \ + s_vendorFunctions->onRequest((a), (b), (c), (d), ((RIL_SOCKET_ID)(e))) +#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest((RIL_SOCKET_ID)(a)) +#else +#define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions->onRequest((a), (b), (c), (d)) +#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest() +#endif + +RIL_RadioFunctions *s_vendorFunctions = NULL; +static CommandInfo *s_commands; + +struct RadioImpl; +struct OemHookImpl; + +#if (SIM_COUNT >= 2) +sp radioService[SIM_COUNT]; +sp oemHookService[SIM_COUNT]; +// counter used for synchronization. It is incremented every time response callbacks are updated. +volatile int32_t mCounterRadio[SIM_COUNT]; +volatile int32_t mCounterOemHook[SIM_COUNT]; +#else +sp radioService[1]; +sp oemHookService[1]; +// counter used for synchronization. It is incremented every time response callbacks are updated. +volatile int32_t mCounterRadio[1]; +volatile int32_t mCounterOemHook[1]; +#endif + +static pthread_rwlock_t radioServiceRwlock = PTHREAD_RWLOCK_INITIALIZER; + +#if (SIM_COUNT >= 2) +static pthread_rwlock_t radioServiceRwlock2 = PTHREAD_RWLOCK_INITIALIZER; +#if (SIM_COUNT >= 3) +static pthread_rwlock_t radioServiceRwlock3 = PTHREAD_RWLOCK_INITIALIZER; +#if (SIM_COUNT >= 4) +static pthread_rwlock_t radioServiceRwlock4 = PTHREAD_RWLOCK_INITIALIZER; +#endif +#endif +#endif + +void convertRilHardwareConfigListToHal(void *response, size_t responseLen, + hidl_vec& records); + +void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc); + +void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce); + +void convertRilSignalStrengthToHal(void *response, size_t responseLen, + SignalStrength& signalStrength); + +void convertRilDataCallToHal(RIL_Data_Call_Response_v6 *dcResponse, + SetupDataCallResult& dcResult); + +void convertRilDataCallToHal(RIL_Data_Call_Response_v9 *dcResponse, + SetupDataCallResult& dcResult); + +void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, + SetupDataCallResult& dcResult); + +void convertRilDataCallListToHal(void *response, size_t responseLen, + hidl_vec& dcResultList); + +void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec& records); + +struct RadioImpl : public IRadio { + int32_t mSlotId; + sp mRadioResponse; + sp mRadioIndication; + + Return setResponseFunctions( + const ::android::sp& radioResponse, + const ::android::sp& radioIndication); + + Return getIccCardStatus(int32_t serial); + + Return supplyIccPinForApp(int32_t serial, const hidl_string& pin, + const hidl_string& aid); + + Return supplyIccPukForApp(int32_t serial, const hidl_string& puk, + const hidl_string& pin, const hidl_string& aid); + + Return supplyIccPin2ForApp(int32_t serial, + const hidl_string& pin2, + const hidl_string& aid); + + Return supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, + const hidl_string& pin2, const hidl_string& aid); + + Return changeIccPinForApp(int32_t serial, const hidl_string& oldPin, + const hidl_string& newPin, const hidl_string& aid); + + Return changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, + const hidl_string& newPin2, const hidl_string& aid); + + Return supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin); + + Return getCurrentCalls(int32_t serial); + + Return dial(int32_t serial, const Dial& dialInfo); + + Return getImsiForApp(int32_t serial, + const ::android::hardware::hidl_string& aid); + + Return hangup(int32_t serial, int32_t gsmIndex); + + Return hangupWaitingOrBackground(int32_t serial); + + Return hangupForegroundResumeBackground(int32_t serial); + + Return switchWaitingOrHoldingAndActive(int32_t serial); + + Return conference(int32_t serial); + + Return rejectCall(int32_t serial); + + Return getLastCallFailCause(int32_t serial); + + Return getSignalStrength(int32_t serial); + + Return getVoiceRegistrationState(int32_t serial); + + Return getDataRegistrationState(int32_t serial); + + Return getOperator(int32_t serial); + + Return setRadioPower(int32_t serial, bool on); + + Return sendDtmf(int32_t serial, + const ::android::hardware::hidl_string& s); + + Return sendSms(int32_t serial, const GsmSmsMessage& message); + + Return sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message); + + Return setupDataCall(int32_t serial, + RadioTechnology radioTechnology, + const DataProfileInfo& profileInfo, + bool modemCognitive, + bool roamingAllowed, + bool isRoaming); + + Return iccIOForApp(int32_t serial, + const IccIo& iccIo); + + Return sendUssd(int32_t serial, + const ::android::hardware::hidl_string& ussd); + + Return cancelPendingUssd(int32_t serial); + + Return getClir(int32_t serial); + + Return setClir(int32_t serial, int32_t status); + + Return getCallForwardStatus(int32_t serial, + const CallForwardInfo& callInfo); + + Return setCallForward(int32_t serial, + const CallForwardInfo& callInfo); + + Return getCallWaiting(int32_t serial, int32_t serviceClass); + + Return setCallWaiting(int32_t serial, bool enable, int32_t serviceClass); + + Return acknowledgeLastIncomingGsmSms(int32_t serial, + bool success, SmsAcknowledgeFailCause cause); + + Return acceptCall(int32_t serial); + + Return deactivateDataCall(int32_t serial, + int32_t cid, bool reasonRadioShutDown); + + Return getFacilityLockForApp(int32_t serial, + const ::android::hardware::hidl_string& facility, + const ::android::hardware::hidl_string& password, + int32_t serviceClass, + const ::android::hardware::hidl_string& appId); + + Return setFacilityLockForApp(int32_t serial, + const ::android::hardware::hidl_string& facility, + bool lockState, + const ::android::hardware::hidl_string& password, + int32_t serviceClass, + const ::android::hardware::hidl_string& appId); + + Return setBarringPassword(int32_t serial, + const ::android::hardware::hidl_string& facility, + const ::android::hardware::hidl_string& oldPassword, + const ::android::hardware::hidl_string& newPassword); + + Return getNetworkSelectionMode(int32_t serial); + + Return setNetworkSelectionModeAutomatic(int32_t serial); + + Return setNetworkSelectionModeManual(int32_t serial, + const ::android::hardware::hidl_string& operatorNumeric); + + Return getAvailableNetworks(int32_t serial); + + Return startDtmf(int32_t serial, + const ::android::hardware::hidl_string& s); + + Return stopDtmf(int32_t serial); + + Return getBasebandVersion(int32_t serial); + + Return separateConnection(int32_t serial, int32_t gsmIndex); + + Return setMute(int32_t serial, bool enable); + + Return getMute(int32_t serial); + + Return getClip(int32_t serial); + + Return getDataCallList(int32_t serial); + + Return setSuppServiceNotifications(int32_t serial, bool enable); + + Return writeSmsToSim(int32_t serial, + const SmsWriteArgs& smsWriteArgs); + + Return deleteSmsOnSim(int32_t serial, int32_t index); + + Return setBandMode(int32_t serial, RadioBandMode mode); + + Return getAvailableBandModes(int32_t serial); + + Return sendEnvelope(int32_t serial, + const ::android::hardware::hidl_string& command); + + Return sendTerminalResponseToSim(int32_t serial, + const ::android::hardware::hidl_string& commandResponse); + + Return handleStkCallSetupRequestFromSim(int32_t serial, bool accept); + + Return explicitCallTransfer(int32_t serial); + + Return setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType); + + Return getPreferredNetworkType(int32_t serial); + + Return getNeighboringCids(int32_t serial); + + Return setLocationUpdates(int32_t serial, bool enable); + + Return setCdmaSubscriptionSource(int32_t serial, + CdmaSubscriptionSource cdmaSub); + + Return setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type); + + Return getCdmaRoamingPreference(int32_t serial); + + Return setTTYMode(int32_t serial, TtyMode mode); + + Return getTTYMode(int32_t serial); + + Return setPreferredVoicePrivacy(int32_t serial, bool enable); + + Return getPreferredVoicePrivacy(int32_t serial); + + Return sendCDMAFeatureCode(int32_t serial, + const ::android::hardware::hidl_string& featureCode); + + Return sendBurstDtmf(int32_t serial, + const ::android::hardware::hidl_string& dtmf, + int32_t on, + int32_t off); + + Return sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms); + + Return acknowledgeLastIncomingCdmaSms(int32_t serial, + const CdmaSmsAck& smsAck); + + Return getGsmBroadcastConfig(int32_t serial); + + Return setGsmBroadcastConfig(int32_t serial, + const hidl_vec& configInfo); + + Return setGsmBroadcastActivation(int32_t serial, bool activate); + + Return getCdmaBroadcastConfig(int32_t serial); + + Return setCdmaBroadcastConfig(int32_t serial, + const hidl_vec& configInfo); + + Return setCdmaBroadcastActivation(int32_t serial, bool activate); + + Return getCDMASubscription(int32_t serial); + + Return writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms); + + Return deleteSmsOnRuim(int32_t serial, int32_t index); + + Return getDeviceIdentity(int32_t serial); + + Return exitEmergencyCallbackMode(int32_t serial); + + Return getSmscAddress(int32_t serial); + + Return setSmscAddress(int32_t serial, + const ::android::hardware::hidl_string& smsc); + + Return reportSmsMemoryStatus(int32_t serial, bool available); + + Return reportStkServiceIsRunning(int32_t serial); + + Return getCdmaSubscriptionSource(int32_t serial); + + Return requestIsimAuthentication(int32_t serial, + const ::android::hardware::hidl_string& challenge); + + Return acknowledgeIncomingGsmSmsWithPdu(int32_t serial, + bool success, + const ::android::hardware::hidl_string& ackPdu); + + Return sendEnvelopeWithStatus(int32_t serial, + const ::android::hardware::hidl_string& contents); + + Return getVoiceRadioTechnology(int32_t serial); + + Return getCellInfoList(int32_t serial); + + Return setCellInfoListRate(int32_t serial, int32_t rate); + + Return setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, + bool modemCognitive, bool isRoaming); + + Return getImsRegistrationState(int32_t serial); + + Return sendImsSms(int32_t serial, const ImsSmsMessage& message); + + Return iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message); + + Return iccOpenLogicalChannel(int32_t serial, + const ::android::hardware::hidl_string& aid, int32_t p2); + + Return iccCloseLogicalChannel(int32_t serial, int32_t channelId); + + Return iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message); + + Return nvReadItem(int32_t serial, NvItem itemId); + + Return nvWriteItem(int32_t serial, const NvWriteItem& item); + + Return nvWriteCdmaPrl(int32_t serial, + const ::android::hardware::hidl_vec& prl); + + Return nvResetConfig(int32_t serial, ResetNvType resetType); + + Return setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub); + + Return setDataAllowed(int32_t serial, bool allow); + + Return getHardwareConfig(int32_t serial); + + Return requestIccSimAuthentication(int32_t serial, + int32_t authContext, + const ::android::hardware::hidl_string& authData, + const ::android::hardware::hidl_string& aid); + + Return setDataProfile(int32_t serial, + const ::android::hardware::hidl_vec& profiles, bool isRoaming); + + Return requestShutdown(int32_t serial); + + Return getRadioCapability(int32_t serial); + + Return setRadioCapability(int32_t serial, const RadioCapability& rc); + + Return startLceService(int32_t serial, int32_t reportInterval, bool pullMode); + + Return stopLceService(int32_t serial); + + Return pullLceData(int32_t serial); + + Return getModemActivityInfo(int32_t serial); + + Return setAllowedCarriers(int32_t serial, + bool allAllowed, + const CarrierRestrictions& carriers); + + Return getAllowedCarriers(int32_t serial); + + Return sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state); + + Return setIndicationFilter(int32_t serial, int32_t indicationFilter); + + Return setSimCardPower(int32_t serial, bool powerUp); + + Return responseAcknowledgement(); + + void checkReturnStatus(Return& ret); +}; + +struct OemHookImpl : public IOemHook { + int32_t mSlotId; + sp mOemHookResponse; + sp mOemHookIndication; + + Return setResponseFunctions( + const ::android::sp& oemHookResponse, + const ::android::sp& oemHookIndication); + + Return sendRequestRaw(int32_t serial, + const ::android::hardware::hidl_vec& data); + + Return sendRequestStrings(int32_t serial, + const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data); +}; + +void memsetAndFreeStrings(int numPointers, ...) { + va_list ap; + va_start(ap, numPointers); + for (int i = 0; i < numPointers; i++) { + char *ptr = va_arg(ap, char *); + if (ptr) { +#ifdef MEMSET_FREED + // TODO: Should pass in the maximum length of the string + memsetString(ptr); +#endif + free(ptr); + } + } + va_end(ap); +} + +void sendErrorResponse(RequestInfo *pRI, RIL_Errno err) { + pRI->pCI->responseFunction((int) pRI->socket_id, + (int) RadioResponseType::SOLICITED, pRI->token, err, NULL, 0); +} + +/** + * Copies over src to dest. If memory allocation fails, responseFunction() is called for the + * request with error RIL_E_NO_MEMORY. + * Returns true on success, and false on failure. + */ +bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) { + size_t len = src.size(); + if (len == 0) { + *dest = NULL; + return true; + } + *dest = (char *) calloc(len + 1, sizeof(char)); + if (*dest == NULL) { + RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return false; + } + strncpy(*dest, src.c_str(), len + 1); + return true; +} + +hidl_string convertCharPtrToHidlString(const char *ptr) { + hidl_string ret; + if (ptr != NULL) { + // TODO: replace this with strnlen + ret.setToExternal(ptr, strlen(ptr)); + } + return ret; +} + +bool dispatchVoid(int serial, int slotId, int request) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + CALL_ONREQUEST(request, NULL, 0, pRI, slotId); + return true; +} + +bool dispatchString(int serial, int slotId, int request, const char * str) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + char *pString; + if (!copyHidlStringToRil(&pString, str, pRI)) { + return false; + } + + CALL_ONREQUEST(request, pString, sizeof(char *), pRI, slotId); + + memsetAndFreeStrings(1, pString); + return true; +} + +bool dispatchStrings(int serial, int slotId, int request, int countStrings, ...) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + char **pStrings; + pStrings = (char **)calloc(countStrings, sizeof(char *)); + if (pStrings == NULL) { + RLOGE("Memory allocation failed for request %s", requestToString(request)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return false; + } + va_list ap; + va_start(ap, countStrings); + for (int i = 0; i < countStrings; i++) { + const char* str = va_arg(ap, const char *); + if (!copyHidlStringToRil(&pStrings[i], hidl_string(str), pRI)) { + va_end(ap); + for (int j = 0; j < i; j++) { + memsetAndFreeStrings(1, pStrings[j]); + } + free(pStrings); + return false; + } + } + va_end(ap); + + CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId); + + if (pStrings != NULL) { + for (int i = 0 ; i < countStrings ; i++) { + memsetAndFreeStrings(1, pStrings[i]); + } + +#ifdef MEMSET_FREED + memset(pStrings, 0, countStrings * sizeof(char *)); +#endif + free(pStrings); + } + return true; +} + +bool dispatchStrings(int serial, int slotId, int request, const hidl_vec& data) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + int countStrings = data.size(); + char **pStrings; + pStrings = (char **)calloc(countStrings, sizeof(char *)); + if (pStrings == NULL) { + RLOGE("Memory allocation failed for request %s", requestToString(request)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return false; + } + + for (int i = 0; i < countStrings; i++) { + if (!copyHidlStringToRil(&pStrings[i], data[i], pRI)) { + for (int j = 0; j < i; j++) { + memsetAndFreeStrings(1, pStrings[j]); + } + free(pStrings); + return false; + } + } + + CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId); + + if (pStrings != NULL) { + for (int i = 0 ; i < countStrings ; i++) { + memsetAndFreeStrings(1, pStrings[i]); + } + +#ifdef MEMSET_FREED + memset(pStrings, 0, countStrings * sizeof(char *)); +#endif + free(pStrings); + } + return true; +} + +bool dispatchInts(int serial, int slotId, int request, int countInts, ...) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + int *pInts = (int *)calloc(countInts, sizeof(int)); + + if (pInts == NULL) { + RLOGE("Memory allocation failed for request %s", requestToString(request)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return false; + } + va_list ap; + va_start(ap, countInts); + for (int i = 0; i < countInts; i++) { + pInts[i] = va_arg(ap, int); + } + va_end(ap); + + CALL_ONREQUEST(request, pInts, countInts * sizeof(int), pRI, slotId); + + if (pInts != NULL) { +#ifdef MEMSET_FREED + memset(pInts, 0, countInts * sizeof(int)); +#endif + free(pInts); + } + return true; +} + +bool dispatchCallForwardStatus(int serial, int slotId, int request, + const CallForwardInfo& callInfo) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + RIL_CallForwardInfo cf; + cf.status = (int) callInfo.status; + cf.reason = callInfo.reason; + cf.serviceClass = callInfo.serviceClass; + cf.toa = callInfo.toa; + cf.timeSeconds = callInfo.timeSeconds; + + if (!copyHidlStringToRil(&cf.number, callInfo.number, pRI)) { + return false; + } + + CALL_ONREQUEST(request, &cf, sizeof(cf), pRI, slotId); + + memsetAndFreeStrings(1, cf.number); + + return true; +} + +bool dispatchRaw(int serial, int slotId, int request, const hidl_vec& rawBytes) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + const uint8_t *uData = rawBytes.data(); + + CALL_ONREQUEST(request, (void *) uData, rawBytes.size(), pRI, slotId); + + return true; +} + +bool dispatchIccApdu(int serial, int slotId, int request, const SimApdu& message) { + RequestInfo *pRI = android::addRequestToList(serial, slotId, request); + if (pRI == NULL) { + return false; + } + + RIL_SIM_APDU apdu = {}; + + apdu.sessionid = message.sessionId; + apdu.cla = message.cla; + apdu.instruction = message.instruction; + apdu.p1 = message.p1; + apdu.p2 = message.p2; + apdu.p3 = message.p3; + + if (!copyHidlStringToRil(&apdu.data, message.data, pRI)) { + return false; + } + + CALL_ONREQUEST(request, &apdu, sizeof(apdu), pRI, slotId); + + memsetAndFreeStrings(1, apdu.data); + + return true; +} + +void checkReturnStatus(int32_t slotId, Return& ret, bool isRadioService) { + if (ret.isOk() == false) { + RLOGE("checkReturnStatus: unable to call response/indication callback"); + // Remote process hosting the callbacks must be dead. Reset the callback objects; + // there's no other recovery to be done here. When the client process is back up, it will + // call setResponseFunctions() + + // Caller should already hold rdlock, release that first + // note the current counter to avoid overwriting updates made by another thread before + // write lock is acquired. + int counter = isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId]; + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(slotId); + int ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + + // acquire wrlock + ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); + assert(ret == 0); + + // make sure the counter value has not changed + if (counter == (isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId])) { + if (isRadioService) { + radioService[slotId]->mRadioResponse = NULL; + radioService[slotId]->mRadioIndication = NULL; + } else { + oemHookService[slotId]->mOemHookResponse = NULL; + oemHookService[slotId]->mOemHookIndication = NULL; + } + isRadioService ? mCounterRadio[slotId]++ : mCounterOemHook[slotId]++; + } else { + RLOGE("checkReturnStatus: not resetting responseFunctions as they likely " + "got updated on another thread"); + } + + // release wrlock + ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + + // Reacquire rdlock + ret = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(ret == 0); + } +} + +void RadioImpl::checkReturnStatus(Return& ret) { + ::checkReturnStatus(mSlotId, ret, true); +} + +Return RadioImpl::setResponseFunctions( + const ::android::sp& radioResponseParam, + const ::android::sp& radioIndicationParam) { + RLOGD("setResponseFunctions"); + + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(mSlotId); + int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); + assert(ret == 0); + + mRadioResponse = radioResponseParam; + mRadioIndication = radioIndicationParam; + mCounterRadio[mSlotId]++; + + ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + + // client is connected. Send initial indications. + android::onNewCommandConnect((RIL_SOCKET_ID) mSlotId); + + return Void(); +} + +Return RadioImpl::getIccCardStatus(int32_t serial) { +#if VDBG + RLOGD("getIccCardStatus: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_STATUS); + return Void(); +} + +Return RadioImpl::supplyIccPinForApp(int32_t serial, const hidl_string& pin, + const hidl_string& aid) { +#if VDBG + RLOGD("supplyIccPinForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN, + 2, pin.c_str(), aid.c_str()); + return Void(); +} + +Return RadioImpl::supplyIccPukForApp(int32_t serial, const hidl_string& puk, + const hidl_string& pin, const hidl_string& aid) { +#if VDBG + RLOGD("supplyIccPukForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK, + 3, puk.c_str(), pin.c_str(), aid.c_str()); + return Void(); +} + +Return RadioImpl::supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2, + const hidl_string& aid) { +#if VDBG + RLOGD("supplyIccPin2ForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2, + 2, pin2.c_str(), aid.c_str()); + return Void(); +} + +Return RadioImpl::supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, + const hidl_string& pin2, const hidl_string& aid) { +#if VDBG + RLOGD("supplyIccPuk2ForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2, + 3, puk2.c_str(), pin2.c_str(), aid.c_str()); + return Void(); +} + +Return RadioImpl::changeIccPinForApp(int32_t serial, const hidl_string& oldPin, + const hidl_string& newPin, const hidl_string& aid) { +#if VDBG + RLOGD("changeIccPinForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN, + 3, oldPin.c_str(), newPin.c_str(), aid.c_str()); + return Void(); +} + +Return RadioImpl::changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, + const hidl_string& newPin2, const hidl_string& aid) { +#if VDBG + RLOGD("changeIccPin2ForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2, + 3, oldPin2.c_str(), newPin2.c_str(), aid.c_str()); + return Void(); +} + +Return RadioImpl::supplyNetworkDepersonalization(int32_t serial, + const hidl_string& netPin) { +#if VDBG + RLOGD("supplyNetworkDepersonalization: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, + 1, netPin.c_str()); + return Void(); +} + +Return RadioImpl::getCurrentCalls(int32_t serial) { +#if VDBG + RLOGD("getCurrentCalls: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CURRENT_CALLS); + return Void(); +} + +Return RadioImpl::dial(int32_t serial, const Dial& dialInfo) { +#if VDBG + RLOGD("dial: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_DIAL); + if (pRI == NULL) { + return Void(); + } + RIL_Dial dial = {}; + RIL_UUS_Info uusInfo = {}; + int32_t sizeOfDial = sizeof(dial); + + if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) { + return Void(); + } + dial.clir = (int) dialInfo.clir; + + if (dialInfo.uusInfo.size() != 0) { + uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType; + uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs; + + if (dialInfo.uusInfo[0].uusData.size() == 0) { + uusInfo.uusData = NULL; + uusInfo.uusLength = 0; + } else { + if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) { + memsetAndFreeStrings(1, dial.address); + return Void(); + } + uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size(); + } + + dial.uusInfo = &uusInfo; + } + + CALL_ONREQUEST(RIL_REQUEST_DIAL, &dial, sizeOfDial, pRI, mSlotId); + + memsetAndFreeStrings(2, dial.address, uusInfo.uusData); + + return Void(); +} + +Return RadioImpl::getImsiForApp(int32_t serial, const hidl_string& aid) { +#if VDBG + RLOGD("getImsiForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI, + 1, aid.c_str()); + return Void(); +} + +Return RadioImpl::hangup(int32_t serial, int32_t gsmIndex) { +#if VDBG + RLOGD("hangup: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_HANGUP, 1, gsmIndex); + return Void(); +} + +Return RadioImpl::hangupWaitingOrBackground(int32_t serial) { +#if VDBG + RLOGD("hangupWaitingOrBackground: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND); + return Void(); +} + +Return RadioImpl::hangupForegroundResumeBackground(int32_t serial) { +#if VDBG + RLOGD("hangupForegroundResumeBackground: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND); + return Void(); +} + +Return RadioImpl::switchWaitingOrHoldingAndActive(int32_t serial) { +#if VDBG + RLOGD("switchWaitingOrHoldingAndActive: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE); + return Void(); +} + +Return RadioImpl::conference(int32_t serial) { +#if VDBG + RLOGD("conference: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFERENCE); + return Void(); +} + +Return RadioImpl::rejectCall(int32_t serial) { +#if VDBG + RLOGD("rejectCall: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_UDUB); + return Void(); +} + +Return RadioImpl::getLastCallFailCause(int32_t serial) { +#if VDBG + RLOGD("getLastCallFailCause: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_LAST_CALL_FAIL_CAUSE); + return Void(); +} + +Return RadioImpl::getSignalStrength(int32_t serial) { +#if VDBG + RLOGD("getSignalStrength: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH); + return Void(); +} + +Return RadioImpl::getVoiceRegistrationState(int32_t serial) { +#if VDBG + RLOGD("getVoiceRegistrationState: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE); + return Void(); +} + +Return RadioImpl::getDataRegistrationState(int32_t serial) { +#if VDBG + RLOGD("getDataRegistrationState: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE); + return Void(); +} + +Return RadioImpl::getOperator(int32_t serial) { +#if VDBG + RLOGD("getOperator: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_OPERATOR); + return Void(); +} + +Return RadioImpl::setRadioPower(int32_t serial, bool on) { + RLOGD("setRadioPower: serial %d on %d", serial, on); + dispatchInts(serial, mSlotId, RIL_REQUEST_RADIO_POWER, 1, BOOL_TO_INT(on)); + return Void(); +} + +Return RadioImpl::sendDtmf(int32_t serial, const hidl_string& s) { +#if VDBG + RLOGD("sendDtmf: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_DTMF, s.c_str()); + return Void(); +} + +Return RadioImpl::sendSms(int32_t serial, const GsmSmsMessage& message) { +#if VDBG + RLOGD("sendSms: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS, + 2, message.smscPdu.c_str(), message.pdu.c_str()); + return Void(); +} + +Return RadioImpl::sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message) { +#if VDBG + RLOGD("sendSMSExpectMore: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE, + 2, message.smscPdu.c_str(), message.pdu.c_str()); + return Void(); +} + +static bool convertMvnoTypeToString(MvnoType type, char *&str) { + switch (type) { + case MvnoType::IMSI: + str = (char *)"imsi"; + return true; + case MvnoType::GID: + str = (char *)"gid"; + return true; + case MvnoType::SPN: + str = (char *)"spn"; + return true; + case MvnoType::NONE: + str = (char *)""; + return true; + } + return false; +} + +Return RadioImpl::setupDataCall(int32_t serial, RadioTechnology radioTechnology, + const DataProfileInfo& dataProfileInfo, bool modemCognitive, + bool roamingAllowed, bool isRoaming) { + +#if VDBG + RLOGD("setupDataCall: serial %d", serial); +#endif + + if (s_vendorFunctions->version >= 4 && s_vendorFunctions->version <= 14) { + const hidl_string &protocol = + (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol); + dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, 7, + std::to_string((int) radioTechnology + 2).c_str(), + std::to_string((int) dataProfileInfo.profileId).c_str(), + dataProfileInfo.apn.c_str(), + dataProfileInfo.user.c_str(), + dataProfileInfo.password.c_str(), + std::to_string((int) dataProfileInfo.authType).c_str(), + protocol.c_str()); + } else if (s_vendorFunctions->version >= 15) { + char *mvnoTypeStr = NULL; + if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, mvnoTypeStr)) { + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SETUP_DATA_CALL); + if (pRI != NULL) { + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + } + return Void(); + } + dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, 15, + std::to_string((int) radioTechnology + 2).c_str(), + std::to_string((int) dataProfileInfo.profileId).c_str(), + dataProfileInfo.apn.c_str(), + dataProfileInfo.user.c_str(), + dataProfileInfo.password.c_str(), + std::to_string((int) dataProfileInfo.authType).c_str(), + dataProfileInfo.protocol.c_str(), + dataProfileInfo.roamingProtocol.c_str(), + std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(), + std::to_string(dataProfileInfo.bearerBitmap).c_str(), + modemCognitive ? "1" : "0", + std::to_string(dataProfileInfo.mtu).c_str(), + mvnoTypeStr, + dataProfileInfo.mvnoMatchData.c_str(), + roamingAllowed ? "1" : "0"); + } else { + RLOGE("Unsupported RIL version %d, min version expected 4", s_vendorFunctions->version); + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SETUP_DATA_CALL); + if (pRI != NULL) { + sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); + } + } + return Void(); +} + +Return RadioImpl::iccIOForApp(int32_t serial, const IccIo& iccIo) { +#if VDBG + RLOGD("iccIOForApp: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_IO); + if (pRI == NULL) { + return Void(); + } + + RIL_SIM_IO_v6 rilIccIo = {}; + rilIccIo.command = iccIo.command; + rilIccIo.fileid = iccIo.fileId; + if (!copyHidlStringToRil(&rilIccIo.path, iccIo.path, pRI)) { + return Void(); + } + + rilIccIo.p1 = iccIo.p1; + rilIccIo.p2 = iccIo.p2; + rilIccIo.p3 = iccIo.p3; + + if (!copyHidlStringToRil(&rilIccIo.data, iccIo.data, pRI)) { + memsetAndFreeStrings(1, rilIccIo.path); + return Void(); + } + + if (!copyHidlStringToRil(&rilIccIo.pin2, iccIo.pin2, pRI)) { + memsetAndFreeStrings(2, rilIccIo.path, rilIccIo.data); + return Void(); + } + + if (!copyHidlStringToRil(&rilIccIo.aidPtr, iccIo.aid, pRI)) { + memsetAndFreeStrings(3, rilIccIo.path, rilIccIo.data, rilIccIo.pin2); + return Void(); + } + + CALL_ONREQUEST(RIL_REQUEST_SIM_IO, &rilIccIo, sizeof(rilIccIo), pRI, mSlotId); + + memsetAndFreeStrings(4, rilIccIo.path, rilIccIo.data, rilIccIo.pin2, rilIccIo.aidPtr); + + return Void(); +} + +Return RadioImpl::sendUssd(int32_t serial, const hidl_string& ussd) { +#if VDBG + RLOGD("sendUssd: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_SEND_USSD, ussd.c_str()); + return Void(); +} + +Return RadioImpl::cancelPendingUssd(int32_t serial) { +#if VDBG + RLOGD("cancelPendingUssd: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CANCEL_USSD); + return Void(); +} + +Return RadioImpl::getClir(int32_t serial) { +#if VDBG + RLOGD("getClir: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CLIR); + return Void(); +} + +Return RadioImpl::setClir(int32_t serial, int32_t status) { +#if VDBG + RLOGD("setClir: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CLIR, 1, status); + return Void(); +} + +Return RadioImpl::getCallForwardStatus(int32_t serial, const CallForwardInfo& callInfo) { +#if VDBG + RLOGD("getCallForwardStatus: serial %d", serial); +#endif + dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, + callInfo); + return Void(); +} + +Return RadioImpl::setCallForward(int32_t serial, const CallForwardInfo& callInfo) { +#if VDBG + RLOGD("setCallForward: serial %d", serial); +#endif + dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_SET_CALL_FORWARD, + callInfo); + return Void(); +} + +Return RadioImpl::getCallWaiting(int32_t serial, int32_t serviceClass) { +#if VDBG + RLOGD("getCallWaiting: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_QUERY_CALL_WAITING, 1, serviceClass); + return Void(); +} + +Return RadioImpl::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) { +#if VDBG + RLOGD("setCallWaiting: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CALL_WAITING, 2, BOOL_TO_INT(enable), + serviceClass); + return Void(); +} + +Return RadioImpl::acknowledgeLastIncomingGsmSms(int32_t serial, + bool success, SmsAcknowledgeFailCause cause) { +#if VDBG + RLOGD("acknowledgeLastIncomingGsmSms: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SMS_ACKNOWLEDGE, 2, BOOL_TO_INT(success), + cause); + return Void(); +} + +Return RadioImpl::acceptCall(int32_t serial) { +#if VDBG + RLOGD("acceptCall: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_ANSWER); + return Void(); +} + +Return RadioImpl::deactivateDataCall(int32_t serial, + int32_t cid, bool reasonRadioShutDown) { +#if VDBG + RLOGD("deactivateDataCall: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL, + 2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0"); + return Void(); +} + +Return RadioImpl::getFacilityLockForApp(int32_t serial, const hidl_string& facility, + const hidl_string& password, int32_t serviceClass, + const hidl_string& appId) { +#if VDBG + RLOGD("getFacilityLockForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_QUERY_FACILITY_LOCK, + 4, facility.c_str(), password.c_str(), + (std::to_string(serviceClass)).c_str(), appId.c_str()); + return Void(); +} + +Return RadioImpl::setFacilityLockForApp(int32_t serial, const hidl_string& facility, + bool lockState, const hidl_string& password, + int32_t serviceClass, const hidl_string& appId) { +#if VDBG + RLOGD("setFacilityLockForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_SET_FACILITY_LOCK, + 5, facility.c_str(), lockState ? "1" : "0", password.c_str(), + (std::to_string(serviceClass)).c_str(), appId.c_str() ); + return Void(); +} + +Return RadioImpl::setBarringPassword(int32_t serial, const hidl_string& facility, + const hidl_string& oldPassword, + const hidl_string& newPassword) { +#if VDBG + RLOGD("setBarringPassword: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD, + 3, facility.c_str(), oldPassword.c_str(), newPassword.c_str()); + return Void(); +} + +Return RadioImpl::getNetworkSelectionMode(int32_t serial) { +#if VDBG + RLOGD("getNetworkSelectionMode: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE); + return Void(); +} + +Return RadioImpl::setNetworkSelectionModeAutomatic(int32_t serial) { +#if VDBG + RLOGD("setNetworkSelectionModeAutomatic: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC); + return Void(); +} + +Return RadioImpl::setNetworkSelectionModeManual(int32_t serial, + const hidl_string& operatorNumeric) { +#if VDBG + RLOGD("setNetworkSelectionModeManual: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, + operatorNumeric.c_str()); + return Void(); +} + +Return RadioImpl::getAvailableNetworks(int32_t serial) { +#if VDBG + RLOGD("getAvailableNetworks: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS); + return Void(); +} + +Return RadioImpl::startDtmf(int32_t serial, const hidl_string& s) { +#if VDBG + RLOGD("startDtmf: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_DTMF_START, + s.c_str()); + return Void(); +} + +Return RadioImpl::stopDtmf(int32_t serial) { +#if VDBG + RLOGD("stopDtmf: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DTMF_STOP); + return Void(); +} + +Return RadioImpl::getBasebandVersion(int32_t serial) { +#if VDBG + RLOGD("getBasebandVersion: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_BASEBAND_VERSION); + return Void(); +} + +Return RadioImpl::separateConnection(int32_t serial, int32_t gsmIndex) { +#if VDBG + RLOGD("separateConnection: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SEPARATE_CONNECTION, 1, gsmIndex); + return Void(); +} + +Return RadioImpl::setMute(int32_t serial, bool enable) { +#if VDBG + RLOGD("setMute: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_MUTE, 1, BOOL_TO_INT(enable)); + return Void(); +} + +Return RadioImpl::getMute(int32_t serial) { +#if VDBG + RLOGD("getMute: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MUTE); + return Void(); +} + +Return RadioImpl::getClip(int32_t serial) { +#if VDBG + RLOGD("getClip: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_CLIP); + return Void(); +} + +Return RadioImpl::getDataCallList(int32_t serial) { +#if VDBG + RLOGD("getDataCallList: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_CALL_LIST); + return Void(); +} + +Return RadioImpl::setSuppServiceNotifications(int32_t serial, bool enable) { +#if VDBG + RLOGD("setSuppServiceNotifications: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, 1, + BOOL_TO_INT(enable)); + return Void(); +} + +Return RadioImpl::writeSmsToSim(int32_t serial, const SmsWriteArgs& smsWriteArgs) { +#if VDBG + RLOGD("writeSmsToSim: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_WRITE_SMS_TO_SIM); + if (pRI == NULL) { + return Void(); + } + + RIL_SMS_WriteArgs args; + args.status = (int) smsWriteArgs.status; + + int len; + if (!copyHidlStringToRil(&args.pdu, smsWriteArgs.pdu, pRI)) { + return Void(); + } + + if (!copyHidlStringToRil(&args.smsc, smsWriteArgs.smsc, pRI)) { + memsetAndFreeStrings(1, args.pdu); + return Void(); + } + + CALL_ONREQUEST(RIL_REQUEST_WRITE_SMS_TO_SIM, &args, sizeof(args), pRI, mSlotId); + + memsetAndFreeStrings(2, args.smsc, args.pdu); + + return Void(); +} + +Return RadioImpl::deleteSmsOnSim(int32_t serial, int32_t index) { +#if VDBG + RLOGD("deleteSmsOnSim: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_DELETE_SMS_ON_SIM, 1, index); + return Void(); +} + +Return RadioImpl::setBandMode(int32_t serial, RadioBandMode mode) { +#if VDBG + RLOGD("setBandMode: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_BAND_MODE, 1, mode); + return Void(); +} + +Return RadioImpl::getAvailableBandModes(int32_t serial) { +#if VDBG + RLOGD("getAvailableBandModes: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE); + return Void(); +} + +Return RadioImpl::sendEnvelope(int32_t serial, const hidl_string& command) { +#if VDBG + RLOGD("sendEnvelope: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, + command.c_str()); + return Void(); +} + +Return RadioImpl::sendTerminalResponseToSim(int32_t serial, + const hidl_string& commandResponse) { +#if VDBG + RLOGD("sendTerminalResponseToSim: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, + commandResponse.c_str()); + return Void(); +} + +Return RadioImpl::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) { +#if VDBG + RLOGD("handleStkCallSetupRequestFromSim: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, + 1, BOOL_TO_INT(accept)); + return Void(); +} + +Return RadioImpl::explicitCallTransfer(int32_t serial) { +#if VDBG + RLOGD("explicitCallTransfer: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_EXPLICIT_CALL_TRANSFER); + return Void(); +} + +Return RadioImpl::setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType) { +#if VDBG + RLOGD("setPreferredNetworkType: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, 1, nwType); + return Void(); +} + +Return RadioImpl::getPreferredNetworkType(int32_t serial) { +#if VDBG + RLOGD("getPreferredNetworkType: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE); + return Void(); +} + +Return RadioImpl::getNeighboringCids(int32_t serial) { +#if VDBG + RLOGD("getNeighboringCids: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_NEIGHBORING_CELL_IDS); + return Void(); +} + +Return RadioImpl::setLocationUpdates(int32_t serial, bool enable) { +#if VDBG + RLOGD("setLocationUpdates: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_LOCATION_UPDATES, 1, BOOL_TO_INT(enable)); + return Void(); +} + +Return RadioImpl::setCdmaSubscriptionSource(int32_t serial, CdmaSubscriptionSource cdmaSub) { +#if VDBG + RLOGD("setCdmaSubscriptionSource: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, 1, cdmaSub); + return Void(); +} + +Return RadioImpl::setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type) { +#if VDBG + RLOGD("setCdmaRoamingPreference: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, 1, type); + return Void(); +} + +Return RadioImpl::getCdmaRoamingPreference(int32_t serial) { +#if VDBG + RLOGD("getCdmaRoamingPreference: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE); + return Void(); +} + +Return RadioImpl::setTTYMode(int32_t serial, TtyMode mode) { +#if VDBG + RLOGD("setTTYMode: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_TTY_MODE, 1, mode); + return Void(); +} + +Return RadioImpl::getTTYMode(int32_t serial) { +#if VDBG + RLOGD("getTTYMode: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_TTY_MODE); + return Void(); +} + +Return RadioImpl::setPreferredVoicePrivacy(int32_t serial, bool enable) { +#if VDBG + RLOGD("setPreferredVoicePrivacy: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, + 1, BOOL_TO_INT(enable)); + return Void(); +} + +Return RadioImpl::getPreferredVoicePrivacy(int32_t serial) { +#if VDBG + RLOGD("getPreferredVoicePrivacy: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE); + return Void(); +} + +Return RadioImpl::sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) { +#if VDBG + RLOGD("sendCDMAFeatureCode: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_CDMA_FLASH, + featureCode.c_str()); + return Void(); +} + +Return RadioImpl::sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on, + int32_t off) { +#if VDBG + RLOGD("sendBurstDtmf: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_CDMA_BURST_DTMF, + 3, dtmf.c_str(), (std::to_string(on)).c_str(), + (std::to_string(off)).c_str()); + return Void(); +} + +void constructCdmaSms(RIL_CDMA_SMS_Message &rcsm, const CdmaSmsMessage& sms) { + rcsm.uTeleserviceID = sms.teleserviceId; + rcsm.bIsServicePresent = BOOL_TO_INT(sms.isServicePresent); + rcsm.uServicecategory = sms.serviceCategory; + rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) sms.address.digitMode; + rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) sms.address.numberMode; + rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) sms.address.numberType; + rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) sms.address.numberPlan; + + rcsm.sAddress.number_of_digits = sms.address.digits.size(); + int digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); + for (int i = 0; i < digitLimit; i++) { + rcsm.sAddress.digits[i] = sms.address.digits[i]; + } + + rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) sms.subAddress.subaddressType; + rcsm.sSubAddress.odd = BOOL_TO_INT(sms.subAddress.odd); + + rcsm.sSubAddress.number_of_digits = sms.subAddress.digits.size(); + digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); + for (int i = 0; i < digitLimit; i++) { + rcsm.sSubAddress.digits[i] = sms.subAddress.digits[i]; + } + + rcsm.uBearerDataLen = sms.bearerData.size(); + digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); + for (int i = 0; i < digitLimit; i++) { + rcsm.aBearerData[i] = sms.bearerData[i]; + } +} + +Return RadioImpl::sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms) { +#if VDBG + RLOGD("sendCdmaSms: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SEND_SMS); + if (pRI == NULL) { + return Void(); + } + + RIL_CDMA_SMS_Message rcsm = {}; + constructCdmaSms(rcsm, sms); + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::acknowledgeLastIncomingCdmaSms(int32_t serial, const CdmaSmsAck& smsAck) { +#if VDBG + RLOGD("acknowledgeLastIncomingCdmaSms: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE); + if (pRI == NULL) { + return Void(); + } + + RIL_CDMA_SMS_Ack rcsa = {}; + + rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) smsAck.errorClass; + rcsa.uSMSCauseCode = smsAck.smsCauseCode; + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::getGsmBroadcastConfig(int32_t serial) { +#if VDBG + RLOGD("getGsmBroadcastConfig: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG); + return Void(); +} + +Return RadioImpl::setGsmBroadcastConfig(int32_t serial, + const hidl_vec& + configInfo) { +#if VDBG + RLOGD("setGsmBroadcastConfig: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG); + if (pRI == NULL) { + return Void(); + } + + int num = configInfo.size(); + RIL_GSM_BroadcastSmsConfigInfo gsmBci[num]; + RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num]; + + for (int i = 0 ; i < num ; i++ ) { + gsmBciPtrs[i] = &gsmBci[i]; + gsmBci[i].fromServiceId = configInfo[i].fromServiceId; + gsmBci[i].toServiceId = configInfo[i].toServiceId; + gsmBci[i].fromCodeScheme = configInfo[i].fromCodeScheme; + gsmBci[i].toCodeScheme = configInfo[i].toCodeScheme; + gsmBci[i].selected = BOOL_TO_INT(configInfo[i].selected); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, gsmBciPtrs, + num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::setGsmBroadcastActivation(int32_t serial, bool activate) { +#if VDBG + RLOGD("setGsmBroadcastActivation: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, + 1, BOOL_TO_INT(!activate)); + return Void(); +} + +Return RadioImpl::getCdmaBroadcastConfig(int32_t serial) { +#if VDBG + RLOGD("getCdmaBroadcastConfig: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG); + return Void(); +} + +Return RadioImpl::setCdmaBroadcastConfig(int32_t serial, + const hidl_vec& + configInfo) { +#if VDBG + RLOGD("setCdmaBroadcastConfig: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG); + if (pRI == NULL) { + return Void(); + } + + int num = configInfo.size(); + RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num]; + RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num]; + + for (int i = 0 ; i < num ; i++ ) { + cdmaBciPtrs[i] = &cdmaBci[i]; + cdmaBci[i].service_category = configInfo[i].serviceCategory; + cdmaBci[i].language = configInfo[i].language; + cdmaBci[i].selected = BOOL_TO_INT(configInfo[i].selected); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, cdmaBciPtrs, + num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::setCdmaBroadcastActivation(int32_t serial, bool activate) { +#if VDBG + RLOGD("setCdmaBroadcastActivation: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, + 1, BOOL_TO_INT(!activate)); + return Void(); +} + +Return RadioImpl::getCDMASubscription(int32_t serial) { +#if VDBG + RLOGD("getCDMASubscription: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_SUBSCRIPTION); + return Void(); +} + +Return RadioImpl::writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms) { +#if VDBG + RLOGD("writeSmsToRuim: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM); + if (pRI == NULL) { + return Void(); + } + + RIL_CDMA_SMS_WriteArgs rcsw = {}; + rcsw.status = (int) cdmaSms.status; + constructCdmaSms(rcsw.message, cdmaSms.message); + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::deleteSmsOnRuim(int32_t serial, int32_t index) { +#if VDBG + RLOGD("deleteSmsOnRuim: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, 1, index); + return Void(); +} + +Return RadioImpl::getDeviceIdentity(int32_t serial) { +#if VDBG + RLOGD("getDeviceIdentity: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY); + return Void(); +} + +Return RadioImpl::exitEmergencyCallbackMode(int32_t serial) { +#if VDBG + RLOGD("exitEmergencyCallbackMode: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE); + return Void(); +} + +Return RadioImpl::getSmscAddress(int32_t serial) { +#if VDBG + RLOGD("getSmscAddress: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SMSC_ADDRESS); + return Void(); +} + +Return RadioImpl::setSmscAddress(int32_t serial, const hidl_string& smsc) { +#if VDBG + RLOGD("setSmscAddress: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_SET_SMSC_ADDRESS, + smsc.c_str()); + return Void(); +} + +Return RadioImpl::reportSmsMemoryStatus(int32_t serial, bool available) { +#if VDBG + RLOGD("reportSmsMemoryStatus: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, 1, + BOOL_TO_INT(available)); + return Void(); +} + +Return RadioImpl::reportStkServiceIsRunning(int32_t serial) { +#if VDBG + RLOGD("reportStkServiceIsRunning: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING); + return Void(); +} + +Return RadioImpl::getCdmaSubscriptionSource(int32_t serial) { +#if VDBG + RLOGD("getCdmaSubscriptionSource: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE); + return Void(); +} + +Return RadioImpl::requestIsimAuthentication(int32_t serial, const hidl_string& challenge) { +#if VDBG + RLOGD("requestIsimAuthentication: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_ISIM_AUTHENTICATION, + challenge.c_str()); + return Void(); +} + +Return RadioImpl::acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success, + const hidl_string& ackPdu) { +#if VDBG + RLOGD("acknowledgeIncomingGsmSmsWithPdu: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, + 2, success ? "1" : "0", ackPdu.c_str()); + return Void(); +} + +Return RadioImpl::sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) { +#if VDBG + RLOGD("sendEnvelopeWithStatus: serial %d", serial); +#endif + dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, + contents.c_str()); + return Void(); +} + +Return RadioImpl::getVoiceRadioTechnology(int32_t serial) { +#if VDBG + RLOGD("getVoiceRadioTechnology: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_RADIO_TECH); + return Void(); +} + +Return RadioImpl::getCellInfoList(int32_t serial) { +#if VDBG + RLOGD("getCellInfoList: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CELL_INFO_LIST); + return Void(); +} + +Return RadioImpl::setCellInfoListRate(int32_t serial, int32_t rate) { +#if VDBG + RLOGD("setCellInfoListRate: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, 1, rate); + return Void(); +} + +Return RadioImpl::setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, + bool modemCognitive, bool isRoaming) { +#if VDBG + RLOGD("setInitialAttachApn: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SET_INITIAL_ATTACH_APN); + if (pRI == NULL) { + return Void(); + } + + if (s_vendorFunctions->version <= 14) { + RIL_InitialAttachApn iaa = {}; + + if (dataProfileInfo.apn.size() == 0) { + iaa.apn = (char *) calloc(1, sizeof(char)); + if (iaa.apn == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + iaa.apn[0] = '\0'; + } else { + if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) { + return Void(); + } + } + + const hidl_string &protocol = + (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol); + + if (!copyHidlStringToRil(&iaa.protocol, protocol, pRI)) { + memsetAndFreeStrings(1, iaa.apn); + return Void(); + } + iaa.authtype = (int) dataProfileInfo.authType; + if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) { + memsetAndFreeStrings(2, iaa.apn, iaa.protocol); + return Void(); + } + if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) { + memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.username); + return Void(); + } + + CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId); + + memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.username, iaa.password); + } else { + RIL_InitialAttachApn_v15 iaa = {}; + + if (dataProfileInfo.apn.size() == 0) { + iaa.apn = (char *) calloc(1, sizeof(char)); + if (iaa.apn == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + iaa.apn[0] = '\0'; + } else { + if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) { + return Void(); + } + } + + if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) { + memsetAndFreeStrings(1, iaa.apn); + return Void(); + } + if (!copyHidlStringToRil(&iaa.roamingProtocol, dataProfileInfo.roamingProtocol, pRI)) { + memsetAndFreeStrings(2, iaa.apn, iaa.protocol); + return Void(); + } + iaa.authtype = (int) dataProfileInfo.authType; + if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) { + memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.roamingProtocol); + return Void(); + } + if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) { + memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username); + return Void(); + } + iaa.supportedTypesBitmask = dataProfileInfo.supportedApnTypesBitmap; + iaa.bearerBitmask = dataProfileInfo.bearerBitmap; + iaa.modemCognitive = BOOL_TO_INT(modemCognitive); + iaa.mtu = dataProfileInfo.mtu; + + if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, iaa.mvnoType)) { + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, + iaa.password); + return Void(); + } + + if (!copyHidlStringToRil(&iaa.mvnoMatchData, dataProfileInfo.mvnoMatchData, pRI)) { + memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, + iaa.password); + return Void(); + } + + CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId); + + memsetAndFreeStrings(6, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, + iaa.password, iaa.mvnoMatchData); + } + + return Void(); +} + +Return RadioImpl::getImsRegistrationState(int32_t serial) { +#if VDBG + RLOGD("getImsRegistrationState: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_IMS_REGISTRATION_STATE); + return Void(); +} + +bool dispatchImsGsmSms(const ImsSmsMessage& message, RequestInfo *pRI) { + RIL_IMS_SMS_Message rism = {}; + char **pStrings; + int countStrings = 2; + int dataLen = sizeof(char *) * countStrings; + + rism.tech = RADIO_TECH_3GPP; + rism.retry = BOOL_TO_INT(message.retry); + rism.messageRef = message.messageRef; + + if (message.gsmMessage.size() != 1) { + RLOGE("dispatchImsGsmSms: Invalid len %s", requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + return false; + } + + pStrings = (char **)calloc(countStrings, sizeof(char *)); + if (pStrings == NULL) { + RLOGE("dispatchImsGsmSms: Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return false; + } + + if (!copyHidlStringToRil(&pStrings[0], message.gsmMessage[0].smscPdu, pRI)) { +#ifdef MEMSET_FREED + memset(pStrings, 0, datalen); +#endif + free(pStrings); + return false; + } + + if (!copyHidlStringToRil(&pStrings[1], message.gsmMessage[0].pdu, pRI)) { + memsetAndFreeStrings(1, pStrings[0]); +#ifdef MEMSET_FREED + memset(pStrings, 0, datalen); +#endif + free(pStrings); + return false; + } + + rism.message.gsmMessage = pStrings; + CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) + + sizeof(uint8_t) + sizeof(int32_t) + dataLen, pRI, pRI->socket_id); + + for (int i = 0 ; i < countStrings ; i++) { + memsetAndFreeStrings(1, pStrings[i]); + } + +#ifdef MEMSET_FREED + memset(pStrings, 0, datalen); +#endif + free(pStrings); + + return true; +} + +bool dispatchImsCdmaSms(const ImsSmsMessage& message, RequestInfo *pRI) { + RIL_IMS_SMS_Message rism = {}; + RIL_CDMA_SMS_Message rcsm = {}; + + if (message.cdmaMessage.size() != 1) { + RLOGE("dispatchImsCdmaSms: Invalid len %s", requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + return false; + } + + rism.tech = RADIO_TECH_3GPP2; + rism.retry = BOOL_TO_INT(message.retry); + rism.messageRef = message.messageRef; + rism.message.cdmaMessage = &rcsm; + + constructCdmaSms(rcsm, message.cdmaMessage[0]); + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) + + sizeof(uint8_t) + sizeof(int32_t) + sizeof(rcsm), pRI, pRI->socket_id); + + return true; +} + +Return RadioImpl::sendImsSms(int32_t serial, const ImsSmsMessage& message) { +#if VDBG + RLOGD("sendImsSms: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_IMS_SEND_SMS); + if (pRI == NULL) { + return Void(); + } + + RIL_RadioTechnologyFamily format = (RIL_RadioTechnologyFamily) message.tech; + + if (RADIO_TECH_3GPP == format) { + dispatchImsGsmSms(message, pRI); + } else if (RADIO_TECH_3GPP2 == format) { + dispatchImsCdmaSms(message, pRI); + } else { + RLOGE("sendImsSms: Invalid radio tech %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + } + return Void(); +} + +Return RadioImpl::iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message) { +#if VDBG + RLOGD("iccTransmitApduBasicChannel: serial %d", serial); +#endif + dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, message); + return Void(); +} + +Return RadioImpl::iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) { +#if VDBG + RLOGD("iccOpenLogicalChannel: serial %d", serial); +#endif + if (s_vendorFunctions->version < 15) { + dispatchString(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL, aid.c_str()); + } else { + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL); + if (pRI == NULL) { + return Void(); + } + + RIL_OpenChannelParams params = {}; + + params.p2 = p2; + + if (!copyHidlStringToRil(¶ms.aidPtr, aid, pRI)) { + return Void(); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, ¶ms, sizeof(params), pRI, mSlotId); + + memsetAndFreeStrings(1, params.aidPtr); + } + return Void(); +} + +Return RadioImpl::iccCloseLogicalChannel(int32_t serial, int32_t channelId) { +#if VDBG + RLOGD("iccCloseLogicalChannel: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SIM_CLOSE_CHANNEL, 1, channelId); + return Void(); +} + +Return RadioImpl::iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message) { +#if VDBG + RLOGD("iccTransmitApduLogicalChannel: serial %d", serial); +#endif + dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, message); + return Void(); +} + +Return RadioImpl::nvReadItem(int32_t serial, NvItem itemId) { +#if VDBG + RLOGD("nvReadItem: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_READ_ITEM); + if (pRI == NULL) { + return Void(); + } + + RIL_NV_ReadItem nvri = {}; + nvri.itemID = (RIL_NV_Item) itemId; + + CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::nvWriteItem(int32_t serial, const NvWriteItem& item) { +#if VDBG + RLOGD("nvWriteItem: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_WRITE_ITEM); + if (pRI == NULL) { + return Void(); + } + + RIL_NV_WriteItem nvwi = {}; + + nvwi.itemID = (RIL_NV_Item) item.itemId; + + if (!copyHidlStringToRil(&nvwi.value, item.value, pRI)) { + return Void(); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, mSlotId); + + memsetAndFreeStrings(1, nvwi.value); + return Void(); +} + +Return RadioImpl::nvWriteCdmaPrl(int32_t serial, const hidl_vec& prl) { +#if VDBG + RLOGD("nvWriteCdmaPrl: serial %d", serial); +#endif + dispatchRaw(serial, mSlotId, RIL_REQUEST_NV_WRITE_CDMA_PRL, prl); + return Void(); +} + +Return RadioImpl::nvResetConfig(int32_t serial, ResetNvType resetType) { + int rilResetType = -1; +#if VDBG + RLOGD("nvResetConfig: serial %d", serial); +#endif + /* Convert ResetNvType to RIL.h values + * RIL_REQUEST_NV_RESET_CONFIG + * 1 - reload all NV items + * 2 - erase NV reset (SCRTN) + * 3 - factory reset (RTN) + */ + switch(resetType) { + case ResetNvType::RELOAD: + rilResetType = 1; + break; + case ResetNvType::ERASE: + rilResetType = 2; + break; + case ResetNvType::FACTORY_RESET: + rilResetType = 3; + break; + } + dispatchInts(serial, mSlotId, RIL_REQUEST_NV_RESET_CONFIG, 1, rilResetType); + return Void(); +} + +Return RadioImpl::setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub) { +#if VDBG + RLOGD("setUiccSubscription: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SET_UICC_SUBSCRIPTION); + if (pRI == NULL) { + return Void(); + } + + RIL_SelectUiccSub rilUiccSub = {}; + + rilUiccSub.slot = uiccSub.slot; + rilUiccSub.app_index = uiccSub.appIndex; + rilUiccSub.sub_type = (RIL_SubscriptionType) uiccSub.subType; + rilUiccSub.act_status = (RIL_UiccSubActStatus) uiccSub.actStatus; + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rilUiccSub, sizeof(rilUiccSub), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::setDataAllowed(int32_t serial, bool allow) { +#if VDBG + RLOGD("setDataAllowed: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_ALLOW_DATA, 1, BOOL_TO_INT(allow)); + return Void(); +} + +Return RadioImpl::getHardwareConfig(int32_t serial) { +#if VDBG + RLOGD("getHardwareConfig: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_HARDWARE_CONFIG); + return Void(); +} + +Return RadioImpl::requestIccSimAuthentication(int32_t serial, int32_t authContext, + const hidl_string& authData, const hidl_string& aid) { +#if VDBG + RLOGD("requestIccSimAuthentication: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_AUTHENTICATION); + if (pRI == NULL) { + return Void(); + } + + RIL_SimAuthentication pf = {}; + + pf.authContext = authContext; + + int len; + if (!copyHidlStringToRil(&pf.authData, authData, pRI)) { + return Void(); + } + + if (!copyHidlStringToRil(&pf.aid, aid, pRI)) { + memsetAndFreeStrings(1, pf.authData); + return Void(); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, mSlotId); + + memsetAndFreeStrings(2, pf.authData, pf.aid); + return Void(); +} + +/** + * @param numProfiles number of data profile + * @param dataProfiles the pointer to the actual data profiles. The acceptable type is + RIL_DataProfileInfo or RIL_DataProfileInfo_v15. + * @param dataProfilePtrs the pointer to the pointers that point to each data profile structure + * @param numfields number of string-type member in the data profile structure + * @param ... the variadic parameters are pointers to each string-type member + **/ +template +void freeSetDataProfileData(int numProfiles, T *dataProfiles, T **dataProfilePtrs, + int numfields, ...) { + va_list args; + va_start(args, numfields); + + // Iterate through each string-type field that need to be free. + for (int i = 0; i < numfields; i++) { + // Iterate through each data profile and free that specific string-type field. + // The type 'char *T::*' is a type of pointer to a 'char *' member inside T structure. + char *T::*ptr = va_arg(args, char *T::*); + for (int j = 0; j < numProfiles; j++) { + memsetAndFreeStrings(1, dataProfiles[j].*ptr); + } + } + + va_end(args); + +#ifdef MEMSET_FREED + memset(dataProfiles, 0, numProfiles * sizeof(T)); + memset(dataProfilePtrs, 0, numProfiles * sizeof(T *)); +#endif + free(dataProfiles); + free(dataProfilePtrs); +} + +Return RadioImpl::setDataProfile(int32_t serial, const hidl_vec& profiles, + bool isRoaming) { +#if VDBG + RLOGD("setDataProfile: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_DATA_PROFILE); + if (pRI == NULL) { + return Void(); + } + + size_t num = profiles.size(); + bool success = false; + + if (s_vendorFunctions->version <= 14) { + + RIL_DataProfileInfo *dataProfiles = + (RIL_DataProfileInfo *) calloc(num, sizeof(RIL_DataProfileInfo)); + + if (dataProfiles == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + + RIL_DataProfileInfo **dataProfilePtrs = + (RIL_DataProfileInfo **) calloc(num, sizeof(RIL_DataProfileInfo *)); + if (dataProfilePtrs == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + free(dataProfiles); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + + for (size_t i = 0; i < num; i++) { + dataProfilePtrs[i] = &dataProfiles[i]; + + success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI); + + const hidl_string &protocol = + (isRoaming ? profiles[i].roamingProtocol : profiles[i].protocol); + + if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI)) { + success = false; + } + + if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, + pRI)) { + success = false; + } + + if (!success) { + freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4, + &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol, + &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password); + return Void(); + } + + dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId; + dataProfiles[i].authType = (int) profiles[i].authType; + dataProfiles[i].type = (int) profiles[i].type; + dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime; + dataProfiles[i].maxConns = profiles[i].maxConns; + dataProfiles[i].waitTime = profiles[i].waitTime; + dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled); + } + + CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs, + num * sizeof(RIL_DataProfileInfo *), pRI, mSlotId); + + freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4, + &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol, + &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password); + } else { + RIL_DataProfileInfo_v15 *dataProfiles = + (RIL_DataProfileInfo_v15 *) calloc(num, sizeof(RIL_DataProfileInfo_v15)); + + if (dataProfiles == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + + RIL_DataProfileInfo_v15 **dataProfilePtrs = + (RIL_DataProfileInfo_v15 **) calloc(num, sizeof(RIL_DataProfileInfo_v15 *)); + if (dataProfilePtrs == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + free(dataProfiles); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + + for (size_t i = 0; i < num; i++) { + dataProfilePtrs[i] = &dataProfiles[i]; + + success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI); + if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, profiles[i].protocol, + pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].roamingProtocol, + profiles[i].roamingProtocol, pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, + pRI)) { + success = false; + } + + if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData, + profiles[i].mvnoMatchData, pRI)) { + success = false; + } + + if (success && !convertMvnoTypeToString(profiles[i].mvnoType, + dataProfiles[i].mvnoType)) { + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + success = false; + } + + if (!success) { + freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6, + &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol, + &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user, + &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData); + return Void(); + } + + dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId; + dataProfiles[i].authType = (int) profiles[i].authType; + dataProfiles[i].type = (int) profiles[i].type; + dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime; + dataProfiles[i].maxConns = profiles[i].maxConns; + dataProfiles[i].waitTime = profiles[i].waitTime; + dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled); + dataProfiles[i].supportedTypesBitmask = profiles[i].supportedApnTypesBitmap; + dataProfiles[i].bearerBitmask = profiles[i].bearerBitmap; + dataProfiles[i].mtu = profiles[i].mtu; + } + + CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs, + num * sizeof(RIL_DataProfileInfo_v15 *), pRI, mSlotId); + + freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6, + &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol, + &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user, + &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData); + } + + return Void(); +} + +Return RadioImpl::requestShutdown(int32_t serial) { +#if VDBG + RLOGD("requestShutdown: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_SHUTDOWN); + return Void(); +} + +Return RadioImpl::getRadioCapability(int32_t serial) { +#if VDBG + RLOGD("getRadioCapability: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_RADIO_CAPABILITY); + return Void(); +} + +Return RadioImpl::setRadioCapability(int32_t serial, const RadioCapability& rc) { +#if VDBG + RLOGD("setRadioCapability: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_RADIO_CAPABILITY); + if (pRI == NULL) { + return Void(); + } + + RIL_RadioCapability rilRc = {}; + + // TODO : set rilRc.version using HIDL version ? + rilRc.session = rc.session; + rilRc.phase = (int) rc.phase; + rilRc.rat = (int) rc.raf; + rilRc.status = (int) rc.status; + strncpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), MAX_UUID_LENGTH); + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId); + + return Void(); +} + +Return RadioImpl::startLceService(int32_t serial, int32_t reportInterval, bool pullMode) { +#if VDBG + RLOGD("startLceService: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_START_LCE, 2, reportInterval, + BOOL_TO_INT(pullMode)); + return Void(); +} + +Return RadioImpl::stopLceService(int32_t serial) { +#if VDBG + RLOGD("stopLceService: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_LCE); + return Void(); +} + +Return RadioImpl::pullLceData(int32_t serial) { +#if VDBG + RLOGD("pullLceData: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_PULL_LCEDATA); + return Void(); +} + +Return RadioImpl::getModemActivityInfo(int32_t serial) { +#if VDBG + RLOGD("getModemActivityInfo: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_ACTIVITY_INFO); + return Void(); +} + +Return RadioImpl::setAllowedCarriers(int32_t serial, bool allAllowed, + const CarrierRestrictions& carriers) { +#if VDBG + RLOGD("setAllowedCarriers: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SET_CARRIER_RESTRICTIONS); + if (pRI == NULL) { + return Void(); + } + + RIL_CarrierRestrictions cr = {}; + RIL_Carrier *allowedCarriers = NULL; + RIL_Carrier *excludedCarriers = NULL; + + cr.len_allowed_carriers = carriers.allowedCarriers.size(); + allowedCarriers = (RIL_Carrier *)calloc(cr.len_allowed_carriers, sizeof(RIL_Carrier)); + if (allowedCarriers == NULL) { + RLOGE("setAllowedCarriers: Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + cr.allowed_carriers = allowedCarriers; + + cr.len_excluded_carriers = carriers.excludedCarriers.size(); + excludedCarriers = (RIL_Carrier *)calloc(cr.len_excluded_carriers, sizeof(RIL_Carrier)); + if (excludedCarriers == NULL) { + RLOGE("setAllowedCarriers: Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); +#ifdef MEMSET_FREED + memset(allowedCarriers, 0, cr.len_allowed_carriers * sizeof(RIL_Carrier)); +#endif + free(allowedCarriers); + return Void(); + } + cr.excluded_carriers = excludedCarriers; + + for (int i = 0; i < cr.len_allowed_carriers; i++) { + allowedCarriers[i].mcc = carriers.allowedCarriers[i].mcc.c_str(); + allowedCarriers[i].mnc = carriers.allowedCarriers[i].mnc.c_str(); + allowedCarriers[i].match_type = (RIL_CarrierMatchType) carriers.allowedCarriers[i].matchType; + allowedCarriers[i].match_data = carriers.allowedCarriers[i].matchData.c_str(); + } + + for (int i = 0; i < cr.len_excluded_carriers; i++) { + excludedCarriers[i].mcc = carriers.excludedCarriers[i].mcc.c_str(); + excludedCarriers[i].mnc = carriers.excludedCarriers[i].mnc.c_str(); + excludedCarriers[i].match_type = + (RIL_CarrierMatchType) carriers.excludedCarriers[i].matchType; + excludedCarriers[i].match_data = carriers.excludedCarriers[i].matchData.c_str(); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, &cr, sizeof(RIL_CarrierRestrictions), pRI, mSlotId); + +#ifdef MEMSET_FREED + memset(allowedCarriers, 0, cr.len_allowed_carriers * sizeof(RIL_Carrier)); + memset(excludedCarriers, 0, cr.len_excluded_carriers * sizeof(RIL_Carrier)); +#endif + free(allowedCarriers); + free(excludedCarriers); + return Void(); +} + +Return RadioImpl::getAllowedCarriers(int32_t serial) { +#if VDBG + RLOGD("getAllowedCarriers: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS); + return Void(); +} + +Return RadioImpl::sendDeviceState(int32_t serial, DeviceStateType deviceStateType, + bool state) { +#if VDBG + RLOGD("sendDeviceState: serial %d", serial); +#endif + if (s_vendorFunctions->version < 15) { + if (deviceStateType == DeviceStateType::LOW_DATA_EXPECTED) { + RLOGD("sendDeviceState: calling screen state %d", BOOL_TO_INT(!state)); + dispatchInts(serial, mSlotId, RIL_REQUEST_SCREEN_STATE, 1, BOOL_TO_INT(!state)); + } else { + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SEND_DEVICE_STATE); + sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); + } + return Void(); + } + dispatchInts(serial, mSlotId, RIL_REQUEST_SEND_DEVICE_STATE, 2, (int) deviceStateType, + BOOL_TO_INT(state)); + return Void(); +} + +Return RadioImpl::setIndicationFilter(int32_t serial, int32_t indicationFilter) { +#if VDBG + RLOGD("setIndicationFilter: serial %d", serial); +#endif + if (s_vendorFunctions->version < 15) { + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, + RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER); + sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); + return Void(); + } + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, 1, indicationFilter); + return Void(); +} + +Return RadioImpl::setSimCardPower(int32_t serial, bool powerUp) { +#if VDBG + RLOGD("setSimCardPower: serial %d", serial); +#endif + dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, BOOL_TO_INT(powerUp)); + return Void(); +} + +Return RadioImpl::responseAcknowledgement() { + android::releaseWakeLock(); + return Void(); +} + +Return OemHookImpl::setResponseFunctions( + const ::android::sp& oemHookResponseParam, + const ::android::sp& oemHookIndicationParam) { +#if VDBG + RLOGD("OemHookImpl::setResponseFunctions"); +#endif + + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(mSlotId); + int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); + assert(ret == 0); + + mOemHookResponse = oemHookResponseParam; + mOemHookIndication = oemHookIndicationParam; + mCounterOemHook[mSlotId]++; + + ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + + return Void(); +} + +Return OemHookImpl::sendRequestRaw(int32_t serial, const hidl_vec& data) { +#if VDBG + RLOGD("OemHookImpl::sendRequestRaw: serial %d", serial); +#endif + dispatchRaw(serial, mSlotId, RIL_REQUEST_OEM_HOOK_RAW, data); + return Void(); +} + +Return OemHookImpl::sendRequestStrings(int32_t serial, + const hidl_vec& data) { +#if VDBG + RLOGD("OemHookImpl::sendRequestStrings: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_OEM_HOOK_STRINGS, data); + return Void(); +} + +/*************************************************************************************************** + * RESPONSE FUNCTIONS + * Functions above are used for requests going from framework to vendor code. The ones below are + * responses for those requests coming back from the vendor code. + **************************************************************************************************/ + +void radio::acknowledgeRequest(int slotId, int serial) { + if (radioService[slotId]->mRadioResponse != NULL) { + Return retStatus = radioService[slotId]->mRadioResponse->acknowledgeRequest(serial); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeRequest: radioService[%d]->mRadioResponse == NULL", slotId); + } +} + +void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e) { + responseInfo.serial = serial; + switch (responseType) { + case RESPONSE_SOLICITED: + responseInfo.type = RadioResponseType::SOLICITED; + break; + case RESPONSE_SOLICITED_ACK_EXP: + responseInfo.type = RadioResponseType::SOLICITED_ACK_EXP; + break; + } + responseInfo.error = (RadioError) e; +} + +int responseIntOrEmpty(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e, + void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + int ret = -1; + + if (response == NULL && responseLen == 0) { + // Earlier RILs did not send a response for some cases although the interface + // expected an integer as response. Do not return error if response is empty. Instead + // Return -1 in those cases to maintain backward compatibility. + } else if (response == NULL || responseLen != sizeof(int)) { + RLOGE("responseIntOrEmpty: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *p_int = (int *) response; + ret = p_int[0]; + } + return ret; +} + +int responseInt(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e, + void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + int ret = -1; + + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("responseInt: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *p_int = (int *) response; + ret = p_int[0]; + } + return ret; +} + +int radio::getIccCardStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + CardStatus cardStatus = {}; + if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6)) { + RLOGE("getIccCardStatusResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response); + cardStatus.cardState = (CardState) p_cur->card_state; + cardStatus.universalPinState = (PinState) p_cur->universal_pin_state; + cardStatus.gsmUmtsSubscriptionAppIndex = p_cur->gsm_umts_subscription_app_index; + cardStatus.cdmaSubscriptionAppIndex = p_cur->cdma_subscription_app_index; + cardStatus.imsSubscriptionAppIndex = p_cur->ims_subscription_app_index; + + RIL_AppStatus *rilAppStatus = p_cur->applications; + cardStatus.applications.resize(p_cur->num_applications); + AppStatus *appStatus = cardStatus.applications.data(); +#if VDBG + RLOGD("getIccCardStatusResponse: num_applications %d", p_cur->num_applications); +#endif + for (int i = 0; i < p_cur->num_applications; i++) { + appStatus[i].appType = (AppType) rilAppStatus[i].app_type; + appStatus[i].appState = (AppState) rilAppStatus[i].app_state; + appStatus[i].persoSubstate = (PersoSubstate) rilAppStatus[i].perso_substate; + appStatus[i].aidPtr = convertCharPtrToHidlString(rilAppStatus[i].aid_ptr); + appStatus[i].appLabelPtr = convertCharPtrToHidlString( + rilAppStatus[i].app_label_ptr); + appStatus[i].pin1Replaced = rilAppStatus[i].pin1_replaced; + appStatus[i].pin1 = (PinState) rilAppStatus[i].pin1; + appStatus[i].pin2 = (PinState) rilAppStatus[i].pin2; + } + } + + Return retStatus = radioService[slotId]->mRadioResponse-> + getIccCardStatusResponse(responseInfo, cardStatus); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getIccCardStatusResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::supplyIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPinForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyIccPinForAppResponse(responseInfo, ret); + RLOGE("supplyIccPinForAppResponse: amit ret %d", ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyIccPukForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPukForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse->supplyIccPukForAppResponse( + responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPukForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPin2ForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyIccPin2ForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyIccPuk2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPuk2ForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyIccPuk2ForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPuk2ForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::changeIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("changeIccPinForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + changeIccPinForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("changeIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::changeIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("changeIccPin2ForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + changeIccPin2ForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("changeIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyNetworkDepersonalizationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyNetworkDepersonalizationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyNetworkDepersonalizationResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyNetworkDepersonalizationResponse: radioService[%d]->mRadioResponse == " + "NULL", slotId); + } + + return 0; +} + +int radio::getCurrentCallsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCurrentCallsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec calls; + if ((response == NULL && responseLen != 0) + || (responseLen % sizeof(RIL_Call *)) != 0) { + RLOGE("getCurrentCallsResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_Call *); + calls.resize(num); + + for (int i = 0 ; i < num ; i++) { + RIL_Call *p_cur = ((RIL_Call **) response)[i]; + /* each call info */ + calls[i].state = (CallState) p_cur->state; + calls[i].index = p_cur->index; + calls[i].toa = p_cur->toa; + calls[i].isMpty = p_cur->isMpty; + calls[i].isMT = p_cur->isMT; + calls[i].als = p_cur->als; + calls[i].isVoice = p_cur->isVoice; + calls[i].isVoicePrivacy = p_cur->isVoicePrivacy; + calls[i].number = convertCharPtrToHidlString(p_cur->number); + calls[i].numberPresentation = (CallPresentation) p_cur->numberPresentation; + calls[i].name = convertCharPtrToHidlString(p_cur->name); + calls[i].namePresentation = (CallPresentation) p_cur->namePresentation; + if (p_cur->uusInfo != NULL && p_cur->uusInfo->uusData != NULL) { + RIL_UUS_Info *uusInfo = p_cur->uusInfo; + calls[i].uusInfo[0].uusType = (UusType) uusInfo->uusType; + calls[i].uusInfo[0].uusDcs = (UusDcs) uusInfo->uusDcs; + // convert uusInfo->uusData to a null-terminated string + char *nullTermStr = strndup(uusInfo->uusData, uusInfo->uusLength); + calls[i].uusInfo[0].uusData = nullTermStr; + free(nullTermStr); + } + } + } + + Return retStatus = radioService[slotId]->mRadioResponse-> + getCurrentCallsResponse(responseInfo, calls); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCurrentCallsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::dialResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("dialResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->dialResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("dialResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getIMSIForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getIMSIForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->getIMSIForAppResponse( + responseInfo, convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getIMSIForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::hangupConnectionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("hangupConnectionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->hangupConnectionResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hangupConnectionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::hangupWaitingOrBackgroundResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::hangupForegroundResumeBackgroundResponse(int slotId, int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::switchWaitingOrHoldingAndActiveResponse(int slotId, int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("switchWaitingOrHoldingAndActiveResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->switchWaitingOrHoldingAndActiveResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("switchWaitingOrHoldingAndActiveResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::conferenceResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responseLen) { +#if VDBG + RLOGD("conferenceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->conferenceResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("conferenceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::rejectCallResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responseLen) { +#if VDBG + RLOGD("rejectCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->rejectCallResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("rejectCallResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getLastCallFailCauseResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getLastCallFailCauseResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + LastCallFailCauseInfo info = {}; + info.vendorCause = hidl_string(); + if (response == NULL) { + RLOGE("getCurrentCallsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else if (responseLen == sizeof(int)) { + int *pInt = (int *) response; + info.causeCode = (LastCallFailCause) pInt[0]; + } else if (responseLen == sizeof(RIL_LastCallFailCauseInfo)) { + RIL_LastCallFailCauseInfo *pFailCauseInfo = (RIL_LastCallFailCauseInfo *) response; + info.causeCode = (LastCallFailCause) pFailCauseInfo->cause_code; + info.vendorCause = convertCharPtrToHidlString(pFailCauseInfo->vendor_cause); + } else { + RLOGE("getCurrentCallsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } + + Return retStatus = radioService[slotId]->mRadioResponse->getLastCallFailCauseResponse( + responseInfo, info); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getLastCallFailCauseResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getSignalStrengthResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getSignalStrengthResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + SignalStrength signalStrength = {}; + if (response == NULL || (responseLen != sizeof(RIL_SignalStrength_v10) + && responseLen != sizeof(RIL_SignalStrength_v8))) { + RLOGE("getSignalStrengthResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilSignalStrengthToHal(response, responseLen, signalStrength); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getSignalStrengthResponse( + responseInfo, signalStrength); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getSignalStrengthResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +RIL_CellInfoType getCellInfoTypeRadioTechnology(char *rat) { + if (rat == NULL) { + return RIL_CELL_INFO_TYPE_NONE; + } + + int radioTech = atoi(rat); + + switch(radioTech) { + + case RADIO_TECH_GPRS: + case RADIO_TECH_EDGE: + case RADIO_TECH_GSM: { + return RIL_CELL_INFO_TYPE_GSM; + } + + case RADIO_TECH_UMTS: + case RADIO_TECH_HSDPA: + case RADIO_TECH_HSUPA: + case RADIO_TECH_HSPA: + case RADIO_TECH_HSPAP: { + return RIL_CELL_INFO_TYPE_WCDMA; + } + + case RADIO_TECH_IS95A: + case RADIO_TECH_IS95B: + case RADIO_TECH_1xRTT: + case RADIO_TECH_EVDO_0: + case RADIO_TECH_EVDO_A: + case RADIO_TECH_EVDO_B: + case RADIO_TECH_EHRPD: { + return RIL_CELL_INFO_TYPE_CDMA; + } + + case RADIO_TECH_LTE: + case RADIO_TECH_LTE_CA: { + return RIL_CELL_INFO_TYPE_LTE; + } + + case RADIO_TECH_TD_SCDMA: { + return RIL_CELL_INFO_TYPE_TD_SCDMA; + } + + default: { + break; + } + } + + return RIL_CELL_INFO_TYPE_NONE; + +} + +void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &rilCellIdentity) { + + cellIdentity.cellIdentityGsm.resize(0); + cellIdentity.cellIdentityWcdma.resize(0); + cellIdentity.cellIdentityCdma.resize(0); + cellIdentity.cellIdentityTdscdma.resize(0); + cellIdentity.cellIdentityLte.resize(0); + cellIdentity.cellInfoType = (CellInfoType)rilCellIdentity.cellInfoType; + switch(rilCellIdentity.cellInfoType) { + + case RIL_CELL_INFO_TYPE_GSM: { + cellIdentity.cellIdentityGsm.resize(1); + cellIdentity.cellIdentityGsm[0].mcc = + std::to_string(rilCellIdentity.cellIdentityGsm.mcc); + cellIdentity.cellIdentityGsm[0].mnc = + std::to_string(rilCellIdentity.cellIdentityGsm.mnc); + cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac; + cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid; + cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn; + cellIdentity.cellIdentityGsm[0].bsic = rilCellIdentity.cellIdentityGsm.bsic; + break; + } + + case RIL_CELL_INFO_TYPE_WCDMA: { + cellIdentity.cellIdentityWcdma.resize(1); + cellIdentity.cellIdentityWcdma[0].mcc = + std::to_string(rilCellIdentity.cellIdentityWcdma.mcc); + cellIdentity.cellIdentityWcdma[0].mnc = + std::to_string(rilCellIdentity.cellIdentityWcdma.mnc); + cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac; + cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid; + cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc; + cellIdentity.cellIdentityWcdma[0].uarfcn = rilCellIdentity.cellIdentityWcdma.uarfcn; + break; + } + + case RIL_CELL_INFO_TYPE_CDMA: { + cellIdentity.cellIdentityCdma.resize(1); + cellIdentity.cellIdentityCdma[0].networkId = rilCellIdentity.cellIdentityCdma.networkId; + cellIdentity.cellIdentityCdma[0].systemId = rilCellIdentity.cellIdentityCdma.systemId; + cellIdentity.cellIdentityCdma[0].baseStationId = + rilCellIdentity.cellIdentityCdma.basestationId; + cellIdentity.cellIdentityCdma[0].longitude = rilCellIdentity.cellIdentityCdma.longitude; + cellIdentity.cellIdentityCdma[0].latitude = rilCellIdentity.cellIdentityCdma.latitude; + break; + } + + case RIL_CELL_INFO_TYPE_LTE: { + cellIdentity.cellIdentityLte.resize(1); + cellIdentity.cellIdentityLte[0].mcc = + std::to_string(rilCellIdentity.cellIdentityLte.mcc); + cellIdentity.cellIdentityLte[0].mnc = + std::to_string(rilCellIdentity.cellIdentityLte.mnc); + cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci; + cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci; + cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac; + cellIdentity.cellIdentityLte[0].earfcn = rilCellIdentity.cellIdentityLte.earfcn; + break; + } + + case RIL_CELL_INFO_TYPE_TD_SCDMA: { + cellIdentity.cellIdentityTdscdma.resize(1); + cellIdentity.cellIdentityTdscdma[0].mcc = + std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc); + cellIdentity.cellIdentityTdscdma[0].mnc = + std::to_string(rilCellIdentity.cellIdentityTdscdma.mnc); + cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac; + cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid; + cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid; + break; + } + + default: { + break; + } + } +} + +int convertResponseStringEntryToInt(char **response, int index, int numStrings) { + if ((response != NULL) && (numStrings > index) && (response[index] != NULL)) { + return atoi(response[index]); + } + + return -1; +} + +int convertResponseHexStringEntryToInt(char **response, int index, int numStrings) { + const int hexBase = 16; + if ((response != NULL) && (numStrings > index) && (response[index] != NULL)) { + return strtol(response[index], NULL, hexBase); + } + + return -1; +} + +/* Fill Cell Identity info from Voice Registration State Response. + * This fucntion is applicable only for RIL Version < 15. + * Response is a "char **". + * First and Second entries are in hex string format + * and rest are integers represented in ascii format. */ +void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity, + int numStrings, char** response) { + + RIL_CellIdentity_v16 rilCellIdentity; + memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16)); + + rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]); + switch(rilCellIdentity.cellInfoType) { + + case RIL_CELL_INFO_TYPE_GSM: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityGsm.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityGsm.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_WCDMA: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityWcdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityWcdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + rilCellIdentity.cellIdentityWcdma.psc = + convertResponseStringEntryToInt(response, 14, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_TD_SCDMA:{ + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityTdscdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityTdscdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_CDMA:{ + rilCellIdentity.cellIdentityCdma.basestationId = + convertResponseStringEntryToInt(response, 4, numStrings); + rilCellIdentity.cellIdentityCdma.longitude = + convertResponseStringEntryToInt(response, 5, numStrings); + rilCellIdentity.cellIdentityCdma.latitude = + convertResponseStringEntryToInt(response, 6, numStrings); + rilCellIdentity.cellIdentityCdma.systemId = + convertResponseStringEntryToInt(response, 8, numStrings); + rilCellIdentity.cellIdentityCdma.networkId = + convertResponseStringEntryToInt(response, 9, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_LTE:{ + /* valid TAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityLte.tac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityLte.ci = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + + default: { + break; + } + } + + fillCellIdentityResponse(cellIdentity, rilCellIdentity); +} + +/* Fill Cell Identity info from Data Registration State Response. + * This fucntion is applicable only for RIL Version < 15. + * Response is a "char **". + * First and Second entries are in hex string format + * and rest are integers represented in ascii format. */ +void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity, + int numStrings, char** response) { + + RIL_CellIdentity_v16 rilCellIdentity; + memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16)); + + rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]); + switch(rilCellIdentity.cellInfoType) { + case RIL_CELL_INFO_TYPE_GSM: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityGsm.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityGsm.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + case RIL_CELL_INFO_TYPE_WCDMA: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityWcdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityWcdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + case RIL_CELL_INFO_TYPE_TD_SCDMA:{ + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityTdscdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityTdscdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + case RIL_CELL_INFO_TYPE_LTE: { + rilCellIdentity.cellIdentityLte.tac = + convertResponseStringEntryToInt(response, 6, numStrings); + rilCellIdentity.cellIdentityLte.pci = + convertResponseStringEntryToInt(response, 7, numStrings); + rilCellIdentity.cellIdentityLte.ci = + convertResponseStringEntryToInt(response, 8, numStrings); + break; + } + default: { + break; + } + } + + fillCellIdentityResponse(cellIdentity, rilCellIdentity); +} + +int radio::getVoiceRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getVoiceRegistrationStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + VoiceRegStateResult voiceRegResponse = {}; + int numStrings = responseLen / sizeof(char *); + if (response == NULL) { + RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else if (s_vendorFunctions->version <= 14) { + if (numStrings != 15) { + RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4); + voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]); + voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0); + voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]); + voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0); + voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0); + voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0); + fillCellIdentityFromVoiceRegStateResponseString(voiceRegResponse.cellIdentity, + numStrings, resp); + } + } else { + RIL_VoiceRegistrationStateResponse *voiceRegState = + (RIL_VoiceRegistrationStateResponse *)response; + + if (responseLen != sizeof(RIL_VoiceRegistrationStateResponse)) { + RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + voiceRegResponse.regState = (RegState) voiceRegState->regState; + voiceRegResponse.rat = voiceRegState->rat;; + voiceRegResponse.cssSupported = voiceRegState->cssSupported; + voiceRegResponse.roamingIndicator = voiceRegState->roamingIndicator; + voiceRegResponse.systemIsInPrl = voiceRegState->systemIsInPrl; + voiceRegResponse.defaultRoamingIndicator = voiceRegState->defaultRoamingIndicator; + voiceRegResponse.reasonForDenial = voiceRegState->reasonForDenial; + fillCellIdentityResponse(voiceRegResponse.cellIdentity, + voiceRegState->cellIdentity); + } + } + + Return retStatus = + radioService[slotId]->mRadioResponse->getVoiceRegistrationStateResponse( + responseInfo, voiceRegResponse); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getVoiceRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getDataRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getDataRegistrationStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + DataRegStateResult dataRegResponse = {}; + if (response == NULL) { + RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else if (s_vendorFunctions->version <= 14) { + int numStrings = responseLen / sizeof(char *); + if ((numStrings != 6) && (numStrings != 11)) { + RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4); + dataRegResponse.rat = ATOI_NULL_HANDLED_DEF(resp[3], 0); + dataRegResponse.reasonDataDenied = ATOI_NULL_HANDLED(resp[4]); + dataRegResponse.maxDataCalls = ATOI_NULL_HANDLED_DEF(resp[5], 1); + fillCellIdentityFromDataRegStateResponseString(dataRegResponse.cellIdentity, + numStrings, resp); + } + } else { + RIL_DataRegistrationStateResponse *dataRegState = + (RIL_DataRegistrationStateResponse *)response; + + if (responseLen != sizeof(RIL_DataRegistrationStateResponse)) { + RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + dataRegResponse.regState = (RegState) dataRegState->regState; + dataRegResponse.rat = dataRegState->rat;; + dataRegResponse.reasonDataDenied = dataRegState->reasonDataDenied; + dataRegResponse.maxDataCalls = dataRegState->maxDataCalls; + fillCellIdentityResponse(dataRegResponse.cellIdentity, dataRegState->cellIdentity); + } + } + + Return retStatus = + radioService[slotId]->mRadioResponse->getDataRegistrationStateResponse(responseInfo, + dataRegResponse); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getDataRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getOperatorResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getOperatorResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_string longName; + hidl_string shortName; + hidl_string numeric; + int numStrings = responseLen / sizeof(char *); + if (response == NULL || numStrings != 3) { + RLOGE("getOperatorResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + + } else { + char **resp = (char **) response; + longName = convertCharPtrToHidlString(resp[0]); + shortName = convertCharPtrToHidlString(resp[1]); + numeric = convertCharPtrToHidlString(resp[2]); + } + Return retStatus = radioService[slotId]->mRadioResponse->getOperatorResponse( + responseInfo, longName, shortName, numeric); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getOperatorResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setRadioPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { + RLOGD("setRadioPowerResponse: serial %d", serial); + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setRadioPowerResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->sendDtmfResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendDtmfResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +SendSmsResult makeSendSmsResult(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e, void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + SendSmsResult result = {}; + + if (response == NULL || responseLen != sizeof(RIL_SMS_Response)) { + RLOGE("Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + result.ackPDU = hidl_string(); + } else { + RIL_SMS_Response *resp = (RIL_SMS_Response *) response; + result.messageRef = resp->messageRef; + result.ackPDU = convertCharPtrToHidlString(resp->ackPDU); + result.errorCode = resp->errorCode; + } + return result; +} + +int radio::sendSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus = radioService[slotId]->mRadioResponse->sendSmsResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendSMSExpectMoreResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendSMSExpectMoreResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus = radioService[slotId]->mRadioResponse->sendSMSExpectMoreResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendSMSExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setupDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setupDataCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + SetupDataCallResult result = {}; + + if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v9) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v6) != 0)) { + if (response != NULL) { + RLOGE("setupDataCallResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } + result.status = DataCallFailCause::ERROR_UNSPECIFIED; + result.type = hidl_string(); + result.ifname = hidl_string(); + result.addresses = hidl_string(); + result.dnses = hidl_string(); + result.gateways = hidl_string(); + result.pcscf = hidl_string(); + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v11)) == 0) { + convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result); + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v9)) == 0) { + convertRilDataCallToHal((RIL_Data_Call_Response_v9 *) response, result); + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v6)) == 0) { + convertRilDataCallToHal((RIL_Data_Call_Response_v6 *) response, result); + } + + Return retStatus = radioService[slotId]->mRadioResponse->setupDataCallResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setupDataCallResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +IccIoResult responseIccIo(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e, void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + IccIoResult result = {}; + + if (response == NULL || responseLen != sizeof(RIL_SIM_IO_Response)) { + RLOGE("Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + result.simResponse = hidl_string(); + } else { + RIL_SIM_IO_Response *resp = (RIL_SIM_IO_Response *) response; + result.sw1 = resp->sw1; + result.sw2 = resp->sw2; + result.simResponse = convertCharPtrToHidlString(resp->simResponse); + } + return result; +} + +int radio::iccIOForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("iccIOForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus = radioService[slotId]->mRadioResponse->iccIOForAppResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccIOForAppResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendUssdResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->sendUssdResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendUssdResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::cancelPendingUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("cancelPendingUssdResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->cancelPendingUssdResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cancelPendingUssdResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getClirResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + int n = -1, m = -1; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 2) { + RLOGE("getClirResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + n = pInt[0]; + m = pInt[1]; + } + Return retStatus = radioService[slotId]->mRadioResponse->getClirResponse(responseInfo, + n, m); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getClirResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setClirResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setClirResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setClirResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getCallForwardStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCallForwardStatusResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec callForwardInfos; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_CallForwardInfo *) != 0) { + RLOGE("getCallForwardStatusResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_CallForwardInfo *); + callForwardInfos.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_CallForwardInfo *resp = ((RIL_CallForwardInfo **) response)[i]; + callForwardInfos[i].status = (CallForwardInfoStatus) resp->status; + callForwardInfos[i].reason = resp->reason; + callForwardInfos[i].serviceClass = resp->serviceClass; + callForwardInfos[i].toa = resp->toa; + callForwardInfos[i].number = convertCharPtrToHidlString(resp->number); + callForwardInfos[i].timeSeconds = resp->timeSeconds; + } + } + + Return retStatus = radioService[slotId]->mRadioResponse->getCallForwardStatusResponse( + responseInfo, callForwardInfos); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCallForwardStatusResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCallForwardResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setCallForwardResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setCallForwardResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCallForwardResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getCallWaitingResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool enable = false; + int serviceClass = -1; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 2) { + RLOGE("getCallWaitingResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + enable = pInt[0] == 1 ? true : false; + serviceClass = pInt[1]; + } + Return retStatus = radioService[slotId]->mRadioResponse->getCallWaitingResponse( + responseInfo, enable, serviceClass); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setCallWaitingResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setCallWaitingResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::acknowledgeLastIncomingGsmSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acknowledgeLastIncomingGsmSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->acknowledgeLastIncomingGsmSmsResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeLastIncomingGsmSmsResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::acceptCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acceptCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->acceptCallResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acceptCallResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::deactivateDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("deactivateDataCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->deactivateDataCallResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("deactivateDataCallResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getFacilityLockForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + getFacilityLockForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setFacilityLockForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->setFacilityLockForAppResponse(responseInfo, + ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setBarringPasswordResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acceptCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setBarringPasswordResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setBarringPasswordResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getNetworkSelectionModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getNetworkSelectionModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool manual = false; + int serviceClass; + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("getNetworkSelectionModeResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + manual = pInt[0] == 1 ? true : false; + } + Return retStatus + = radioService[slotId]->mRadioResponse->getNetworkSelectionModeResponse( + responseInfo, + manual); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getNetworkSelectionModeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setNetworkSelectionModeAutomaticResponse(int slotId, int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setNetworkSelectionModeAutomaticResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setNetworkSelectionModeAutomaticResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setNetworkSelectionModeAutomaticResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::setNetworkSelectionModeManualResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setNetworkSelectionModeManualResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setNetworkSelectionModeManualResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acceptCallResponse: radioService[%d]->setNetworkSelectionModeManualResponse " + "== NULL", slotId); + } + + return 0; +} + +int convertOperatorStatusToInt(const char *str) { + if (strncmp("unknown", str, 9) == 0) { + return (int) OperatorStatus::UNKNOWN; + } else if (strncmp("available", str, 9) == 0) { + return (int) OperatorStatus::AVAILABLE; + } else if (strncmp("current", str, 9) == 0) { + return (int) OperatorStatus::CURRENT; + } else if (strncmp("forbidden", str, 9) == 0) { + return (int) OperatorStatus::FORBIDDEN; + } else { + return -1; + } +} + +int radio::getAvailableNetworksResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getAvailableNetworksResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec networks; + if ((response == NULL && responseLen != 0) + || responseLen % (4 * sizeof(char *))!= 0) { + RLOGE("getAvailableNetworksResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + int numStrings = responseLen / sizeof(char *); + networks.resize(numStrings/4); + for (int i = 0, j = 0; i < numStrings; i = i + 4, j++) { + networks[j].alphaLong = convertCharPtrToHidlString(resp[i]); + networks[j].alphaShort = convertCharPtrToHidlString(resp[i + 1]); + networks[j].operatorNumeric = convertCharPtrToHidlString(resp[i + 2]); + int status = convertOperatorStatusToInt(resp[i + 3]); + if (status == -1) { + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + networks[j].status = (OperatorStatus) status; + } + } + } + Return retStatus + = radioService[slotId]->mRadioResponse->getAvailableNetworksResponse(responseInfo, + networks); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getAvailableNetworksResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::startDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("startDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->startDtmfResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("startDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::stopDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("stopDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->stopDtmfResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stopDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getBasebandVersionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getBasebandVersionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->getBasebandVersionResponse(responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getBasebandVersionResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::separateConnectionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("separateConnectionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->separateConnectionResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("separateConnectionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setMuteResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setMuteResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getMuteResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool enable = false; + int serviceClass; + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("getMuteResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + enable = pInt[0] == 1 ? true : false; + } + Return retStatus = radioService[slotId]->mRadioResponse->getMuteResponse(responseInfo, + enable); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getClipResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getClipResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse->getClipResponse(responseInfo, + (ClipStatus) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getClipResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getDataCallListResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getDataCallListResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec ret; + if ((response == NULL && responseLen != 0) + || (responseLen % sizeof(RIL_Data_Call_Response_v11) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v9) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v6) != 0)) { + RLOGE("getDataCallListResponse: invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilDataCallListToHal(response, responseLen, ret); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getDataCallListResponse( + responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getDataCallListResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setSuppServiceNotificationsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setSuppServiceNotificationsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setSuppServiceNotificationsResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setSuppServiceNotificationsResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::deleteSmsOnSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("deleteSmsOnSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->deleteSmsOnSimResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("deleteSmsOnSimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setBandModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setBandModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setBandModeResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setBandModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::writeSmsToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("writeSmsToSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->writeSmsToSimResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("writeSmsToSimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getAvailableBandModesResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getAvailableBandModesResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec modes; + if ((response == NULL && responseLen != 0)|| responseLen % sizeof(int) != 0) { + RLOGE("getAvailableBandModesResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + int numInts = responseLen / sizeof(int); + modes.resize(numInts); + for (int i = 0; i < numInts; i++) { + modes[i] = (RadioBandMode) pInt[i]; + } + } + Return retStatus + = radioService[slotId]->mRadioResponse->getAvailableBandModesResponse(responseInfo, + modes); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getAvailableBandModesResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendEnvelopeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendEnvelopeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendEnvelopeResponse(responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendEnvelopeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendTerminalResponseToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendTerminalResponseToSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendTerminalResponseToSimResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendTerminalResponseToSimResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::handleStkCallSetupRequestFromSimResponse(int slotId, + int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("handleStkCallSetupRequestFromSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->handleStkCallSetupRequestFromSimResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("handleStkCallSetupRequestFromSimResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::explicitCallTransferResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("explicitCallTransferResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->explicitCallTransferResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("explicitCallTransferResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setPreferredNetworkTypeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setPreferredNetworkTypeResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + + +int radio::getPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getPreferredNetworkTypeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getPreferredNetworkTypeResponse( + responseInfo, (PreferredNetworkType) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getNeighboringCidsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getNeighboringCidsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec cells; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_NeighboringCell *) != 0) { + RLOGE("getNeighboringCidsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_NeighboringCell *); + cells.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_NeighboringCell *resp = ((RIL_NeighboringCell **) response)[i]; + cells[i].cid = convertCharPtrToHidlString(resp->cid); + cells[i].rssi = resp->rssi; + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getNeighboringCidsResponse(responseInfo, + cells); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getNeighboringCidsResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setLocationUpdatesResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setLocationUpdatesResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setLocationUpdatesResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setLocationUpdatesResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaSubscriptionSourceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaSubscriptionSourceResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaRoamingPreferenceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaRoamingPreferenceResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCdmaRoamingPreferenceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getCdmaRoamingPreferenceResponse( + responseInfo, (CdmaRoamingType) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setTTYModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setTTYModeResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getTTYModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getTTYModeResponse(responseInfo, + (TtyMode) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setPreferredVoicePrivacyResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setPreferredVoicePrivacyResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getPreferredVoicePrivacyResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool enable = false; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 1) { + RLOGE("getPreferredVoicePrivacyResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + enable = pInt[0] == 1 ? true : false; + } + Return retStatus + = radioService[slotId]->mRadioResponse->getPreferredVoicePrivacyResponse( + responseInfo, enable); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendCDMAFeatureCodeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendCDMAFeatureCodeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendCDMAFeatureCodeResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendCDMAFeatureCodeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendBurstDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendBurstDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendBurstDtmfResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendBurstDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendCdmaSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->sendCdmaSmsResponse(responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendCdmaSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::acknowledgeLastIncomingCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acknowledgeLastIncomingCdmaSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->acknowledgeLastIncomingCdmaSmsResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeLastIncomingCdmaSmsResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::getGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getGsmBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec configs; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) { + RLOGE("getGsmBroadcastConfigResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *); + configs.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_GSM_BroadcastSmsConfigInfo *resp = + ((RIL_GSM_BroadcastSmsConfigInfo **) response)[i]; + configs[i].fromServiceId = resp->fromServiceId; + configs[i].toServiceId = resp->toServiceId; + configs[i].fromCodeScheme = resp->fromCodeScheme; + configs[i].toCodeScheme = resp->toCodeScheme; + configs[i].selected = resp->selected == 1 ? true : false; + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getGsmBroadcastConfigResponse(responseInfo, + configs); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setGsmBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setGsmBroadcastConfigResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setGsmBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setGsmBroadcastActivationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setGsmBroadcastActivationResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setGsmBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCdmaBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec configs; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) { + RLOGE("getCdmaBroadcastConfigResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_CDMA_BroadcastSmsConfigInfo *); + configs.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_CDMA_BroadcastSmsConfigInfo *resp = + ((RIL_CDMA_BroadcastSmsConfigInfo **) response)[i]; + configs[i].serviceCategory = resp->service_category; + configs[i].language = resp->language; + configs[i].selected = resp->selected == 1 ? true : false; + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getCdmaBroadcastConfigResponse(responseInfo, + configs); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaBroadcastConfigResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaBroadcastActivationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaBroadcastActivationResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCDMASubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getCDMASubscriptionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + int numStrings = responseLen / sizeof(char *); + hidl_string emptyString; + if (response == NULL || numStrings != 5) { + RLOGE("getOperatorResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + Return retStatus + = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse( + responseInfo, emptyString, emptyString, emptyString, emptyString, emptyString); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + char **resp = (char **) response; + Return retStatus + = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse( + responseInfo, + convertCharPtrToHidlString(resp[0]), + convertCharPtrToHidlString(resp[1]), + convertCharPtrToHidlString(resp[2]), + convertCharPtrToHidlString(resp[3]), + convertCharPtrToHidlString(resp[4])); + radioService[slotId]->checkReturnStatus(retStatus); + } + } else { + RLOGE("getCDMASubscriptionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::writeSmsToRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("writeSmsToRuimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->writeSmsToRuimResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("writeSmsToRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::deleteSmsOnRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("deleteSmsOnRuimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->deleteSmsOnRuimResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("deleteSmsOnRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getDeviceIdentityResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getDeviceIdentityResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + int numStrings = responseLen / sizeof(char *); + hidl_string emptyString; + if (response == NULL || numStrings != 4) { + RLOGE("getDeviceIdentityResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + Return retStatus + = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo, + emptyString, emptyString, emptyString, emptyString); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + char **resp = (char **) response; + Return retStatus + = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo, + convertCharPtrToHidlString(resp[0]), + convertCharPtrToHidlString(resp[1]), + convertCharPtrToHidlString(resp[2]), + convertCharPtrToHidlString(resp[3])); + radioService[slotId]->checkReturnStatus(retStatus); + } + } else { + RLOGE("getDeviceIdentityResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::exitEmergencyCallbackModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("exitEmergencyCallbackModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->exitEmergencyCallbackModeResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("exitEmergencyCallbackModeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getSmscAddressResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->getSmscAddressResponse(responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setSmscAddressResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setSmscAddressResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::reportSmsMemoryStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("reportSmsMemoryStatusResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->reportSmsMemoryStatusResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("reportSmsMemoryStatusResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::reportStkServiceIsRunningResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("reportStkServiceIsRunningResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse-> + reportStkServiceIsRunningResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("reportStkServiceIsRunningResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCdmaSubscriptionSourceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getCdmaSubscriptionSourceResponse( + responseInfo, (CdmaSubscriptionSource) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::requestIsimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("requestIsimAuthenticationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->requestIsimAuthenticationResponse( + responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("requestIsimAuthenticationResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::acknowledgeIncomingGsmSmsWithPduResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("acknowledgeIncomingGsmSmsWithPduResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->acknowledgeIncomingGsmSmsWithPduResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeIncomingGsmSmsWithPduResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::sendEnvelopeWithStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendEnvelopeWithStatusResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, + response, responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->sendEnvelopeWithStatusResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendEnvelopeWithStatusResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getVoiceRadioTechnologyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getVoiceRadioTechnologyResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getVoiceRadioTechnologyResponse( + responseInfo, (RadioTechnology) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getVoiceRadioTechnologyResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCellInfoListResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getCellInfoListResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec ret; + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_CellInfo_v12) != 0) { + RLOGE("getCellInfoListResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilCellInfoListToHal(response, responseLen, ret); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getCellInfoListResponse( + responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCellInfoListResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setCellInfoListRateResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setCellInfoListRateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCellInfoListRateResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCellInfoListRateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setInitialAttachApnResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setInitialAttachApnResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getImsRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getImsRegistrationStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool isRegistered = false; + int ratFamily = 0; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 2) { + RLOGE("getImsRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + isRegistered = pInt[0] == 1 ? true : false; + ratFamily = pInt[1]; + } + Return retStatus + = radioService[slotId]->mRadioResponse->getImsRegistrationStateResponse( + responseInfo, isRegistered, (RadioTechnologyFamily) ratFamily); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getImsRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendImsSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendImsSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->sendImsSmsResponse(responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::iccTransmitApduBasicChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("iccTransmitApduBasicChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->iccTransmitApduBasicChannelResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccTransmitApduBasicChannelResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::iccOpenLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("iccOpenLogicalChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + int channelId = -1; + hidl_vec selectResponse; + int numInts = responseLen / sizeof(int); + if (response == NULL || responseLen % sizeof(int) != 0) { + RLOGE("iccOpenLogicalChannelResponse Invalid response: NULL"); + if (response != NULL) { + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } + } else { + int *pInt = (int *) response; + channelId = pInt[0]; + selectResponse.resize(numInts - 1); + for (int i = 1; i < numInts; i++) { + selectResponse[i - 1] = (int8_t) pInt[i]; + } + } + Return retStatus + = radioService[slotId]->mRadioResponse->iccOpenLogicalChannelResponse(responseInfo, + channelId, selectResponse); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccOpenLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::iccCloseLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("iccCloseLogicalChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->iccCloseLogicalChannelResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccCloseLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::iccTransmitApduLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("iccTransmitApduLogicalChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->iccTransmitApduLogicalChannelResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccTransmitApduLogicalChannelResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::nvReadItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvReadItemResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->nvReadItemResponse( + responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvReadItemResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::nvWriteItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvWriteItemResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->nvWriteItemResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvWriteItemResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::nvWriteCdmaPrlResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvWriteCdmaPrlResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->nvWriteCdmaPrlResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvWriteCdmaPrlResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::nvResetConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvResetConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->nvResetConfigResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvResetConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setUiccSubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setUiccSubscriptionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setUiccSubscriptionResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setUiccSubscriptionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setDataAllowedResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setDataAllowedResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setDataAllowedResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setDataAllowedResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getHardwareConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getHardwareConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec result; + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_HardwareConfig) != 0) { + RLOGE("hardwareConfigChangedInd: invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilHardwareConfigListToHal(response, responseLen, result); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getHardwareConfigResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getHardwareConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::requestIccSimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("requestIccSimAuthenticationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->requestIccSimAuthenticationResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("requestIccSimAuthenticationResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::setDataProfileResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setDataProfileResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setDataProfileResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::requestShutdownResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("requestShutdownResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->requestShutdownResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("requestShutdownResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +void responseRadioCapability(RadioResponseInfo& responseInfo, int serial, + int responseType, RIL_Errno e, void *response, size_t responseLen, RadioCapability& rc) { + populateResponseInfo(responseInfo, serial, responseType, e); + + if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) { + RLOGE("responseRadioCapability: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + rc.logicalModemUuid = hidl_string(); + } else { + convertRilRadioCapabilityToHal(response, responseLen, rc); + } +} + +int radio::getRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getRadioCapabilityResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + RadioCapability result = {}; + responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen, + result); + Return retStatus = radioService[slotId]->mRadioResponse->getRadioCapabilityResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setRadioCapabilityResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + RadioCapability result = {}; + responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen, + result); + Return retStatus = radioService[slotId]->mRadioResponse->setRadioCapabilityResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +LceStatusInfo responseLceStatusInfo(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e, void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + LceStatusInfo result = {}; + + if (response == NULL || responseLen != sizeof(RIL_LceStatusInfo)) { + RLOGE("Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_LceStatusInfo *resp = (RIL_LceStatusInfo *) response; + result.lceStatus = (LceStatus) resp->lce_status; + result.actualIntervalMs = (uint8_t) resp->actual_interval_ms; + } + return result; +} + +int radio::startLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("startLceServiceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e, + response, responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->startLceServiceResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("startLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::stopLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("stopLceServiceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e, + response, responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->stopLceServiceResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stopLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::pullLceDataResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("pullLceDataResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + LceDataInfo result = {}; + if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) { + RLOGE("pullLceDataResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilLceDataInfoToHal(response, responseLen, result); + } + + Return retStatus = radioService[slotId]->mRadioResponse->pullLceDataResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("pullLceDataResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getModemActivityInfoResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getModemActivityInfoResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + ActivityStatsInfo info; + if (response == NULL || responseLen != sizeof(RIL_ActivityStatsInfo)) { + RLOGE("getModemActivityInfoResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_ActivityStatsInfo *resp = (RIL_ActivityStatsInfo *)response; + info.sleepModeTimeMs = resp->sleep_mode_time_ms; + info.idleModeTimeMs = resp->idle_mode_time_ms; + for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) { + info.txmModetimeMs[i] = resp->tx_mode_time_ms[i]; + } + info.rxModeTimeMs = resp->rx_mode_time_ms; + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getModemActivityInfoResponse(responseInfo, + info); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getModemActivityInfoResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setAllowedCarriersResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->setAllowedCarriersResponse(responseInfo, + ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getAllowedCarriersResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + CarrierRestrictions carrierInfo = {}; + bool allAllowed = true; + if (response == NULL) { +#if VDBG + RLOGD("getAllowedCarriersResponse response is NULL: all allowed"); +#endif + carrierInfo.allowedCarriers.resize(0); + carrierInfo.excludedCarriers.resize(0); + } else if (responseLen != sizeof(RIL_CarrierRestrictions)) { + RLOGE("getAllowedCarriersResponse Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_CarrierRestrictions *pCr = (RIL_CarrierRestrictions *)response; + if (pCr->len_allowed_carriers > 0 || pCr->len_excluded_carriers > 0) { + allAllowed = false; + } + + carrierInfo.allowedCarriers.resize(pCr->len_allowed_carriers); + for(int i = 0; i < pCr->len_allowed_carriers; i++) { + RIL_Carrier *carrier = pCr->allowed_carriers + i; + carrierInfo.allowedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc); + carrierInfo.allowedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc); + carrierInfo.allowedCarriers[i].matchType = (CarrierMatchType) carrier->match_type; + carrierInfo.allowedCarriers[i].matchData = + convertCharPtrToHidlString(carrier->match_data); + } + + carrierInfo.excludedCarriers.resize(pCr->len_excluded_carriers); + for(int i = 0; i < pCr->len_excluded_carriers; i++) { + RIL_Carrier *carrier = pCr->excluded_carriers + i; + carrierInfo.excludedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc); + carrierInfo.excludedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc); + carrierInfo.excludedCarriers[i].matchType = (CarrierMatchType) carrier->match_type; + carrierInfo.excludedCarriers[i].matchData = + convertCharPtrToHidlString(carrier->match_data); + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getAllowedCarriersResponse(responseInfo, + allAllowed, carrierInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendDeviceStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen) { +#if VDBG + RLOGD("sendDeviceStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendDeviceStateResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendDeviceStateResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setIndicationFilterResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen) { +#if VDBG + RLOGD("setIndicationFilterResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setIndicationFilterResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + + +int radio::setSimCardPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setSimCardPowerResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setSimCardPowerResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setSimCardPowerResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendRequestRawResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendRequestRawResponse: serial %d", serial); +#endif + + if (oemHookService[slotId]->mOemHookResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec data; + + if (response == NULL) { + RLOGE("sendRequestRawResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + data.setToExternal((uint8_t *) response, responseLen); + } + Return retStatus = oemHookService[slotId]->mOemHookResponse-> + sendRequestRawResponse(responseInfo, data); + checkReturnStatus(slotId, retStatus, false); + } else { + RLOGE("sendRequestRawResponse: oemHookService[%d]->mOemHookResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendRequestStringsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendRequestStringsResponse: serial %d", serial); +#endif + + if (oemHookService[slotId]->mOemHookResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec data; + + if ((response == NULL && responseLen != 0) || responseLen % sizeof(char *) != 0) { + RLOGE("sendRequestStringsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + int numStrings = responseLen / sizeof(char *); + data.resize(numStrings); + for (int i = 0; i < numStrings; i++) { + data[i] = convertCharPtrToHidlString(resp[i]); + } + } + Return retStatus + = oemHookService[slotId]->mOemHookResponse->sendRequestStringsResponse( + responseInfo, data); + checkReturnStatus(slotId, retStatus, false); + } else { + RLOGE("sendRequestStringsResponse: oemHookService[%d]->mOemHookResponse == " + "NULL", slotId); + } + + return 0; +} + +// Radio Indication functions + +RadioIndicationType convertIntToRadioIndicationType(int indicationType) { + return indicationType == RESPONSE_UNSOLICITED ? (RadioIndicationType::UNSOLICITED) : + (RadioIndicationType::UNSOLICITED_ACK_EXP); +} + +int radio::radioStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + RadioState radioState = + (RadioState) CALL_ONSTATEREQUEST(slotId); + RLOGD("radioStateChangedInd: radioState %d", radioState); + Return retStatus = radioService[slotId]->mRadioIndication->radioStateChanged( + convertIntToRadioIndicationType(indicationType), radioState); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("radioStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::callStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("callStateChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->callStateChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("callStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::networkStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("networkStateChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->networkStateChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("networkStateChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +uint8_t hexCharToInt(uint8_t c) { + if (c >= '0' && c <= '9') return (c - '0'); + if (c >= 'A' && c <= 'F') return (c - 'A' + 10); + if (c >= 'a' && c <= 'f') return (c - 'a' + 10); + + return INVALID_HEX_CHAR; +} + +uint8_t * convertHexStringToBytes(void *response, size_t responseLen) { + if (responseLen % 2 != 0) { + return NULL; + } + + uint8_t *bytes = (uint8_t *)calloc(responseLen/2, sizeof(uint8_t)); + if (bytes == NULL) { + RLOGE("convertHexStringToBytes: cannot allocate memory for bytes string"); + return NULL; + } + uint8_t *hexString = (uint8_t *)response; + + for (size_t i = 0; i < responseLen; i += 2) { + uint8_t hexChar1 = hexCharToInt(hexString[i]); + uint8_t hexChar2 = hexCharToInt(hexString[i + 1]); + + if (hexChar1 == INVALID_HEX_CHAR || hexChar2 == INVALID_HEX_CHAR) { + RLOGE("convertHexStringToBytes: invalid hex char %d %d", + hexString[i], hexString[i + 1]); + free(bytes); + return NULL; + } + bytes[i/2] = ((hexChar1 << 4) | hexChar2); + } + + return bytes; +} + +int radio::newSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("newSmsInd: invalid response"); + return 0; + } + + uint8_t *bytes = convertHexStringToBytes(response, responseLen); + if (bytes == NULL) { + RLOGE("newSmsInd: convertHexStringToBytes failed"); + return 0; + } + + hidl_vec pdu; + pdu.setToExternal(bytes, responseLen/2); +#if VDBG + RLOGD("newSmsInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newSms( + convertIntToRadioIndicationType(indicationType), pdu); + radioService[slotId]->checkReturnStatus(retStatus); + free(bytes); + } else { + RLOGE("newSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::newSmsStatusReportInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("newSmsStatusReportInd: invalid response"); + return 0; + } + + uint8_t *bytes = convertHexStringToBytes(response, responseLen); + if (bytes == NULL) { + RLOGE("newSmsStatusReportInd: convertHexStringToBytes failed"); + return 0; + } + + hidl_vec pdu; + pdu.setToExternal(bytes, responseLen/2); +#if VDBG + RLOGD("newSmsStatusReportInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newSmsStatusReport( + convertIntToRadioIndicationType(indicationType), pdu); + radioService[slotId]->checkReturnStatus(retStatus); + free(bytes); + } else { + RLOGE("newSmsStatusReportInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::newSmsOnSimInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("newSmsOnSimInd: invalid response"); + return 0; + } + int32_t recordNumber = ((int32_t *) response)[0]; +#if VDBG + RLOGD("newSmsOnSimInd: slotIndex %d", recordNumber); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newSmsOnSim( + convertIntToRadioIndicationType(indicationType), recordNumber); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("newSmsOnSimInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::onUssdInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != 2 * sizeof(char *)) { + RLOGE("onUssdInd: invalid response"); + return 0; + } + char **strings = (char **) response; + char *mode = strings[0]; + hidl_string msg = convertCharPtrToHidlString(strings[1]); + UssdModeType modeType = (UssdModeType) atoi(mode); +#if VDBG + RLOGD("onUssdInd: mode %s", mode); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->onUssd( + convertIntToRadioIndicationType(indicationType), modeType, msg); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("onUssdInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::nitzTimeReceivedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("nitzTimeReceivedInd: invalid response"); + return 0; + } + hidl_string nitzTime = convertCharPtrToHidlString((char *) response); + int64_t timeReceived = android::elapsedRealtime(); +#if VDBG + RLOGD("nitzTimeReceivedInd: nitzTime %s receivedTime %" PRId64, nitzTime.c_str(), + timeReceived); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->nitzTimeReceived( + convertIntToRadioIndicationType(indicationType), nitzTime, timeReceived); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nitzTimeReceivedInd: radioService[%d]->mRadioIndication == NULL", slotId); + return -1; + } + + return 0; +} + +void convertRilSignalStrengthToHalV8(void *response, size_t responseLen, + SignalStrength& signalStrength) { + RIL_SignalStrength_v8 *rilSignalStrength = (RIL_SignalStrength_v8 *) response; + + // Fixup LTE for backwards compatibility + // signalStrength: -1 -> 99 + if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) { + rilSignalStrength->LTE_SignalStrength.signalStrength = 99; + } + // rsrp: -1 -> INT_MAX all other negative value to positive. + // So remap here + if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX; + } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp; + } + // rsrq: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) { + rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX; + } + // Not remapping rssnr is already using INT_MAX + // cqi: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.cqi == -1) { + rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX; + } + + signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength; + signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate; + signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm; + signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio; + signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm; + signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio; + signalStrength.evdo.signalNoiseRatio = + rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio; + signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength; + signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp; + signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq; + signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr; + signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi; + signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance; + signalStrength.tdScdma.rscp = INT_MAX; +} + +void convertRilSignalStrengthToHalV10(void *response, size_t responseLen, + SignalStrength& signalStrength) { + RIL_SignalStrength_v10 *rilSignalStrength = (RIL_SignalStrength_v10 *) response; + + // Fixup LTE for backwards compatibility + // signalStrength: -1 -> 99 + if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) { + rilSignalStrength->LTE_SignalStrength.signalStrength = 99; + } + // rsrp: -1 -> INT_MAX all other negative value to positive. + // So remap here + if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX; + } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp; + } + // rsrq: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) { + rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX; + } + // Not remapping rssnr is already using INT_MAX + // cqi: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.cqi == -1) { + rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX; + } + + signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength; + signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate; + signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm; + signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio; + signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm; + signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio; + signalStrength.evdo.signalNoiseRatio = + rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio; + signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength; + signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp; + signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq; + signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr; + signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi; + signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance; + signalStrength.tdScdma.rscp = rilSignalStrength->TD_SCDMA_SignalStrength.rscp; +} + +void convertRilSignalStrengthToHal(void *response, size_t responseLen, + SignalStrength& signalStrength) { + if (responseLen == sizeof(RIL_SignalStrength_v8)) { + convertRilSignalStrengthToHalV8(response, responseLen, signalStrength); + } else { + convertRilSignalStrengthToHalV10(response, responseLen, signalStrength); + } +} + +int radio::currentSignalStrengthInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || (responseLen != sizeof(RIL_SignalStrength_v10) + && responseLen != sizeof(RIL_SignalStrength_v8))) { + RLOGE("currentSignalStrengthInd: invalid response"); + return 0; + } + + SignalStrength signalStrength = {}; + convertRilSignalStrengthToHal(response, responseLen, signalStrength); + +#if VDBG + RLOGD("currentSignalStrengthInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->currentSignalStrength( + convertIntToRadioIndicationType(indicationType), signalStrength); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("currentSignalStrengthInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilDataCallToHal(RIL_Data_Call_Response_v6 *dcResponse, + SetupDataCallResult& dcResult) { + dcResult.status = (DataCallFailCause) dcResponse->status; + dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; + dcResult.cid = dcResponse->cid; + dcResult.active = dcResponse->active; + dcResult.type = convertCharPtrToHidlString(dcResponse->type); + dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); + dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); + dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); + dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); + dcResult.pcscf = hidl_string(); + dcResult.mtu = 0; +} + +void convertRilDataCallToHal(RIL_Data_Call_Response_v9 *dcResponse, + SetupDataCallResult& dcResult) { + dcResult.status = (DataCallFailCause) dcResponse->status; + dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; + dcResult.cid = dcResponse->cid; + dcResult.active = dcResponse->active; + dcResult.type = convertCharPtrToHidlString(dcResponse->type); + dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); + dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); + dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); + dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); + dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf); + dcResult.mtu = 0; +} + +void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, + SetupDataCallResult& dcResult) { + dcResult.status = (DataCallFailCause) dcResponse->status; + dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; + dcResult.cid = dcResponse->cid; + dcResult.active = dcResponse->active; + dcResult.type = convertCharPtrToHidlString(dcResponse->type); + dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); + dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); + dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); + dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); + dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf); + dcResult.mtu = dcResponse->mtu; +} + +void convertRilDataCallListToHal(void *response, size_t responseLen, + hidl_vec& dcResultList) { + int num; + + if ((responseLen % sizeof(RIL_Data_Call_Response_v11)) == 0) { + num = responseLen / sizeof(RIL_Data_Call_Response_v11); + RIL_Data_Call_Response_v11 *dcResponse = (RIL_Data_Call_Response_v11 *) response; + dcResultList.resize(num); + for (int i = 0; i < num; i++) { + convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); + } + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v9)) == 0) { + num = responseLen / sizeof(RIL_Data_Call_Response_v9); + RIL_Data_Call_Response_v9 *dcResponse = (RIL_Data_Call_Response_v9 *) response; + dcResultList.resize(num); + for (int i = 0; i < num; i++) { + convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); + } + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v6)) == 0) { + num = responseLen / sizeof(RIL_Data_Call_Response_v6); + RIL_Data_Call_Response_v6 *dcResponse = (RIL_Data_Call_Response_v6 *) response; + dcResultList.resize(num); + for (int i = 0; i < num; i++) { + convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); + } + } +} + +int radio::dataCallListChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if ((response == NULL && responseLen != 0) + || (responseLen % sizeof(RIL_Data_Call_Response_v11) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v9) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v6) != 0)) { + RLOGE("dataCallListChangedInd: invalid response"); + return 0; + } + hidl_vec dcList; + convertRilDataCallListToHal(response, responseLen, dcList); +#if VDBG + RLOGD("dataCallListChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->dataCallListChanged( + convertIntToRadioIndicationType(indicationType), dcList); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("dataCallListChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::suppSvcNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_SuppSvcNotification)) { + RLOGE("suppSvcNotifyInd: invalid response"); + return 0; + } + + SuppSvcNotification suppSvc = {}; + RIL_SuppSvcNotification *ssn = (RIL_SuppSvcNotification *) response; + suppSvc.isMT = ssn->notificationType; + suppSvc.code = ssn->code; + suppSvc.index = ssn->index; + suppSvc.type = ssn->type; + suppSvc.number = convertCharPtrToHidlString(ssn->number); + +#if VDBG + RLOGD("suppSvcNotifyInd: isMT %d code %d index %d type %d", + suppSvc.isMT, suppSvc.code, suppSvc.index, suppSvc.type); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->suppSvcNotify( + convertIntToRadioIndicationType(indicationType), suppSvc); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("suppSvcNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkSessionEndInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("stkSessionEndInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkSessionEnd( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkSessionEndInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkProactiveCommandInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("stkProactiveCommandInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("stkProactiveCommandInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkProactiveCommand( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkProactiveCommandInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkEventNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("stkEventNotifyInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("stkEventNotifyInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkEventNotify( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkEventNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkCallSetupInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("stkCallSetupInd: invalid response"); + return 0; + } + int32_t timeout = ((int32_t *) response)[0]; +#if VDBG + RLOGD("stkCallSetupInd: timeout %d", timeout); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkCallSetup( + convertIntToRadioIndicationType(indicationType), timeout); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkCallSetupInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::simSmsStorageFullInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("simSmsStorageFullInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->simSmsStorageFull( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("simSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::simRefreshInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_SimRefreshResponse_v7)) { + RLOGE("simRefreshInd: invalid response"); + return 0; + } + + SimRefreshResult refreshResult = {}; + RIL_SimRefreshResponse_v7 *simRefreshResponse = ((RIL_SimRefreshResponse_v7 *) response); + refreshResult.type = + (android::hardware::radio::V1_0::SimRefreshType) simRefreshResponse->result; + refreshResult.efId = simRefreshResponse->ef_id; + refreshResult.aid = convertCharPtrToHidlString(simRefreshResponse->aid); + +#if VDBG + RLOGD("simRefreshInd: type %d efId %d", refreshResult.type, refreshResult.efId); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->simRefresh( + convertIntToRadioIndicationType(indicationType), refreshResult); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("simRefreshInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +void convertRilCdmaSignalInfoRecordToHal(RIL_CDMA_SignalInfoRecord *signalInfoRecord, + CdmaSignalInfoRecord& record) { + record.isPresent = signalInfoRecord->isPresent; + record.signalType = signalInfoRecord->signalType; + record.alertPitch = signalInfoRecord->alertPitch; + record.signal = signalInfoRecord->signal; +} + +int radio::callRingInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + bool isGsm; + CdmaSignalInfoRecord record = {}; + if (response == NULL || responseLen == 0) { + isGsm = true; + } else { + isGsm = false; + if (responseLen != sizeof (RIL_CDMA_SignalInfoRecord)) { + RLOGE("callRingInd: invalid response"); + return 0; + } + convertRilCdmaSignalInfoRecordToHal((RIL_CDMA_SignalInfoRecord *) response, record); + } + +#if VDBG + RLOGD("callRingInd: isGsm %d", isGsm); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->callRing( + convertIntToRadioIndicationType(indicationType), isGsm, record); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("callRingInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::simStatusChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("simStatusChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->simStatusChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("simStatusChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaNewSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_CDMA_SMS_Message)) { + RLOGE("cdmaNewSmsInd: invalid response"); + return 0; + } + + CdmaSmsMessage msg = {}; + RIL_CDMA_SMS_Message *rilMsg = (RIL_CDMA_SMS_Message *) response; + msg.teleserviceId = rilMsg->uTeleserviceID; + msg.isServicePresent = rilMsg->bIsServicePresent; + msg.serviceCategory = rilMsg->uServicecategory; + msg.address.digitMode = + (android::hardware::radio::V1_0::CdmaSmsDigitMode) rilMsg->sAddress.digit_mode; + msg.address.numberMode = + (android::hardware::radio::V1_0::CdmaSmsNumberMode) rilMsg->sAddress.number_mode; + msg.address.numberType = + (android::hardware::radio::V1_0::CdmaSmsNumberType) rilMsg->sAddress.number_type; + msg.address.numberPlan = + (android::hardware::radio::V1_0::CdmaSmsNumberPlan) rilMsg->sAddress.number_plan; + + int digitLimit = MIN((rilMsg->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); + msg.address.digits.setToExternal(rilMsg->sAddress.digits, digitLimit); + + msg.subAddress.subaddressType = (android::hardware::radio::V1_0::CdmaSmsSubaddressType) + rilMsg->sSubAddress.subaddressType; + msg.subAddress.odd = rilMsg->sSubAddress.odd; + + digitLimit= MIN((rilMsg->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); + msg.subAddress.digits.setToExternal(rilMsg->sSubAddress.digits, digitLimit); + + digitLimit = MIN((rilMsg->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); + msg.bearerData.setToExternal(rilMsg->aBearerData, digitLimit); + +#if VDBG + RLOGD("cdmaNewSmsInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaNewSms( + convertIntToRadioIndicationType(indicationType), msg); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaNewSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::newBroadcastSmsInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("newBroadcastSmsInd: invalid response"); + return 0; + } + + hidl_vec data; + data.setToExternal((uint8_t *) response, responseLen); +#if VDBG + RLOGD("newBroadcastSmsInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newBroadcastSms( + convertIntToRadioIndicationType(indicationType), data); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("newBroadcastSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaRuimSmsStorageFullInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("cdmaRuimSmsStorageFullInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaRuimSmsStorageFull( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaRuimSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::restrictedStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("restrictedStateChangedInd: invalid response"); + return 0; + } + int32_t state = ((int32_t *) response)[0]; +#if VDBG + RLOGD("restrictedStateChangedInd: state %d", state); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->restrictedStateChanged( + convertIntToRadioIndicationType(indicationType), (PhoneRestrictedState) state); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("restrictedStateChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::enterEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("enterEmergencyCallbackModeInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->enterEmergencyCallbackMode( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("enterEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::cdmaCallWaitingInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_CDMA_CallWaiting_v6)) { + RLOGE("cdmaCallWaitingInd: invalid response"); + return 0; + } + + CdmaCallWaiting callWaitingRecord = {}; + RIL_CDMA_CallWaiting_v6 *callWaitingRil = ((RIL_CDMA_CallWaiting_v6 *) response); + callWaitingRecord.number = convertCharPtrToHidlString(callWaitingRil->number); + callWaitingRecord.numberPresentation = + (CdmaCallWaitingNumberPresentation) callWaitingRil->numberPresentation; + callWaitingRecord.name = convertCharPtrToHidlString(callWaitingRil->name); + convertRilCdmaSignalInfoRecordToHal(&callWaitingRil->signalInfoRecord, + callWaitingRecord.signalInfoRecord); + callWaitingRecord.numberType = (CdmaCallWaitingNumberType) callWaitingRil->number_type; + callWaitingRecord.numberPlan = (CdmaCallWaitingNumberPlan) callWaitingRil->number_plan; + +#if VDBG + RLOGD("cdmaCallWaitingInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaCallWaiting( + convertIntToRadioIndicationType(indicationType), callWaitingRecord); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaCallWaitingInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaOtaProvisionStatusInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("cdmaOtaProvisionStatusInd: invalid response"); + return 0; + } + int32_t status = ((int32_t *) response)[0]; +#if VDBG + RLOGD("cdmaOtaProvisionStatusInd: status %d", status); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaOtaProvisionStatus( + convertIntToRadioIndicationType(indicationType), (CdmaOtaProvisionStatus) status); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaOtaProvisionStatusInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::cdmaInfoRecInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_CDMA_InformationRecords)) { + RLOGE("cdmaInfoRecInd: invalid response"); + return 0; + } + + CdmaInformationRecords records = {}; + RIL_CDMA_InformationRecords *recordsRil = (RIL_CDMA_InformationRecords *) response; + + char* string8 = NULL; + int num = MIN(recordsRil->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); + if (recordsRil->numberOfInfoRecs > RIL_CDMA_MAX_NUMBER_OF_INFO_RECS) { + RLOGE("cdmaInfoRecInd: received %d recs which is more than %d, dropping " + "additional ones", recordsRil->numberOfInfoRecs, + RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); + } + records.infoRec.resize(num); + for (int i = 0 ; i < num ; i++) { + CdmaInformationRecord *record = &records.infoRec[i]; + RIL_CDMA_InformationRecord *infoRec = &recordsRil->infoRec[i]; + record->name = (CdmaInfoRecName) infoRec->name; + // All vectors should be size 0 except one which will be size 1. Set everything to + // size 0 initially. + record->display.resize(0); + record->number.resize(0); + record->signal.resize(0); + record->redir.resize(0); + record->lineCtrl.resize(0); + record->clir.resize(0); + record->audioCtrl.resize(0); + switch (infoRec->name) { + case RIL_CDMA_DISPLAY_INFO_REC: + case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: { + if (infoRec->rec.display.alpha_len > CDMA_ALPHA_INFO_BUFFER_LENGTH) { + RLOGE("cdmaInfoRecInd: invalid display info response length %d " + "expected not more than %d", (int) infoRec->rec.display.alpha_len, + CDMA_ALPHA_INFO_BUFFER_LENGTH); + return 0; + } + string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1) * sizeof(char)); + if (string8 == NULL) { + RLOGE("cdmaInfoRecInd: Memory allocation failed for " + "responseCdmaInformationRecords"); + return 0; + } + memcpy(string8, infoRec->rec.display.alpha_buf, infoRec->rec.display.alpha_len); + string8[(int)infoRec->rec.display.alpha_len] = '\0'; + + record->display.resize(1); + record->display[0].alphaBuf = string8; + free(string8); + string8 = NULL; + break; + } + + case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: + case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: + case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: { + if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) { + RLOGE("cdmaInfoRecInd: invalid display info response length %d " + "expected not more than %d", (int) infoRec->rec.number.len, + CDMA_NUMBER_INFO_BUFFER_LENGTH); + return 0; + } + string8 = (char*) malloc((infoRec->rec.number.len + 1) * sizeof(char)); + if (string8 == NULL) { + RLOGE("cdmaInfoRecInd: Memory allocation failed for " + "responseCdmaInformationRecords"); + return 0; + } + memcpy(string8, infoRec->rec.number.buf, infoRec->rec.number.len); + string8[(int)infoRec->rec.number.len] = '\0'; + + record->number.resize(1); + record->number[0].number = string8; + free(string8); + string8 = NULL; + record->number[0].numberType = infoRec->rec.number.number_type; + record->number[0].numberPlan = infoRec->rec.number.number_plan; + record->number[0].pi = infoRec->rec.number.pi; + record->number[0].si = infoRec->rec.number.si; + break; + } + + case RIL_CDMA_SIGNAL_INFO_REC: { + record->signal.resize(1); + record->signal[0].isPresent = infoRec->rec.signal.isPresent; + record->signal[0].signalType = infoRec->rec.signal.signalType; + record->signal[0].alertPitch = infoRec->rec.signal.alertPitch; + record->signal[0].signal = infoRec->rec.signal.signal; + break; + } + + case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: { + if (infoRec->rec.redir.redirectingNumber.len > + CDMA_NUMBER_INFO_BUFFER_LENGTH) { + RLOGE("cdmaInfoRecInd: invalid display info response length %d " + "expected not more than %d\n", + (int)infoRec->rec.redir.redirectingNumber.len, + CDMA_NUMBER_INFO_BUFFER_LENGTH); + return 0; + } + string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber.len + 1) * + sizeof(char)); + if (string8 == NULL) { + RLOGE("cdmaInfoRecInd: Memory allocation failed for " + "responseCdmaInformationRecords"); + return 0; + } + memcpy(string8, infoRec->rec.redir.redirectingNumber.buf, + infoRec->rec.redir.redirectingNumber.len); + string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0'; + + record->redir.resize(1); + record->redir[0].redirectingNumber.number = string8; + free(string8); + string8 = NULL; + record->redir[0].redirectingNumber.numberType = + infoRec->rec.redir.redirectingNumber.number_type; + record->redir[0].redirectingNumber.numberPlan = + infoRec->rec.redir.redirectingNumber.number_plan; + record->redir[0].redirectingNumber.pi = infoRec->rec.redir.redirectingNumber.pi; + record->redir[0].redirectingNumber.si = infoRec->rec.redir.redirectingNumber.si; + record->redir[0].redirectingReason = + (CdmaRedirectingReason) infoRec->rec.redir.redirectingReason; + break; + } + + case RIL_CDMA_LINE_CONTROL_INFO_REC: { + record->lineCtrl.resize(1); + record->lineCtrl[0].lineCtrlPolarityIncluded = + infoRec->rec.lineCtrl.lineCtrlPolarityIncluded; + record->lineCtrl[0].lineCtrlToggle = infoRec->rec.lineCtrl.lineCtrlToggle; + record->lineCtrl[0].lineCtrlReverse = infoRec->rec.lineCtrl.lineCtrlReverse; + record->lineCtrl[0].lineCtrlPowerDenial = + infoRec->rec.lineCtrl.lineCtrlPowerDenial; + break; + } + + case RIL_CDMA_T53_CLIR_INFO_REC: { + record->clir.resize(1); + record->clir[0].cause = infoRec->rec.clir.cause; + break; + } + + case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: { + record->audioCtrl.resize(1); + record->audioCtrl[0].upLink = infoRec->rec.audioCtrl.upLink; + record->audioCtrl[0].downLink = infoRec->rec.audioCtrl.downLink; + break; + } + + case RIL_CDMA_T53_RELEASE_INFO_REC: + RLOGE("cdmaInfoRecInd: RIL_CDMA_T53_RELEASE_INFO_REC: INVALID"); + return 0; + + default: + RLOGE("cdmaInfoRecInd: Incorrect name value"); + return 0; + } + } + +#if VDBG + RLOGD("cdmaInfoRecInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaInfoRec( + convertIntToRadioIndicationType(indicationType), records); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaInfoRecInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::indicateRingbackToneInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("indicateRingbackToneInd: invalid response"); + return 0; + } + bool start = ((int32_t *) response)[0]; +#if VDBG + RLOGD("indicateRingbackToneInd: start %d", start); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->indicateRingbackTone( + convertIntToRadioIndicationType(indicationType), start); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("indicateRingbackToneInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::resendIncallMuteInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("resendIncallMuteInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->resendIncallMute( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("resendIncallMuteInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaSubscriptionSourceChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("cdmaSubscriptionSourceChangedInd: invalid response"); + return 0; + } + int32_t cdmaSource = ((int32_t *) response)[0]; +#if VDBG + RLOGD("cdmaSubscriptionSourceChangedInd: cdmaSource %d", cdmaSource); +#endif + Return retStatus = radioService[slotId]->mRadioIndication-> + cdmaSubscriptionSourceChanged(convertIntToRadioIndicationType(indicationType), + (CdmaSubscriptionSource) cdmaSource); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaSubscriptionSourceChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::cdmaPrlChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("cdmaPrlChangedInd: invalid response"); + return 0; + } + int32_t version = ((int32_t *) response)[0]; +#if VDBG + RLOGD("cdmaPrlChangedInd: version %d", version); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaPrlChanged( + convertIntToRadioIndicationType(indicationType), version); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaPrlChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::exitEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("exitEmergencyCallbackModeInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->exitEmergencyCallbackMode( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("exitEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::rilConnectedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + RLOGD("rilConnectedInd"); + Return retStatus = radioService[slotId]->mRadioIndication->rilConnected( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("rilConnectedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::voiceRadioTechChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("voiceRadioTechChangedInd: invalid response"); + return 0; + } + int32_t rat = ((int32_t *) response)[0]; +#if VDBG + RLOGD("voiceRadioTechChangedInd: rat %d", rat); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->voiceRadioTechChanged( + convertIntToRadioIndicationType(indicationType), (RadioTechnology) rat); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("voiceRadioTechChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec& records) { + int num = responseLen / sizeof(RIL_CellInfo_v12); + records.resize(num); + + RIL_CellInfo_v12 *rillCellInfo = (RIL_CellInfo_v12 *) response; + for (int i = 0; i < num; i++) { + records[i].cellInfoType = (CellInfoType) rillCellInfo->cellInfoType; + records[i].registered = rillCellInfo->registered; + records[i].timeStampType = (TimeStampType) rillCellInfo->timeStampType; + records[i].timeStamp = rillCellInfo->timeStamp; + // All vectors should be size 0 except one which will be size 1. Set everything to + // size 0 initially. + records[i].gsm.resize(0); + records[i].wcdma.resize(0); + records[i].cdma.resize(0); + records[i].lte.resize(0); + records[i].tdscdma.resize(0); + switch(rillCellInfo->cellInfoType) { + case RIL_CELL_INFO_TYPE_GSM: { + records[i].gsm.resize(1); + CellInfoGsm *cellInfoGsm = &records[i].gsm[0]; + cellInfoGsm->cellIdentityGsm.mcc = + std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mcc); + cellInfoGsm->cellIdentityGsm.mnc = + std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc); + cellInfoGsm->cellIdentityGsm.lac = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.lac; + cellInfoGsm->cellIdentityGsm.cid = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.cid; + cellInfoGsm->cellIdentityGsm.arfcn = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.arfcn; + cellInfoGsm->cellIdentityGsm.bsic = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.bsic; + cellInfoGsm->signalStrengthGsm.signalStrength = + rillCellInfo->CellInfo.gsm.signalStrengthGsm.signalStrength; + cellInfoGsm->signalStrengthGsm.bitErrorRate = + rillCellInfo->CellInfo.gsm.signalStrengthGsm.bitErrorRate; + cellInfoGsm->signalStrengthGsm.timingAdvance = + rillCellInfo->CellInfo.gsm.signalStrengthGsm.timingAdvance; + break; + } + + case RIL_CELL_INFO_TYPE_WCDMA: { + records[i].wcdma.resize(1); + CellInfoWcdma *cellInfoWcdma = &records[i].wcdma[0]; + cellInfoWcdma->cellIdentityWcdma.mcc = + std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mcc); + cellInfoWcdma->cellIdentityWcdma.mnc = + std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc); + cellInfoWcdma->cellIdentityWcdma.lac = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.lac; + cellInfoWcdma->cellIdentityWcdma.cid = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.cid; + cellInfoWcdma->cellIdentityWcdma.psc = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.psc; + cellInfoWcdma->cellIdentityWcdma.uarfcn = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.uarfcn; + cellInfoWcdma->signalStrengthWcdma.signalStrength = + rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.signalStrength; + cellInfoWcdma->signalStrengthWcdma.bitErrorRate = + rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate; + break; + } + + case RIL_CELL_INFO_TYPE_CDMA: { + records[i].cdma.resize(1); + CellInfoCdma *cellInfoCdma = &records[i].cdma[0]; + cellInfoCdma->cellIdentityCdma.networkId = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.networkId; + cellInfoCdma->cellIdentityCdma.systemId = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.systemId; + cellInfoCdma->cellIdentityCdma.baseStationId = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.basestationId; + cellInfoCdma->cellIdentityCdma.longitude = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.longitude; + cellInfoCdma->cellIdentityCdma.latitude = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.latitude; + cellInfoCdma->signalStrengthCdma.dbm = + rillCellInfo->CellInfo.cdma.signalStrengthCdma.dbm; + cellInfoCdma->signalStrengthCdma.ecio = + rillCellInfo->CellInfo.cdma.signalStrengthCdma.ecio; + cellInfoCdma->signalStrengthEvdo.dbm = + rillCellInfo->CellInfo.cdma.signalStrengthEvdo.dbm; + cellInfoCdma->signalStrengthEvdo.ecio = + rillCellInfo->CellInfo.cdma.signalStrengthEvdo.ecio; + cellInfoCdma->signalStrengthEvdo.signalNoiseRatio = + rillCellInfo->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio; + break; + } + + case RIL_CELL_INFO_TYPE_LTE: { + records[i].lte.resize(1); + CellInfoLte *cellInfoLte = &records[i].lte[0]; + cellInfoLte->cellIdentityLte.mcc = + std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mcc); + cellInfoLte->cellIdentityLte.mnc = + std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc); + cellInfoLte->cellIdentityLte.ci = + rillCellInfo->CellInfo.lte.cellIdentityLte.ci; + cellInfoLte->cellIdentityLte.pci = + rillCellInfo->CellInfo.lte.cellIdentityLte.pci; + cellInfoLte->cellIdentityLte.tac = + rillCellInfo->CellInfo.lte.cellIdentityLte.tac; + cellInfoLte->cellIdentityLte.earfcn = + rillCellInfo->CellInfo.lte.cellIdentityLte.earfcn; + cellInfoLte->signalStrengthLte.signalStrength = + rillCellInfo->CellInfo.lte.signalStrengthLte.signalStrength; + cellInfoLte->signalStrengthLte.rsrp = + rillCellInfo->CellInfo.lte.signalStrengthLte.rsrp; + cellInfoLte->signalStrengthLte.rsrq = + rillCellInfo->CellInfo.lte.signalStrengthLte.rsrq; + cellInfoLte->signalStrengthLte.rssnr = + rillCellInfo->CellInfo.lte.signalStrengthLte.rssnr; + cellInfoLte->signalStrengthLte.cqi = + rillCellInfo->CellInfo.lte.signalStrengthLte.cqi; + cellInfoLte->signalStrengthLte.timingAdvance = + rillCellInfo->CellInfo.lte.signalStrengthLte.timingAdvance; + break; + } + + case RIL_CELL_INFO_TYPE_TD_SCDMA: { + records[i].tdscdma.resize(1); + CellInfoTdscdma *cellInfoTdscdma = &records[i].tdscdma[0]; + cellInfoTdscdma->cellIdentityTdscdma.mcc = + std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mcc); + cellInfoTdscdma->cellIdentityTdscdma.mnc = + std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc); + cellInfoTdscdma->cellIdentityTdscdma.lac = + rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.lac; + cellInfoTdscdma->cellIdentityTdscdma.cid = + rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cid; + cellInfoTdscdma->cellIdentityTdscdma.cpid = + rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cpid; + cellInfoTdscdma->signalStrengthTdscdma.rscp = + rillCellInfo->CellInfo.tdscdma.signalStrengthTdscdma.rscp; + break; + } + default: { + break; + } + } + rillCellInfo += 1; + } +} + +int radio::cellInfoListInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if ((response == NULL && responseLen != 0) || responseLen % sizeof(RIL_CellInfo_v12) != 0) { + RLOGE("cellInfoListInd: invalid response"); + return 0; + } + + hidl_vec records; + convertRilCellInfoListToHal(response, responseLen, records); + +#if VDBG + RLOGD("cellInfoListInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cellInfoList( + convertIntToRadioIndicationType(indicationType), records); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cellInfoListInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::imsNetworkStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("imsNetworkStateChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->imsNetworkStateChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("imsNetworkStateChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::subscriptionStatusChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("subscriptionStatusChangedInd: invalid response"); + return 0; + } + bool activate = ((int32_t *) response)[0]; +#if VDBG + RLOGD("subscriptionStatusChangedInd: activate %d", activate); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->subscriptionStatusChanged( + convertIntToRadioIndicationType(indicationType), activate); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("subscriptionStatusChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::srvccStateNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("srvccStateNotifyInd: invalid response"); + return 0; + } + int32_t state = ((int32_t *) response)[0]; +#if VDBG + RLOGD("srvccStateNotifyInd: rat %d", state); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->srvccStateNotify( + convertIntToRadioIndicationType(indicationType), (SrvccState) state); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("srvccStateNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +void convertRilHardwareConfigListToHal(void *response, size_t responseLen, + hidl_vec& records) { + int num = responseLen / sizeof(RIL_HardwareConfig); + records.resize(num); + + RIL_HardwareConfig *rilHardwareConfig = (RIL_HardwareConfig *) response; + for (int i = 0; i < num; i++) { + records[i].type = (HardwareConfigType) rilHardwareConfig[i].type; + records[i].uuid = convertCharPtrToHidlString(rilHardwareConfig[i].uuid); + records[i].state = (HardwareConfigState) rilHardwareConfig[i].state; + switch (rilHardwareConfig[i].type) { + case RIL_HARDWARE_CONFIG_MODEM: { + records[i].modem.resize(1); + records[i].sim.resize(0); + HardwareConfigModem *hwConfigModem = &records[i].modem[0]; + hwConfigModem->rat = rilHardwareConfig[i].cfg.modem.rat; + hwConfigModem->maxVoice = rilHardwareConfig[i].cfg.modem.maxVoice; + hwConfigModem->maxData = rilHardwareConfig[i].cfg.modem.maxData; + hwConfigModem->maxStandby = rilHardwareConfig[i].cfg.modem.maxStandby; + break; + } + + case RIL_HARDWARE_CONFIG_SIM: { + records[i].sim.resize(1); + records[i].modem.resize(0); + records[i].sim[0].modemUuid = + convertCharPtrToHidlString(rilHardwareConfig[i].cfg.sim.modemUuid); + break; + } + } + } +} + +int radio::hardwareConfigChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_HardwareConfig) != 0) { + RLOGE("hardwareConfigChangedInd: invalid response"); + return 0; + } + + hidl_vec configs; + convertRilHardwareConfigListToHal(response, responseLen, configs); + +#if VDBG + RLOGD("hardwareConfigChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->hardwareConfigChanged( + convertIntToRadioIndicationType(indicationType), configs); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hardwareConfigChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc) { + RIL_RadioCapability *rilRadioCapability = (RIL_RadioCapability *) response; + rc.session = rilRadioCapability->session; + rc.phase = (android::hardware::radio::V1_0::RadioCapabilityPhase) rilRadioCapability->phase; + rc.raf = rilRadioCapability->rat; + rc.logicalModemUuid = convertCharPtrToHidlString(rilRadioCapability->logicalModemUuid); + rc.status = (android::hardware::radio::V1_0::RadioCapabilityStatus) rilRadioCapability->status; +} + +int radio::radioCapabilityIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) { + RLOGE("radioCapabilityIndicationInd: invalid response"); + return 0; + } + + RadioCapability rc = {}; + convertRilRadioCapabilityToHal(response, responseLen, rc); + +#if VDBG + RLOGD("radioCapabilityIndicationInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->radioCapabilityIndication( + convertIntToRadioIndicationType(indicationType), rc); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("radioCapabilityIndicationInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) { + if ((reqType == SS_INTERROGATION) && + (serType == SS_CFU || + serType == SS_CF_BUSY || + serType == SS_CF_NO_REPLY || + serType == SS_CF_NOT_REACHABLE || + serType == SS_CF_ALL || + serType == SS_CF_ALL_CONDITIONAL)) { + return true; + } + return false; +} + +int radio::onSupplementaryServiceIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_StkCcUnsolSsResponse)) { + RLOGE("onSupplementaryServiceIndicationInd: invalid response"); + return 0; + } + + RIL_StkCcUnsolSsResponse *rilSsResponse = (RIL_StkCcUnsolSsResponse *) response; + StkCcUnsolSsResult ss = {}; + ss.serviceType = (SsServiceType) rilSsResponse->serviceType; + ss.requestType = (SsRequestType) rilSsResponse->requestType; + ss.teleserviceType = (SsTeleserviceType) rilSsResponse->teleserviceType; + ss.serviceClass = rilSsResponse->serviceClass; + ss.result = (RadioError) rilSsResponse->result; + + if (isServiceTypeCfQuery(rilSsResponse->serviceType, rilSsResponse->requestType)) { +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd CF type, num of Cf elements %d", + rilSsResponse->cfData.numValidIndexes); +#endif + if (rilSsResponse->cfData.numValidIndexes > NUM_SERVICE_CLASSES) { + RLOGE("onSupplementaryServiceIndicationInd numValidIndexes is greater than " + "max value %d, truncating it to max value", NUM_SERVICE_CLASSES); + rilSsResponse->cfData.numValidIndexes = NUM_SERVICE_CLASSES; + } + + ss.cfData.resize(1); + ss.ssInfo.resize(0); + + /* number of call info's */ + ss.cfData[0].cfInfo.resize(rilSsResponse->cfData.numValidIndexes); + + for (int i = 0; i < rilSsResponse->cfData.numValidIndexes; i++) { + RIL_CallForwardInfo cf = rilSsResponse->cfData.cfInfo[i]; + CallForwardInfo *cfInfo = &ss.cfData[0].cfInfo[i]; + + cfInfo->status = (CallForwardInfoStatus) cf.status; + cfInfo->reason = cf.reason; + cfInfo->serviceClass = cf.serviceClass; + cfInfo->toa = cf.toa; + cfInfo->number = convertCharPtrToHidlString(cf.number); + cfInfo->timeSeconds = cf.timeSeconds; +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd: " + "Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status, + cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds); +#endif + } + } else { + ss.ssInfo.resize(1); + ss.cfData.resize(0); + + /* each int */ + ss.ssInfo[0].ssInfo.resize(SS_INFO_MAX); + for (int i = 0; i < SS_INFO_MAX; i++) { +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd: Data: %d", + rilSsResponse->ssInfo[i]); +#endif + ss.ssInfo[0].ssInfo[i] = rilSsResponse->ssInfo[i]; + } + } + +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication-> + onSupplementaryServiceIndication(convertIntToRadioIndicationType(indicationType), + ss); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("onSupplementaryServiceIndicationInd: " + "radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkCallControlAlphaNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("stkCallControlAlphaNotifyInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("stkCallControlAlphaNotifyInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkCallControlAlphaNotify( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkCallControlAlphaNotifyInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce) { + RIL_LceDataInfo *rilLceDataInfo = (RIL_LceDataInfo *)response; + lce.lastHopCapacityKbps = rilLceDataInfo->last_hop_capacity_kbps; + lce.confidenceLevel = rilLceDataInfo->confidence_level; + lce.lceSuspended = rilLceDataInfo->lce_suspended; +} + +int radio::lceDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) { + RLOGE("lceDataInd: invalid response"); + return 0; + } + + LceDataInfo lce = {}; + convertRilLceDataInfoToHal(response, responseLen, lce); +#if VDBG + RLOGD("lceDataInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->lceData( + convertIntToRadioIndicationType(indicationType), lce); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("lceDataInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::pcoDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_PCO_Data)) { + RLOGE("pcoDataInd: invalid response"); + return 0; + } + + PcoDataInfo pco = {}; + RIL_PCO_Data *rilPcoData = (RIL_PCO_Data *)response; + pco.cid = rilPcoData->cid; + pco.bearerProto = convertCharPtrToHidlString(rilPcoData->bearer_proto); + pco.pcoId = rilPcoData->pco_id; + pco.contents.setToExternal((uint8_t *) rilPcoData->contents, rilPcoData->contents_length); + +#if VDBG + RLOGD("pcoDataInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->pcoData( + convertIntToRadioIndicationType(indicationType), pco); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("pcoDataInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::modemResetInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("modemResetInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("modemResetInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->modemReset( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("modemResetInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::oemHookRawInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (oemHookService[slotId] != NULL && oemHookService[slotId]->mOemHookIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("oemHookRawInd: invalid response"); + return 0; + } + + hidl_vec data; + data.setToExternal((uint8_t *) response, responseLen); +#if VDBG + RLOGD("oemHookRawInd"); +#endif + Return retStatus = oemHookService[slotId]->mOemHookIndication->oemHookRaw( + convertIntToRadioIndicationType(indicationType), data); + checkReturnStatus(slotId, retStatus, false); + } else { + RLOGE("oemHookRawInd: oemHookService[%d]->mOemHookIndication == NULL", slotId); + } + + return 0; +} + +void radio::registerService(RIL_RadioFunctions *callbacks, CommandInfo *commands) { + using namespace android::hardware; + int simCount = 1; + const char *serviceNames[] = { + android::RIL_getServiceName() + #if (SIM_COUNT >= 2) + , RIL2_SERVICE_NAME + #if (SIM_COUNT >= 3) + , RIL3_SERVICE_NAME + #if (SIM_COUNT >= 4) + , RIL4_SERVICE_NAME + #endif + #endif + #endif + }; + + #if (SIM_COUNT >= 2) + simCount = SIM_COUNT; + #endif + + configureRpcThreadpool(1, true /* callerWillJoin */); + for (int i = 0; i < simCount; i++) { + pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(i); + int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); + assert(ret == 0); + + radioService[i] = new RadioImpl; + radioService[i]->mSlotId = i; + oemHookService[i] = new OemHookImpl; + oemHookService[i]->mSlotId = i; + RLOGD("registerService: starting IRadio %s", serviceNames[i]); + android::status_t status = radioService[i]->registerAsService(serviceNames[i]); + status = oemHookService[i]->registerAsService(serviceNames[i]); + + ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + } + + s_vendorFunctions = callbacks; + s_commands = commands; +} + +void rilc_thread_pool() { + joinRpcThreadpool(); +} + +pthread_rwlock_t * radio::getRadioServiceRwlock(int slotId) { + pthread_rwlock_t *radioServiceRwlockPtr = &radioServiceRwlock; + + #if (SIM_COUNT >= 2) + if (slotId == 2) radioServiceRwlockPtr = &radioServiceRwlock2; + #if (SIM_COUNT >= 3) + if (slotId == 3) radioServiceRwlockPtr = &radioServiceRwlock3; + #if (SIM_COUNT >= 4) + if (slotId == 4) radioServiceRwlockPtr = &radioServiceRwlock4; + #endif + #endif + #endif + + return radioServiceRwlockPtr; +} diff --git a/ril/libril/ril_service.h b/ril/libril/ril_service.h new file mode 100644 index 00000000..441b5879 --- /dev/null +++ b/ril/libril/ril_service.h @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RIL_SERVICE_H +#define RIL_SERVICE_H + +#include +#include + +namespace radio { +void registerService(RIL_RadioFunctions *callbacks, android::CommandInfo *commands); + +int getIccCardStatusResponse(int slotId, int responseType, + int token, RIL_Errno e, void *response, size_t responselen); + +int supplyIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyIccPukForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyIccPuk2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int changeIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int changeIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyNetworkDepersonalizationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getCurrentCallsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int dialResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, size_t responselen); + +int getIMSIForAppResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int hangupConnectionResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int hangupWaitingOrBackgroundResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int hangupForegroundResumeBackgroundResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int switchWaitingOrHoldingAndActiveResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int conferenceResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int rejectCallResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int getLastCallFailCauseResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getSignalStrengthResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int getVoiceRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getDataRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getOperatorResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setRadioPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendSMSExpectMoreResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setupDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen); + +int iccIOForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int cancelPendingUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, size_t responselen); + +int setClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, size_t responselen); + +int getCallForwardStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCallForwardResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acknowledgeLastIncomingGsmSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acceptCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int deactivateDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setBarringPasswordResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getNetworkSelectionModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setNetworkSelectionModeAutomaticResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setNetworkSelectionModeManualResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getAvailableNetworksResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int startDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int stopDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getBasebandVersionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int separateConnectionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getClipResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getDataCallListResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int setSuppServiceNotificationsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int writeSmsToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int deleteSmsOnSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setBandModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getAvailableBandModesResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendEnvelopeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendTerminalResponseToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int handleStkCallSetupRequestFromSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int explicitCallTransferResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getNeighboringCidsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setLocationUpdatesResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendCDMAFeatureCodeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendBurstDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acknowledgeLastIncomingCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setGsmBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getCDMASubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int writeSmsToRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int deleteSmsOnRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getDeviceIdentityResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int exitEmergencyCallbackModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int reportSmsMemoryStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int reportStkServiceIsRunningResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int getCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int requestIsimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acknowledgeIncomingGsmSmsWithPduResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendEnvelopeWithStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getVoiceRadioTechnologyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getCellInfoListResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen); + +int setCellInfoListRateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setInitialAttachApnResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getImsRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendImsSmsResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int iccTransmitApduBasicChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int iccOpenLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + + +int iccCloseLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int iccTransmitApduLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int nvReadItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + + +int nvWriteItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int nvWriteCdmaPrlResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int nvResetConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setUiccSubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setDataAllowedResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getHardwareConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int requestIccSimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setDataProfileResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int requestShutdownResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int setRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int startLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int stopLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int pullLceDataResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int getModemActivityInfoResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendDeviceStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setIndicationFilterResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setSimCardPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +void acknowledgeRequest(int slotId, int serial); + +int radioStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen); + +int callStateChangedInd(int slotId, int indType, int token, + RIL_Errno e, void *response, size_t responselen); + +int networkStateChangedInd(int slotId, int indType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newSmsStatusReportInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newSmsOnSimInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int onUssdInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int nitzTimeReceivedInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int currentSignalStrengthInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responselen); + +int dataCallListChangedInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int suppSvcNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkSessionEndInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkProactiveCommandInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkEventNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkCallSetupInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int simSmsStorageFullInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int simRefreshInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int callRingInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int simStatusChangedInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int cdmaNewSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newBroadcastSmsInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaRuimSmsStorageFullInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int restrictedStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int enterEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaCallWaitingInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaOtaProvisionStatusInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaInfoRecInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int oemHookRawInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int indicateRingbackToneInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int resendIncallMuteInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaSubscriptionSourceChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responselen); + +int cdmaPrlChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int exitEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int rilConnectedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int voiceRadioTechChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cellInfoListInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int imsNetworkStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int subscriptionStatusChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int srvccStateNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int hardwareConfigChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int radioCapabilityIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int onSupplementaryServiceIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responselen); + +int stkCallControlAlphaNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int lceDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int pcoDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int modemResetInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int sendRequestRawResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int sendRequestStringsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +pthread_rwlock_t * getRadioServiceRwlock(int slotId); + +} // namespace radio + +#endif // RIL_SERVICE_H \ No newline at end of file diff --git a/ril/libril/ril_unsol_commands.h b/ril/libril/ril_unsol_commands.h index 11ae0500..948eaeb7 100644 --- a/ril/libril/ril_unsol_commands.h +++ b/ril/libril/ril_unsol_commands.h @@ -14,50 +14,51 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ - {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, responseString, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_ON_USSD, responseStrings, WAKE_PARTIAL}, - {RIL_UNSOL_ON_USSD_REQUEST, responseVoid, DONT_WAKE}, - {RIL_UNSOL_NITZ_TIME_RECEIVED, responseString, WAKE_PARTIAL}, - {RIL_UNSOL_SIGNAL_STRENGTH, responseRilSignalStrength, DONT_WAKE}, - {RIL_UNSOL_DATA_CALL_LIST_CHANGED, responseDataCallList, WAKE_PARTIAL}, - {RIL_UNSOL_SUPP_SVC_NOTIFICATION, responseSsn, WAKE_PARTIAL}, - {RIL_UNSOL_STK_SESSION_END, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_STK_PROACTIVE_COMMAND, responseString, WAKE_PARTIAL}, - {RIL_UNSOL_STK_EVENT_NOTIFY, responseString, WAKE_PARTIAL}, - {RIL_UNSOL_STK_CALL_SETUP, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_SIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_SIM_REFRESH, responseSimRefresh, WAKE_PARTIAL}, - {RIL_UNSOL_CALL_RING, responseCallRing, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, responseCdmaSms, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, responseRaw, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_RESTRICTED_STATE_CHANGED, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_CALL_WAITING, responseCdmaCallWaiting, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_INFO_REC, responseCdmaInformationRecords, WAKE_PARTIAL}, - {RIL_UNSOL_OEM_HOOK_RAW, responseRaw, WAKE_PARTIAL}, - {RIL_UNSOL_RINGBACK_TONE, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_RESEND_INCALL_MUTE, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_PRL_CHANGED, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_RIL_CONNECTED, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_CELL_INFO_LIST, responseCellInfoList, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, - {RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_SRVCC_STATE_NOTIFY, responseInts, WAKE_PARTIAL}, - {RIL_UNSOL_HARDWARE_CONFIG_CHANGED, responseHardwareConfig, WAKE_PARTIAL}, - {RIL_UNSOL_DC_RT_INFO_CHANGED, responseDcRtInfo, WAKE_PARTIAL}, - {RIL_UNSOL_RADIO_CAPABILITY, responseRadioCapability, WAKE_PARTIAL}, - {RIL_UNSOL_ON_SS, responseSSData, WAKE_PARTIAL}, - {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, responseString, WAKE_PARTIAL}, - {RIL_UNSOL_LCEDATA_RECV, responseLceData, WAKE_PARTIAL}, - {RIL_UNSOL_PCO_DATA, responsePcoData, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, radio::radioStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, radio::callStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, radio::networkStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_SMS, radio::newSmsInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, radio::newSmsStatusReportInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, radio::newSmsOnSimInd, WAKE_PARTIAL}, + {RIL_UNSOL_ON_USSD, radio::onUssdInd, WAKE_PARTIAL}, + {RIL_UNSOL_ON_USSD_REQUEST, radio::onUssdInd, DONT_WAKE}, + {RIL_UNSOL_NITZ_TIME_RECEIVED, radio::nitzTimeReceivedInd, WAKE_PARTIAL}, + {RIL_UNSOL_SIGNAL_STRENGTH, radio::currentSignalStrengthInd, DONT_WAKE}, + {RIL_UNSOL_DATA_CALL_LIST_CHANGED, radio::dataCallListChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_SUPP_SVC_NOTIFICATION, radio::suppSvcNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_SESSION_END, radio::stkSessionEndInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_PROACTIVE_COMMAND, radio::stkProactiveCommandInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_EVENT_NOTIFY, radio::stkEventNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_CALL_SETUP, radio::stkCallSetupInd, WAKE_PARTIAL}, + {RIL_UNSOL_SIM_SMS_STORAGE_FULL, radio::simSmsStorageFullInd, WAKE_PARTIAL}, + {RIL_UNSOL_SIM_REFRESH, radio::simRefreshInd, WAKE_PARTIAL}, + {RIL_UNSOL_CALL_RING, radio::callRingInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, radio::simStatusChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, radio::cdmaNewSmsInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, radio::newBroadcastSmsInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, radio::cdmaRuimSmsStorageFullInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESTRICTED_STATE_CHANGED, radio::restrictedStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, radio::enterEmergencyCallbackModeInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_CALL_WAITING, radio::cdmaCallWaitingInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, radio::cdmaOtaProvisionStatusInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_INFO_REC, radio::cdmaInfoRecInd, WAKE_PARTIAL}, + {RIL_UNSOL_OEM_HOOK_RAW, radio::oemHookRawInd, WAKE_PARTIAL}, + {RIL_UNSOL_RINGBACK_TONE, radio::indicateRingbackToneInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESEND_INCALL_MUTE, radio::resendIncallMuteInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, radio::cdmaSubscriptionSourceChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_PRL_CHANGED, radio::cdmaPrlChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, radio::exitEmergencyCallbackModeInd, WAKE_PARTIAL}, + {RIL_UNSOL_RIL_CONNECTED, radio::rilConnectedInd, WAKE_PARTIAL}, + {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, radio::voiceRadioTechChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_CELL_INFO_LIST, radio::cellInfoListInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, radio::imsNetworkStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, radio::subscriptionStatusChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_SRVCC_STATE_NOTIFY, radio::srvccStateNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_HARDWARE_CONFIG_CHANGED, radio::hardwareConfigChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_DC_RT_INFO_CHANGED, NULL, WAKE_PARTIAL}, + {RIL_UNSOL_RADIO_CAPABILITY, radio::radioCapabilityIndicationInd, WAKE_PARTIAL}, + {RIL_UNSOL_ON_SS, radio::onSupplementaryServiceIndicationInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, radio::stkCallControlAlphaNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_LCEDATA_RECV, radio::lceDataInd, WAKE_PARTIAL}, + {RIL_UNSOL_PCO_DATA, radio::pcoDataInd, WAKE_PARTIAL}, + {RIL_UNSOL_MODEM_RESTART, radio::modemResetInd, WAKE_PARTIAL}, diff --git a/ril/libril/sap_service.cpp b/ril/libril/sap_service.cpp new file mode 100644 index 00000000..7bed05a4 --- /dev/null +++ b/ril/libril/sap_service.cpp @@ -0,0 +1,958 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "RIL_SAP" + +#include + +#include +#include +#include +#include "pb_decode.h" +#include "pb_encode.h" + +using namespace android::hardware::radio::V1_0; +using ::android::hardware::Return; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_array; +using ::android::hardware::Void; +using android::CommandInfo; +using android::RequestInfo; +using android::requestToString; +using android::sp; + +struct SapImpl; + +#if (SIM_COUNT >= 2) +sp sapService[SIM_COUNT]; +#else +sp sapService[1]; +#endif + +struct SapImpl : public ISap { + int32_t slotId; + sp sapCallback; + RIL_SOCKET_ID rilSocketId; + + Return setCallback(const ::android::sp& sapCallbackParam); + + Return connectReq(int32_t token, int32_t maxMsgSize); + + Return disconnectReq(int32_t token); + + Return apduReq(int32_t token, SapApduType type, const hidl_vec& command); + + Return transferAtrReq(int32_t token); + + Return powerReq(int32_t token, bool state); + + Return resetSimReq(int32_t token); + + Return transferCardReaderStatusReq(int32_t token); + + Return setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol); + + MsgHeader* createMsgHeader(MsgId msgId, int32_t token); + + Return addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, uint8_t *reqPtr); + + void sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...); + + void checkReturnStatus(Return& ret); +}; + +void SapImpl::checkReturnStatus(Return& ret) { + if (ret.isOk() == false) { + RLOGE("checkReturnStatus: unable to call response/indication callback: %s", + ret.description().c_str()); + // Remote process (SapRilReceiver.java) hosting the callback must be dead. Reset the + // callback object; there's no other recovery to be done here. When the client process is + // back up, it will call setCallback() + sapCallback = NULL; + } +} + +Return SapImpl::setCallback(const ::android::sp& sapCallbackParam) { + RLOGD("SapImpl::setCallback for slotId %d", slotId); + sapCallback = sapCallbackParam; + return Void(); +} + +MsgHeader* SapImpl::createMsgHeader(MsgId msgId, int32_t token) { + // Memory for msg will be freed by RilSapSocket::onRequestComplete() + MsgHeader *msg = (MsgHeader *)calloc(1, sizeof(MsgHeader)); + if (msg == NULL) { + return NULL; + } + msg->token = token; + msg->type = MsgType_REQUEST; + msg->id = msgId; + msg->error = Error_RIL_E_SUCCESS; + return msg; +} + +Return SapImpl::addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, + uint8_t *reqPtr) { + msg->payload = (pb_bytes_array_t *)malloc(sizeof(pb_bytes_array_t) - 1 + reqLen); + if (msg->payload == NULL) { + sendFailedResponse(msg->id, msg->token, 2, reqPtr, msg); + return Void(); + } + msg->payload->size = reqLen; + memcpy(msg->payload->bytes, reqPtr, reqLen); + + RilSapSocket *sapSocket = RilSapSocket::getSocketById(rilSocketId); + if (sapSocket) { + RLOGD("SapImpl::addPayloadAndDispatchRequest: calling dispatchRequest"); + sapSocket->dispatchRequest(msg); + } else { + RLOGE("SapImpl::addPayloadAndDispatchRequest: sapSocket is null"); + sendFailedResponse(msg->id, msg->token, 3, msg->payload, reqPtr, msg); + return Void(); + } + free(msg->payload); + free(reqPtr); + return Void(); +} + +void SapImpl::sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...) { + va_list ap; + va_start(ap, numPointers); + for (int i = 0; i < numPointers; i++) { + void *ptr = va_arg(ap, void *); + if (ptr) free(ptr); + } + va_end(ap); + Return retStatus; + switch(msgId) { + case MsgId_RIL_SIM_SAP_CONNECT: + retStatus = sapCallback->connectResponse(token, SapConnectRsp::CONNECT_FAILURE, 0); + break; + + case MsgId_RIL_SIM_SAP_DISCONNECT: + retStatus = sapCallback->disconnectResponse(token); + break; + + case MsgId_RIL_SIM_SAP_APDU: { + hidl_vec apduRsp; + retStatus = sapCallback->apduResponse(token, SapResultCode::GENERIC_FAILURE, apduRsp); + break; + } + + case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { + hidl_vec atr; + retStatus = sapCallback->transferAtrResponse(token, SapResultCode::GENERIC_FAILURE, + atr); + break; + } + + case MsgId_RIL_SIM_SAP_POWER: + retStatus = sapCallback->powerResponse(token, SapResultCode::GENERIC_FAILURE); + break; + + case MsgId_RIL_SIM_SAP_RESET_SIM: + retStatus = sapCallback->resetSimResponse(token, SapResultCode::GENERIC_FAILURE); + break; + + case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: + retStatus = sapCallback->transferCardReaderStatusResponse(token, + SapResultCode::GENERIC_FAILURE, 0); + break; + + case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: + retStatus = sapCallback->transferProtocolResponse(token, SapResultCode::NOT_SUPPORTED); + break; + + default: + return; + } + sapService[slotId]->checkReturnStatus(retStatus); +} + +Return SapImpl::connectReq(int32_t token, int32_t maxMsgSize) { + RLOGD("SapImpl::connectReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_CONNECT, token); + if (msg == NULL) { + RLOGE("SapImpl::connectReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_CONNECT_REQ *****/ + RIL_SIM_SAP_CONNECT_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_CONNECT_REQ)); + req.max_message_size = maxMsgSize; + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::connectReq: Error getting encoded size for RIL_SIM_SAP_CONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::connectReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg); + return Void(); + } + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::connectReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::connectReq: Error encoding RIL_SIM_SAP_CONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_CONNECT_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::disconnectReq(int32_t token) { + RLOGD("SapImpl::disconnectReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_DISCONNECT, token); + if (msg == NULL) { + RLOGE("SapImpl::disconnectReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_DISCONNECT_REQ *****/ + RIL_SIM_SAP_DISCONNECT_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_DISCONNECT_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::disconnectReq: Error getting encoded size for RIL_SIM_SAP_DISCONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::disconnectReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::disconnectReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::disconnectReq: Error encoding RIL_SIM_SAP_DISCONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_DISCONNECT_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::apduReq(int32_t token, SapApduType type, const hidl_vec& command) { + RLOGD("SapImpl::apduReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_APDU, token); + if (msg == NULL) { + RLOGE("SapImpl::apduReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_APDU_REQ *****/ + RIL_SIM_SAP_APDU_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_APDU_REQ)); + req.type = (RIL_SIM_SAP_APDU_REQ_Type)type; + + if (command.size() > 0) { + req.command = (pb_bytes_array_t *)malloc(sizeof(pb_bytes_array_t) - 1 + command.size()); + if (req.command == NULL) { + RLOGE("SapImpl::apduReq: Error allocating memory for req.command"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 1, msg); + return Void(); + } + req.command->size = command.size(); + memcpy(req.command->bytes, command.data(), command.size()); + } + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_APDU_REQ_fields, &req)) { + RLOGE("SapImpl::apduReq: Error getting encoded size for RIL_SIM_SAP_APDU_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::apduReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::apduReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_APDU_REQ_fields, &req)) { + RLOGE("SapImpl::apduReq: Error encoding RIL_SIM_SAP_APDU_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 3, req.command, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_APDU_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::transferAtrReq(int32_t token) { + RLOGD("SapImpl::transferAtrReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token); + if (msg == NULL) { + RLOGE("SapImpl::transferAtrReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ *****/ + RIL_SIM_SAP_TRANSFER_ATR_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_ATR_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) { + RLOGE("SapImpl::transferAtrReq: Error getting encoded size for " + "RIL_SIM_SAP_TRANSFER_ATR_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::transferAtrReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::transferAtrReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) { + RLOGE("SapImpl::transferAtrReq: Error encoding RIL_SIM_SAP_TRANSFER_ATR_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::powerReq(int32_t token, bool state) { + RLOGD("SapImpl::powerReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_POWER, token); + if (msg == NULL) { + RLOGE("SapImpl::powerReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_POWER_REQ *****/ + RIL_SIM_SAP_POWER_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_POWER_REQ)); + req.state = state; + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_POWER_REQ_fields, &req)) { + RLOGE("SapImpl::powerReq: Error getting encoded size for RIL_SIM_SAP_POWER_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::powerReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::powerReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_POWER_REQ_fields, &req)) { + RLOGE("SapImpl::powerReq: Error encoding RIL_SIM_SAP_POWER_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_POWER_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::resetSimReq(int32_t token) { + RLOGD("SapImpl::resetSimReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_RESET_SIM, token); + if (msg == NULL) { + RLOGE("SapImpl::resetSimReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_RESET_SIM_REQ *****/ + RIL_SIM_SAP_RESET_SIM_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_RESET_SIM_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) { + RLOGE("SapImpl::resetSimReq: Error getting encoded size for RIL_SIM_SAP_RESET_SIM_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::resetSimReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::resetSimReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) { + RLOGE("SapImpl::resetSimReq: Error encoding RIL_SIM_SAP_RESET_SIM_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_RESET_SIM_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::transferCardReaderStatusReq(int32_t token) { + RLOGD("SapImpl::transferCardReaderStatusReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token); + if (msg == NULL) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ *****/ + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, + &req)) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error getting encoded size for " + "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::transferCardReaderStatusReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, &req)) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error encoding " + "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol) { + RLOGD("SapImpl::setTransferProtocolReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token); + if (msg == NULL) { + RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ *****/ + RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ)); + req.protocol = (RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_Protocol)transferProtocol; + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) { + RLOGE("SapImpl::setTransferProtocolReq: Error getting encoded size for " + "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::setTransferProtocolReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) { + RLOGE("SapImpl::setTransferProtocolReq: Error encoding " + "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +void *sapDecodeMessage(MsgId msgId, MsgType msgType, uint8_t *payloadPtr, size_t payloadLen) { + void *responsePtr = NULL; + bool decodeStatus = false; + pb_istream_t stream; + + /* Create the stream */ + stream = pb_istream_from_buffer((uint8_t *)payloadPtr, payloadLen); + + /* Decode based on the message id */ + switch (msgId) + { + case MsgId_RIL_SIM_SAP_CONNECT: + responsePtr = malloc(sizeof(RIL_SIM_SAP_CONNECT_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_CONNECT_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_CONNECT_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_DISCONNECT: + if (msgType == MsgType_RESPONSE) { + responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_RSP"); + return NULL; + } + } + } else { + responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_IND)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_IND_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_IND"); + return NULL; + } + } + } + break; + + case MsgId_RIL_SIM_SAP_APDU: + responsePtr = malloc(sizeof(RIL_SIM_SAP_APDU_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_APDU_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_APDU_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_TRANSFER_ATR: + responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_ATR_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_ATR_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_ATR_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_POWER: + responsePtr = malloc(sizeof(RIL_SIM_SAP_POWER_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_POWER_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_POWER_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_RESET_SIM: + responsePtr = malloc(sizeof(RIL_SIM_SAP_RESET_SIM_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_RESET_SIM_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_RESET_SIM_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_STATUS: + responsePtr = malloc(sizeof(RIL_SIM_SAP_STATUS_IND)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_STATUS_IND_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_STATUS_IND"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: + responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_fields, + responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_ERROR_RESP: + responsePtr = malloc(sizeof(RIL_SIM_SAP_ERROR_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_ERROR_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_ERROR_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: + responsePtr = malloc(sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_fields, + responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP"); + return NULL; + } + } + break; + + default: + break; + } + return responsePtr; +} /* sapDecodeMessage */ + +sp getSapImpl(RilSapSocket *sapSocket) { + switch (sapSocket->getSocketId()) { + case RIL_SOCKET_1: + RLOGD("getSapImpl: returning sapService[0]"); + return sapService[0]; + #if (SIM_COUNT >= 2) + case RIL_SOCKET_2: + return sapService[1]; + #if (SIM_COUNT >= 3) + case RIL_SOCKET_3: + return sapService[2]; + #if (SIM_COUNT >= 4) + case RIL_SOCKET_4: + return sapService[3]; + #endif + #endif + #endif + default: + return NULL; + } +} + +SapResultCode convertApduResponseProtoToHal(RIL_SIM_SAP_APDU_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_NOT_READY: + return SapResultCode::CARD_NOT_ACCESSSIBLE; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + default: + return SapResultCode::GENERIC_FAILURE; + } +} + +SapResultCode convertTransferAtrResponseProtoToHal( + RIL_SIM_SAP_TRANSFER_ATR_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE: + return SapResultCode::DATA_NOT_AVAILABLE; + default: + return SapResultCode::GENERIC_FAILURE; + } +} + +SapResultCode convertPowerResponseProtoToHal(RIL_SIM_SAP_POWER_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_ON: + return SapResultCode::CARD_ALREADY_POWERED_ON; + default: + return SapResultCode::GENERIC_FAILURE; + } +} + +SapResultCode convertResetSimResponseProtoToHal(RIL_SIM_SAP_RESET_SIM_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_NOT_READY: + return SapResultCode::CARD_NOT_ACCESSSIBLE; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + } + return SapResultCode::GENERIC_FAILURE; +} + +SapResultCode convertTransferCardReaderStatusResponseProtoToHal( + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE: + return SapResultCode::DATA_NOT_AVAILABLE; + } + return SapResultCode::GENERIC_FAILURE; +} + +void processResponse(MsgHeader *rsp, RilSapSocket *sapSocket, MsgType msgType) { + MsgId msgId = rsp->id; + uint8_t *data = rsp->payload->bytes; + size_t dataLen = rsp->payload->size; + + void *messagePtr = sapDecodeMessage(msgId, msgType, data, dataLen); + + sp sapImpl = getSapImpl(sapSocket); + if (sapImpl->sapCallback == NULL) { + RLOGE("processResponse: sapCallback == NULL; msgId = %d; msgType = %d", + msgId, msgType); + return; + } + + RLOGD("processResponse: sapCallback != NULL; msgId = %d; msgType = %d", + msgId, msgType); + + Return retStatus; + switch (msgId) { + case MsgId_RIL_SIM_SAP_CONNECT: { + RIL_SIM_SAP_CONNECT_RSP *connectRsp = (RIL_SIM_SAP_CONNECT_RSP *)messagePtr; + RLOGD("processResponse: calling sapCallback->connectResponse %d %d %d", + rsp->token, + connectRsp->response, + connectRsp->max_message_size); + retStatus = sapImpl->sapCallback->connectResponse(rsp->token, + (SapConnectRsp)connectRsp->response, + connectRsp->max_message_size); + break; + } + + case MsgId_RIL_SIM_SAP_DISCONNECT: + if (msgType == MsgType_RESPONSE) { + RLOGD("processResponse: calling sapCallback->disconnectResponse %d", rsp->token); + retStatus = sapImpl->sapCallback->disconnectResponse(rsp->token); + } else { + RIL_SIM_SAP_DISCONNECT_IND *disconnectInd = + (RIL_SIM_SAP_DISCONNECT_IND *)messagePtr; + RLOGD("processResponse: calling sapCallback->disconnectIndication %d %d", + rsp->token, disconnectInd->disconnectType); + retStatus = sapImpl->sapCallback->disconnectIndication(rsp->token, + (SapDisconnectType)disconnectInd->disconnectType); + } + break; + + case MsgId_RIL_SIM_SAP_APDU: { + RIL_SIM_SAP_APDU_RSP *apduRsp = (RIL_SIM_SAP_APDU_RSP *)messagePtr; + SapResultCode apduResponse = convertApduResponseProtoToHal(apduRsp->response); + RLOGD("processResponse: calling sapCallback->apduResponse %d %d", + rsp->token, apduResponse); + hidl_vec apduRspVec; + if (apduRsp->apduResponse != NULL && apduRsp->apduResponse->size > 0) { + apduRspVec.setToExternal(apduRsp->apduResponse->bytes, apduRsp->apduResponse->size); + } + retStatus = sapImpl->sapCallback->apduResponse(rsp->token, apduResponse, apduRspVec); + break; + } + + case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { + RIL_SIM_SAP_TRANSFER_ATR_RSP *transferAtrRsp = + (RIL_SIM_SAP_TRANSFER_ATR_RSP *)messagePtr; + SapResultCode transferAtrResponse = + convertTransferAtrResponseProtoToHal(transferAtrRsp->response); + RLOGD("processResponse: calling sapCallback->transferAtrResponse %d %d", + rsp->token, transferAtrResponse); + hidl_vec transferAtrRspVec; + if (transferAtrRsp->atr != NULL && transferAtrRsp->atr->size > 0) { + transferAtrRspVec.setToExternal(transferAtrRsp->atr->bytes, + transferAtrRsp->atr->size); + } + retStatus = sapImpl->sapCallback->transferAtrResponse(rsp->token, transferAtrResponse, + transferAtrRspVec); + break; + } + + case MsgId_RIL_SIM_SAP_POWER: { + SapResultCode powerResponse = convertPowerResponseProtoToHal( + ((RIL_SIM_SAP_POWER_RSP *)messagePtr)->response); + RLOGD("processResponse: calling sapCallback->powerResponse %d %d", + rsp->token, powerResponse); + retStatus = sapImpl->sapCallback->powerResponse(rsp->token, powerResponse); + break; + } + + case MsgId_RIL_SIM_SAP_RESET_SIM: { + SapResultCode resetSimResponse = convertResetSimResponseProtoToHal( + ((RIL_SIM_SAP_RESET_SIM_RSP *)messagePtr)->response); + RLOGD("processResponse: calling sapCallback->resetSimResponse %d %d", + rsp->token, resetSimResponse); + retStatus = sapImpl->sapCallback->resetSimResponse(rsp->token, resetSimResponse); + break; + } + + case MsgId_RIL_SIM_SAP_STATUS: { + RIL_SIM_SAP_STATUS_IND *statusInd = (RIL_SIM_SAP_STATUS_IND *)messagePtr; + RLOGD("processResponse: calling sapCallback->statusIndication %d %d", + rsp->token, statusInd->statusChange); + retStatus = sapImpl->sapCallback->statusIndication(rsp->token, + (SapStatus)statusInd->statusChange); + break; + } + + case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: { + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *transferStatusRsp = + (RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *)messagePtr; + SapResultCode transferCardReaderStatusResponse = + convertTransferCardReaderStatusResponseProtoToHal( + transferStatusRsp->response); + RLOGD("processResponse: calling sapCallback->transferCardReaderStatusResponse %d %d %d", + rsp->token, + transferCardReaderStatusResponse, + transferStatusRsp->CardReaderStatus); + retStatus = sapImpl->sapCallback->transferCardReaderStatusResponse(rsp->token, + transferCardReaderStatusResponse, + transferStatusRsp->CardReaderStatus); + break; + } + + case MsgId_RIL_SIM_SAP_ERROR_RESP: { + RLOGD("processResponse: calling sapCallback->errorResponse %d", rsp->token); + retStatus = sapImpl->sapCallback->errorResponse(rsp->token); + break; + } + + case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: { + SapResultCode setTransferProtocolResponse; + if (((RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP *)messagePtr)->response == + RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_Response_RIL_E_SUCCESS) { + setTransferProtocolResponse = SapResultCode::SUCCESS; + } else { + setTransferProtocolResponse = SapResultCode::NOT_SUPPORTED; + } + RLOGD("processResponse: calling sapCallback->transferProtocolResponse %d %d", + rsp->token, setTransferProtocolResponse); + retStatus = sapImpl->sapCallback->transferProtocolResponse(rsp->token, + setTransferProtocolResponse); + break; + } + + default: + return; + } + sapImpl->checkReturnStatus(retStatus); +} + +void sap::processResponse(MsgHeader *rsp, RilSapSocket *sapSocket) { + processResponse(rsp, sapSocket, MsgType_RESPONSE); +} + +void sap::processUnsolResponse(MsgHeader *rsp, RilSapSocket *sapSocket) { + processResponse(rsp, sapSocket, MsgType_UNSOL_RESPONSE); +} + +void sap::registerService(RIL_RadioFunctions *callbacks) { + using namespace android::hardware; + int simCount = 1; + const char *serviceNames[] = { + android::RIL_getServiceName() + #if (SIM_COUNT >= 2) + , RIL2_SERVICE_NAME + #if (SIM_COUNT >= 3) + , RIL3_SERVICE_NAME + #if (SIM_COUNT >= 4) + , RIL4_SERVICE_NAME + #endif + #endif + #endif + }; + + RIL_SOCKET_ID socketIds[] = { + RIL_SOCKET_1 + #if (SIM_COUNT >= 2) + , RIL_SOCKET_2 + #if (SIM_COUNT >= 3) + , RIL_SOCKET_3 + #if (SIM_COUNT >= 4) + , RIL_SOCKET_4 + #endif + #endif + #endif + }; + #if (SIM_COUNT >= 2) + simCount = SIM_COUNT; + #endif + + for (int i = 0; i < simCount; i++) { + sapService[i] = new SapImpl; + sapService[i]->slotId = i; + sapService[i]->rilSocketId = socketIds[i]; + RLOGD("registerService: starting ISap %s for slotId %d", serviceNames[i], i); + android::status_t status = sapService[i]->registerAsService(serviceNames[i]); + RLOGD("registerService: started ISap %s status %d", serviceNames[i], status); + } +} diff --git a/ril/libril/sap_service.h b/ril/libril/sap_service.h new file mode 100644 index 00000000..afed6126 --- /dev/null +++ b/ril/libril/sap_service.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SAP_SERVICE_H +#define SAP_SERVICE_H + +#include +#include +#include +#include + +namespace sap { + +void registerService(RIL_RadioFunctions *callbacks); +void processResponse(MsgHeader *rsp, RilSapSocket *sapSocket); +void processUnsolResponse(MsgHeader *rsp, RilSapSocket *sapSocket); + +} // namespace android + +#endif // RIL_SERVICE_H \ No newline at end of file