/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#define __STDC_LIMIT_MACROS
#include <stdint.h>
#define RIL_SHLIB
#include "telephony/ril.h"
#include "RilSapSocket.h"
#include "pb_decode.h"
#include "pb_encode.h"
#define LOG_TAG "RIL_UIM_SOCKET"
#include <utils/Log.h>
#include <arpa/inet.h>
#include <errno.h>

static RilSapSocket::RilSapSocketList *head = NULL;

void ril_sap_on_request_complete (
        RIL_Token t, RIL_Errno e,
        void *response, size_t responselen
);

void ril_sap_on_unsolicited_response (
        int unsolResponse, const void *data,
        size_t datalen
);
extern "C" void
RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
        const struct timeval *relativeTime);

struct RIL_Env RilSapSocket::uimRilEnv = {
        .OnRequestComplete = RilSapSocket::sOnRequestComplete,
        .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse,
        .RequestTimedCallback = RIL_requestTimedCallback
};

void RilSapSocket::sOnRequestComplete (RIL_Token t,
        RIL_Errno e,
        void *response,
        size_t responselen) {
    RilSapSocket *sap_socket;
    SapSocketRequest *request = (SapSocketRequest*) t;

    RLOGD("Socket id:%d", request->socketId);

    sap_socket = getSocketById(request->socketId);

    if (sap_socket) {
        sap_socket->onRequestComplete(t,e,response,responselen);
    } else {
        RLOGE("Invalid socket id");
        if (request->curr->payload) {
            free(request->curr->payload);
        }
        free(request->curr);
        free(request);
    }
}

#if defined(ANDROID_MULTI_SIM)
void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
        const void *data,
        size_t datalen,
        RIL_SOCKET_ID socketId) {
    RilSapSocket *sap_socket = getSocketById(socketId);
    if (sap_socket) {
        sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
    }
}
#else
void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
       const void *data,
       size_t datalen) {
    RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1);
    sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
}
#endif

void RilSapSocket::printList() {
    RilSapSocketList *current = head;
    RLOGD("Printing socket list");
    while(NULL != current) {
        RLOGD("SocketName:%s",current->socket->name);
        RLOGD("Socket id:%d",current->socket->id);
        current = current->next;
    }
}

RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) {
    RilSapSocket *sap_socket;
    RilSapSocketList *current = head;

    RLOGD("Entered getSocketById");
    printList();

    while(NULL != current) {
        if(socketId == current->socket->id) {
            sap_socket = current->socket;
            return sap_socket;
        }
        current = current->next;
    }
    return NULL;
}

void RilSapSocket::initSapSocket(const char *socketName,
        RIL_RadioFunctions *uimFuncs) {

    if (strcmp(socketName, "sap_uim_socket1") == 0) {
        if(!SocketExists(socketName)) {
            addSocketToList(socketName, RIL_SOCKET_1, uimFuncs);
        }
    }

#if (SIM_COUNT >= 2)
    if (strcmp(socketName, "sap_uim_socket2") == 0) {
        if(!SocketExists(socketName)) {
            addSocketToList(socketName, RIL_SOCKET_2, uimFuncs);
        }
    }
#endif

#if (SIM_COUNT >= 3)
    if (strcmp(socketName, "sap_uim_socket3") == 0) {
        if(!SocketExists(socketName)) {
            addSocketToList(socketName, RIL_SOCKET_3, uimFuncs);
        }
    }
#endif

#if (SIM_COUNT >= 4)
    if (strcmp(socketName, "sap_uim_socket4") == 0) {
        if(!SocketExists(socketName)) {
            addSocketToList(socketName, RIL_SOCKET_4, uimFuncs);
        }
    }
#endif
}

void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid,
        RIL_RadioFunctions *uimFuncs) {
    RilSapSocket* socket = NULL;
    RilSapSocketList *current;

    if(!SocketExists(socketName)) {
        socket = new RilSapSocket(socketName, socketid, uimFuncs);
        RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList));
        if (!listItem) {
            RLOGE("addSocketToList: OOM");
            return;
        }
        listItem->socket = socket;
        listItem->next = NULL;

        RLOGD("Adding socket with id: %d", socket->id);

        if(NULL == head) {
            head = listItem;
            head->next = NULL;
        }
        else {
            current = head;
            while(NULL != current->next) {
                current = current->next;
            }
            current->next = listItem;
        }
        socket->socketInit();
    }
}

bool RilSapSocket::SocketExists(const char *socketName) {
    RilSapSocketList* current = head;

    while(NULL != current) {
        if(strcmp(current->socket->name, socketName) == 0) {
            return true;
        }
        current = current->next;
    }
    return false;
}

void* RilSapSocket::processRequestsLoop(void) {
    RLOGI("UIM_SOCKET:Request loop started");

    while(true) {
        SapSocketRequest *req = dispatchQueue.dequeue();

        RLOGI("New request from the dispatch Queue");

        if (req != NULL) {
            dispatchRequest(req->curr);
            free(req);
        } else {
            RLOGE("Fetched null buffer from queue!");
        }
    }
    return NULL;
}

RilSapSocket::RilSapSocket(const char *socketName,
        RIL_SOCKET_ID socketId,
        RIL_RadioFunctions *inputUimFuncs):
        RilSocket(socketName, socketId) {
    if (inputUimFuncs) {
        uimFuncs = inputUimFuncs;
    }
}

#define BYTES_PER_LINE 16

#define NIBBLE_TO_HEX(n) ({ \
  uint8_t __n = (uint8_t) (n) & 0x0f; \
  __nibble >= 10 ? 'A' + __n - 10: '0' + __n; \
})

#define HEX_HIGH(b) ({ \
  uint8_t __b = (uint8_t) (b); \
  uint8_t __nibble = (__b >> 4) & 0x0f; \
  NIBBLE_TO_HEX(__nibble); \
})

#define HEX_LOW(b) ({ \
  uint8_t __b = (uint8_t) (b); \
  uint8_t __nibble = __b & 0x0f; \
  NIBBLE_TO_HEX(__nibble); \
})

void log_hex(const char *who, const uint8_t *buffer, int length) {
    char out[80];
    int source = 0;
    int dest = 0;
    int dest_len = sizeof(out);
    int per_line = 0;

    do {
        dest += sprintf(out, "%8.8s [%8.8x] ", who, source);
        for(; source < length && dest_len - dest > 3 && per_line < BYTES_PER_LINE; source++,
        per_line ++) {
            out[dest++] = HEX_HIGH(buffer[source]);
            out[dest++] = HEX_LOW(buffer[source]);
            out[dest++] = ' ';
        }
        if (dest < dest_len && (per_line == BYTES_PER_LINE || source >= length)) {
            out[dest++] = 0;
            per_line = 0;
            dest = 0;
            RLOGD("%s\n", out);
        }
    } while(source < length && dest < dest_len);
}

void RilSapSocket::dispatchRequest(MsgHeader *req) {
    // SapSocketRequest will be deallocated in onRequestComplete()
    SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
    if (!currRequest) {
        RLOGE("dispatchRequest: OOM");
        // Free MsgHeader allocated in pushRecord()
        free(req);
        return;
    }
    currRequest->token = req->token;
    currRequest->curr = req;
    currRequest->p_next = NULL;
    currRequest->socketId = id;

    pendingResponseQueue.enqueue(currRequest);

    if (uimFuncs) {
        RLOGI("[%d] > SAP REQUEST type: %d. id: %d. error: %d",
        req->token,
        req->type,
        req->id,
        req->error );

#if defined(ANDROID_MULTI_SIM)
        uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
#else
        uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
#endif
    }
}

void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
        size_t response_len) {
    SapSocketRequest* request= (SapSocketRequest*)t;
    MsgHeader *hdr = request->curr;

    if (response && response_len > 0) {
        MsgHeader rsp;
        rsp.token = request->curr->token;
        rsp.type = MsgType_RESPONSE;
        rsp.id = request->curr->id;
        rsp.error = (Error)e;
        rsp.payload = (pb_bytes_array_t *)calloc(1,
                sizeof(pb_bytes_array_t) + response_len);
        if (!rsp.payload) {
            RLOGE("onRequestComplete: OOM");
        } else {
            memcpy(rsp.payload->bytes, response, response_len);
            rsp.payload->size = response_len;

            RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);

            sendResponse(&rsp);
            free(rsp.payload);
        }
    }

    // Deallocate SapSocketRequest
    if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) {
        RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
        RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id");
    }

    // Deallocate MsgHeader
    free(hdr);
}

void RilSapSocket::sendResponse(MsgHeader* hdr) {
    size_t encoded_size = 0;
    uint32_t written_size;
    size_t buffer_size = 0;
    pb_ostream_t ostream;
    bool success = false;

    pthread_mutex_lock(&write_lock);

    if ((success = pb_get_encoded_size(&encoded_size, MsgHeader_fields,
        hdr)) && encoded_size <= INT32_MAX && commandFd != -1) {
        buffer_size = encoded_size + sizeof(uint32_t);
        uint8_t buffer[buffer_size];
        written_size = htonl((uint32_t) encoded_size);
        ostream = pb_ostream_from_buffer(buffer, buffer_size);
        pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size));
        success = pb_encode(&ostream, MsgHeader_fields, hdr);

        if (success) {
            RLOGD("Size: %d (0x%x) Size as written: 0x%x", encoded_size, encoded_size,
        written_size);
            log_hex("onRequestComplete", &buffer[sizeof(written_size)], encoded_size);
            RLOGI("[%d] < SAP RESPONSE type: %d. id: %d. error: %d",
        hdr->token, hdr->type, hdr->id,hdr->error );

            if ( 0 != blockingWrite_helper(commandFd, buffer, buffer_size)) {
                RLOGE("Error %d while writing to fd", errno);
            } else {
                RLOGD("Write successful");
            }
        } else {
            RLOGE("Error while encoding response of type %d id %d buffer_size: %d: %s.",
            hdr->type, hdr->id, buffer_size, PB_GET_ERROR(&ostream));
        }
    } else {
    RLOGE("Not sending response type %d: encoded_size: %u. commandFd: %d. encoded size result: %d",
        hdr->type, encoded_size, commandFd, success);
    }

    pthread_mutex_unlock(&write_lock);
}

void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) {
    if (data && datalen > 0) {
        pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1,
                sizeof(pb_bytes_array_t) + datalen);
        if (!payload) {
            RLOGE("onUnsolicitedResponse: OOM");
            return;
        }
        memcpy(payload->bytes, data, datalen);
        payload->size = datalen;
        MsgHeader rsp;
        rsp.payload = payload;
        rsp.type = MsgType_UNSOL_RESPONSE;
        rsp.id = (MsgId)unsolResponse;
        rsp.error = Error_RIL_E_SUCCESS;
        sendResponse(&rsp);
        free(payload);
    }
}

void RilSapSocket::pushRecord(void *p_record, size_t recordlen) {
    pb_istream_t stream = pb_istream_from_buffer((uint8_t *)p_record, recordlen);
    // MsgHeader will be deallocated in onRequestComplete()
    MsgHeader *reqHeader = (MsgHeader *)malloc(sizeof (MsgHeader));
    if (!reqHeader) {
        RLOGE("pushRecord: OOM");
        return;
    }
    memset(reqHeader, 0, sizeof(MsgHeader));

    log_hex("BtSapTest-Payload", (const uint8_t*)p_record, recordlen);

    if (!pb_decode(&stream, MsgHeader_fields, reqHeader) ) {
        RLOGE("Error decoding protobuf buffer : %s", PB_GET_ERROR(&stream));
        free(reqHeader);
    } else {
        // SapSocketRequest will be deallocated in processRequestsLoop()
        SapSocketRequest *recv = (SapSocketRequest*)malloc(sizeof(SapSocketRequest));
        if (!recv) {
            RLOGE("pushRecord: OOM");
            free(reqHeader);
            return;
        }
        recv->token = reqHeader->token;
        recv->curr = reqHeader;
        recv->socketId = id;

        dispatchQueue.enqueue(recv);
    }
}

void RilSapSocket::sendDisconnect() {
    size_t encoded_size = 0;
    uint32_t written_size;
    size_t buffer_size = 0;
    pb_ostream_t ostream;
    bool success = false;

    RIL_SIM_SAP_DISCONNECT_REQ disconnectReq;

   if ((success = pb_get_encoded_size(&encoded_size, RIL_SIM_SAP_DISCONNECT_REQ_fields,
        &disconnectReq)) && encoded_size <= INT32_MAX) {
        buffer_size = encoded_size + sizeof(uint32_t);
        uint8_t buffer[buffer_size];
        written_size = htonl((uint32_t) encoded_size);
        ostream = pb_ostream_from_buffer(buffer, buffer_size);
        pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size));
        success = pb_encode(&ostream, RIL_SIM_SAP_DISCONNECT_REQ_fields, buffer);

        if(success) {
            // Buffer will be deallocated in sOnRequestComplete()
            pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1,
                    sizeof(pb_bytes_array_t) + written_size);
            if (!payload) {
                RLOGE("sendDisconnect: OOM");
                return;
            }
            memcpy(payload->bytes, buffer, written_size);
            payload->size = written_size;
            // MsgHeader will be deallocated in sOnRequestComplete()
            MsgHeader *hdr = (MsgHeader *)malloc(sizeof(MsgHeader));
            if (!hdr) {
                RLOGE("sendDisconnect: OOM");
                free(payload);
                return;
            }
            hdr->payload = payload;
            hdr->type = MsgType_REQUEST;
            hdr->id = MsgId_RIL_SIM_SAP_DISCONNECT;
            hdr->error = Error_RIL_E_SUCCESS;
            dispatchDisconnect(hdr);
        }
        else {
            RLOGE("Encode failed in send disconnect!");
        }
    }
}

void RilSapSocket::dispatchDisconnect(MsgHeader *req) {
    // SapSocketRequest will be deallocated in sOnRequestComplete()
    SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
    if (!currRequest) {
        RLOGE("dispatchDisconnect: OOM");
        // Free memory allocated in sendDisconnect
        free(req->payload);
        free(req);
        return;
    }
    currRequest->token = -1;
    currRequest->curr = req;
    currRequest->p_next = NULL;
    currRequest->socketId = (RIL_SOCKET_ID)99;

    RLOGD("Sending disconnect on command close!");

#if defined(ANDROID_MULTI_SIM)
    uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
#else
    uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
#endif
}

void RilSapSocket::onCommandsSocketClosed() {
    sendDisconnect();
    RLOGE("Socket command closed");
}
