/* * 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 <android/hardware/radio/1.0/ISap.h> #include <hwbinder/IPCThreadState.h> #include <hwbinder/ProcessState.h> #include <sap_service.h> #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<SapImpl> sapService[SIM_COUNT]; #else sp<SapImpl> sapService[1]; #endif struct SapImpl : public ISap { int32_t slotId; sp<ISapCallback> sapCallback; RIL_SOCKET_ID rilSocketId; Return<void> setCallback(const ::android::sp<ISapCallback>& sapCallbackParam); Return<void> connectReq(int32_t token, int32_t maxMsgSize); Return<void> disconnectReq(int32_t token); Return<void> apduReq(int32_t token, SapApduType type, const hidl_vec<uint8_t>& command); Return<void> transferAtrReq(int32_t token); Return<void> powerReq(int32_t token, bool state); Return<void> resetSimReq(int32_t token); Return<void> transferCardReaderStatusReq(int32_t token); Return<void> setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol); MsgHeader* createMsgHeader(MsgId msgId, int32_t token); Return<void> addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, uint8_t *reqPtr); void sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...); void checkReturnStatus(Return<void>& ret); }; void SapImpl::checkReturnStatus(Return<void>& 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<void> SapImpl::setCallback(const ::android::sp<ISapCallback>& 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<void> 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<void> 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<uint8_t> apduRsp; retStatus = sapCallback->apduResponse(token, SapResultCode::GENERIC_FAILURE, apduRsp); break; } case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { hidl_vec<uint8_t> 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<void> 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<void> 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<void> SapImpl::apduReq(int32_t token, SapApduType type, const hidl_vec<uint8_t>& 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<void> 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<void> 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<void> 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<void> 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<void> 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<SapImpl> 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> 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<void> 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<uint8_t> 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<uint8_t> 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); } }