/*
 * 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) {
    pb_bytes_array_t *payload = (pb_bytes_array_t *) malloc(sizeof(pb_bytes_array_t) - 1 + reqLen);
    if (payload == NULL) {
        sendFailedResponse(msg->id, msg->token, 2, reqPtr, msg);
        return Void();
    }

    msg->payload = payload;
    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, 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;
    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(const 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);
    }
}
