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