/* Copyright Statement:
 *
 * This software/firmware and related documentation ("MediaTek Software") are
 * protected under relevant copyright laws. The information contained herein
 * is confidential and proprietary to MediaTek Inc. and/or its licensors.
 * Without the prior written permission of MediaTek inc. and/or its licensors,
 * any reproduction, modification, use or disclosure of MediaTek Software,
 * and information contained herein, in whole or in part, shall be strictly prohibited.
 */
/* MediaTek Inc. (C) 2010. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
 * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
 * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
 * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
 * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
 * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
 * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
 * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
 * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
 * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
 * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
 * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
 * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
 *
 * The following software/firmware and/or related documentation ("MediaTek Software")
 * have been modified by MediaTek Inc. All revisions are subject to any receiver's
 * applicable license agreements with MediaTek Inc.
 */
#include <alloca.h>
#include <stdlib.h>
#include <stdio.h>
#include <vendor-ril/telephony/ril.h>
#include "common.h"
#undef LOG_TAG
#define LOG_TAG "MULTI_USER_RspDisp"

//data struct
typedef struct{
    int request;
    RIL_SOCKET_ID socket_id;
    char* arg;
}ResponseDisptachData;

struct RspDisp_Event{
    struct RspDisp_Event* next;
    struct RspDisp_Event* prev;
    ResponseDisptachData data;
};
//global variable
static pthread_mutex_t s_listMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_listCond = PTHREAD_COND_INITIALIZER;
//marco define
#define LIST_LOCK()  pthread_mutex_lock(&s_listMutex)
#define LIST_UNLOCK() pthread_mutex_unlock(&s_listMutex)
#define WAITLIST() pthread_cond_wait(&s_listCond,&s_listMutex)
#define WAKEUPLIST() pthread_cond_signal(&s_listCond)

//list variable and function announce
static struct RspDisp_Event rspDisp_list;
void initList(struct RspDisp_Event* list);
void addToList(struct RspDisp_Event* ev, struct RspDisp_Event* list);
void removeFromList(struct RspDisp_Event* ev);

void intRspList()
{
    LIST_LOCK();
    initList(&rspDisp_list);
    LIST_UNLOCK();
}

//function define
void initList(struct RspDisp_Event* list)
{
    memset(list, 0 ,sizeof(struct RspDisp_Event));
    list->next = list;
    list->prev = list;
    RLOGD("Demo Ril_event init list!");
}

void addToList(struct RspDisp_Event* ev, struct RspDisp_Event* list)
{ //add to list tail
    ev->next = list;
    ev->prev = list->prev;
    ev->prev->next = ev;
    list->prev = ev;
    RLOGD("Demo Ril_event add an event to list!");
}

void removeFromList(struct RspDisp_Event* ev)
{
    ev->next->prev = ev->prev;
    ev->prev->next = ev->next;
    ev->next = NULL;
    ev->prev = NULL;
    RLOGD("Demo Ril_event remove an event from list!");
}

void ARspRequestWithArg(int request, const char* arg,RIL_SOCKET_ID socket_id)
{
    struct RspDisp_Event* event = (struct RspDisp_Event*)malloc(sizeof(struct RspDisp_Event));

    if(event == NULL)
    {
        RLOGE("malloc event memory error!");
        return;
    }
    RLOGD("A Request happened, request is %s!",android::requestToString(request));
    event->data.request = request;
    if (arg != NULL) {
        event->data.arg = strdup(arg);
    } else {
        event->data.arg = NULL;
    }

    event->data.socket_id = socket_id;
    event->prev = NULL;
    event->next = NULL;
    LIST_LOCK();
    addToList(event,&rspDisp_list);
    WAKEUPLIST();
    LIST_UNLOCK();
    return;
}

void ARspRequest (int request,RIL_SOCKET_ID socket_id)
{
    ARspRequestWithArg(request, NULL,socket_id);
}

int dispOnSupport(int request)
{
    switch (request){
    case RIL_REQUEST_GET_CURRENT_CALLS:       return 1;
    case RIL_REQUEST_ANSWER:                  return 1;
    case RIL_REQUEST_GET_SIM_STATUS:          return 1;
    case RIL_REQUEST_DATA_REGISTRATION_STATE: return 1;
    case RIL_REQUEST_VOICE_REGISTRATION_STATE: return 1;
    case RIL_REQUEST_SMS_ACKNOWLEDGE:         return 1;
    case RIL_REQUEST_OEM_HOOK_RAW:              return 1;
    case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return 1;
    case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return 1;
    case RIL_REQUEST_RADIO_POWER: return 1;
    case RIL_REQUEST_ALLOW_DATA: return 1;
    case RIL_REQUEST_CDMA_FLASH: return 1;
    case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return 1;
    //case :return 1;
    default:return 0;
    }
}
//ResponseDispatch function used for :
// 1. ril request triggered by RIL_onRequestComplete flow
// 2. ril request triggered by RIL_onUnsolicitedResponse flow
void responseDispatch()
{
    struct RspDisp_Event* event = NULL;
    RLOGD("start loop!");

    prctl(PR_SET_NAME,(unsigned long)"demo_Rsp_disp");

    for(;;){

        LIST_LOCK();
        if(rspDisp_list.next == &rspDisp_list) {    //if blank list  then wait
            RLOGD("blank list ,then wait!");
            while(rspDisp_list.next == &rspDisp_list){
                WAITLIST();
            }
        }
        event = rspDisp_list.next;
        removeFromList(event);
        LIST_UNLOCK();

         // do ril request
         if(dispOnSupport(event->data.request) != 1) {
            RLOGD("event not support!");
            goto event_done;
        }
        android::RspDispFunction(event->data.request, event->data.arg, event->data.socket_id);

    event_done:
        if(event != NULL) {
            if(event->data.arg != NULL) {
                free(event->data.arg);
                event->data.arg = NULL;
            }
            free(event);
            event = NULL;
        }
    }

    return;
}
