/*
 * 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);
    }
}
