[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_call.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_call.cpp
new file mode 100644
index 0000000..90175a7
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_call.cpp
@@ -0,0 +1,976 @@
+#include <dlfcn.h>
+#include <string.h>
+#include <stdint.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "lynq_common.h"
+#include "lynq_call.h"
+#include <vendor-ril/telephony/ril.h>
+#include <stateManager/stateManager.h>
+#include <cutils/jstring.h>
+
+//#include "Parcel.h"
+
+//#include <sys/time.h>
+//#include <time.h>
+
+//#include <vendor-ril/mtk-rilproxy/atchannel.h>
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_CALL"
+
+//rita add @2020.7.8 for add call api
+//mobiletek @2020.11.10 add api statemanager
+int timer_count=0;
+enum {EXIT ,CHECK}status_call;
+callInfoLink * callInfoLinkhead =NULL;
+
+int call_Info_Init()
+{
+    callInfoLinkhead=create_callInfoLink();
+    if(callInfoLinkhead==NULL)
+    {
+        RLOGD("init call  info fail,maybe malloc fail!");
+        return -1;
+    }
+    return 0;
+}
+void sigalrm_handler(int sig)
+{
+        timer_count++;
+        printf("timer signal.. %d\n", timer_count);
+}
+void updateCallBackInfo(lynqCallList *message,lynq_call_list *calllsit)
+{
+    message->call_id=calllsit->callid;
+    message->call_state=(lynqCallState)calllsit->callState;
+    message->toa=calllsit->toa;
+    message->addr = calllsit->addr;
+    //memcpy(message->addr, calllsit->addr, strlen(calllsit->addr)+1);
+    return;
+}
+void showCallList(lynq_call_list *calllsit)
+{
+    if (calllsit==NULL)
+    {
+        RLOGD("the call list is null");
+        return;
+    }
+    LYINFLOG("lynq token is %d\n",calllsit->token);
+    LYINFLOG("lynq callid is %d\n",calllsit->callid);
+    LYINFLOG("lynq toa is %d\n",calllsit->toa);
+    LYINFLOG("lynq addr is %s\n",calllsit->addr);
+    LYINFLOG("lynq callstate is %d\n",calllsit->callState);
+    LYINFLOG("lynq lynq_error is %d\n",calllsit->lynq_error);
+    LYINFLOG("lynq isMT is %d\n",calllsit->isMT);
+    LYINFLOG("lynq serflen is %d\n",calllsit->selflen);
+    return;
+}
+void checkCallInfo(lynqCallList *message,const char *UserPhonyNum,int32_t token)
+{
+    int resplen=0;
+    int time_call =100;//10 s.
+    callInfoLink *temp;
+    enum{RUN,EXIT}state;
+    state=RUN;
+    while(time_call--)
+    {
+        millli_sleep_with_restart(100);
+        temp=callInfoLinkhead;
+        if (temp != NULL)
+        {
+            do
+            {
+                LYDBGLOG("[%s][%d][%s]token=%x Error_tok=%d,request is %d\n",__FUNCTION__, __LINE__,__FILE__,
+                temp->token, temp->Error_tok,temp->request);
+                //RLOGD("token=%x Error_tok=%d", p->token, p->Error_tok,p->request);
+                switch (temp->request)
+                {
+                    case RIL_REQUEST_DIAL:
+                    {
+                        if(temp->Error_tok==RIL_E_GENERIC_FAILURE)
+                        {
+                            message->call_state=LYNQ_CALL_DACTIVE;
+                            message->base.e = temp->Error_tok;
+                            return;
+                        }
+                        if((temp->calllist_tok==NULL)||(temp->calllist_tok[0]==NULL))
+                        {
+                            RLOGD("call list is null");
+                            state=EXIT;
+                            break;
+                         }
+                        resplen=temp->calllist_tok[0]->selflen;
+                        //printf("----resplen %d----\n",resplen);
+                        for(int i=0;i<resplen;i++)
+                        {
+                            printf("temp->token %x,input token is %x\n",temp->token,token);
+                            if((temp->token==token)&&(temp->calllist_tok[i]->callState==2))
+                            {
+                                //showCallList(temp->calllist_tok[i]);//for test
+                                if(strcmp(temp->calllist_tok[i]->addr, UserPhonyNum)==0)
+                                {
+                                    updateCallBackInfo(message,temp->calllist_tok[i]);
+                                    state=EXIT;
+                                    return;
+                                }
+                            }
+                            /*
+                            if(temp->calllist_tok[i]->lynq_error==RIL_E_GENERIC_FAILURE)
+                            {
+                                printf("RIL_E_GENERIC_FAILURE\n");
+                                state=EXIT;
+                                break;
+                            }*/
+                         }
+                        break;
+                    }
+                    case RIL_REQUEST_ANSWER:
+                    {
+                        if(temp->Error_tok==RIL_E_GENERIC_FAILURE)
+                        {
+                            printf("RIL_E_GENERIC_FAILURE\n");
+                            message->call_state=LYNQ_CALL_INCOMING;
+                            message->base.e = temp->Error_tok;
+                            return;
+                        }
+                        if((temp->calllist_tok==NULL)||(temp->calllist_tok[0]==NULL))
+                        {
+                            RLOGD("call list is null");
+                            state=EXIT;
+                            break;
+                         }
+                        resplen=temp->calllist_tok[0]->selflen;
+                        //printf("----resplen %d----\n",resplen);
+                        for(int i=0;i<resplen;i++)
+                        {
+                            printf("temp->token %x,input token is %x\n",temp->token,token);
+                            if((temp->token==token)&&(temp->calllist_tok[i]->isMT==1)
+                                &&(temp->calllist_tok[i]->callState==0))
+                            {
+                                showCallList(temp->calllist_tok[i]);//for test
+                                updateCallBackInfo(message,temp->calllist_tok[i]);
+                                state=EXIT;
+                                return;
+                            }
+                         }
+                        time_call=time_call-5;
+                        break;
+                    }
+                    default:
+                        break;
+                    }
+                
+                temp = temp->next;
+            }
+            while ((temp != NULL)&&(state==RUN));
+        }
+        else
+        {
+            RLOGD("call info link head is null");
+            continue;
+        }
+    }
+    printf("time_call is %d \n",time_call);
+    if(time_call<0)
+    {
+        message->call_state=LYNQ_CALL_DACTIVE;
+        message->base.e = -1;
+    }
+    return ;
+}
+static char *strdupReadString(Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+
+    return strndup16to8(s16, stringlen);
+}
+static lynq_call_list ** parcelToCallList(Parcel &p,int &len)
+{
+    int num = 0;
+    int uusPresent;
+    lynq_call_list **pCallLists = NULL;
+    lynq_call_list *pCallList = NULL;
+    int32_t res;
+    p.setDataPosition(0);
+    if (p.dataAvail() > 0) 
+    {
+        p.readInt32(&num);
+        len=num;
+        pCallLists = (lynq_call_list **) calloc(1, sizeof(lynq_call_list *) * num);
+        memset(pCallLists,0,sizeof(lynq_call_list *) * num);
+        for (int i = 0; i < num; i++) 
+        {
+            pCallList = (lynq_call_list *) calloc(1, sizeof(lynq_call_list));
+            memset(pCallList,0,sizeof(lynq_call_list));
+            pCallLists[i] = pCallList;
+            p.readInt32(&res);
+            pCallLists[i]->callState = (RIL_CallState) res;
+            p.readInt32(&pCallLists[i]->callid);
+            p.readInt32(&pCallLists[i]->toa);
+            p.readInt32(&res);
+            pCallLists[i]->isMpty = (uint8_t) res;
+            p.readInt32(&res);
+            pCallLists[i]->isMT = (uint8_t) res;
+            pCallLists[i]->addr = strdupReadString(p);
+            pCallLists[i]->selflen = num;
+        }
+    }
+    return pCallLists;
+}
+static void updateCallLists(const char *UserPhonyNum,lynqCallList *message,lynqQueue * node,int time)
+{
+    int resplen=0;
+    int time_call =time;
+    lynq_call_list ** call_list=NULL;
+    if(node ==NULL)
+    {
+        LYDBGLOG("update call lists node is null!");
+        return;
+    }
+    while(time_call--)
+    {
+        millli_sleep_with_restart(10);
+        switch (node->request)
+        {
+            case RIL_REQUEST_DIAL:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("call lists is null");
+                    break;
+                 }
+                for(int i=0;i<resplen;i++)
+                {
+                    if(call_list[i]->callState==2)
+                    {
+                        //showCallList(call_list[i]);//for test
+                        if(strcmp(call_list[i]->addr, UserPhonyNum)==0)
+                        {
+                            updateCallBackInfo(message,call_list[i]);
+                            return;
+                        }
+                    }
+                }
+                break;
+            }
+            case RIL_REQUEST_ANSWER:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("incoming call lists is null");
+                    break;
+                 }
+                if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                {
+                    for(int i=0;i<resplen;i++)
+                    {
+                        if(call_list[i]->isMT==1)
+                        {
+                            message->call_state=(lynqCallState)call_list[i]->callState;
+                            break;
+                        }
+                    }
+                    message->base.e = node->t_Errno;
+                    return;
+                }
+                for(int i=0;i<resplen;i++)
+                {
+                    if((call_list[i]->isMT==1)&&(call_list[i]->callState==RIL_CALL_ACTIVE))
+                    {
+                        //showCallList(call_list[i]);//for test
+                        updateCallBackInfo(message,call_list[i]);
+                        return;
+                    }
+                }
+                break;
+            }
+            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("[%s] call lists is null\n",__FUNCTION__);
+                    break;
+                }
+                for(int i =0;i<resplen;i++)
+                {
+                    if(call_list[i]->callState==RIL_CALL_ACTIVE)
+                    {
+                        //showCallList(call_list[i]);//for test
+                        updateCallBackInfo(message,call_list[i]);
+                        return;
+                    }
+                }
+                break;
+            }
+            case RIL_REQUEST_CONFERENCE:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("call lists is null");
+                    break;
+                }
+                for(int i =0;i<resplen;i++)
+                {
+                    if((call_list[i]->callState==RIL_CALL_ACTIVE)&&(call_list[i]->isMpty !=0))
+                    {
+                        //showCallList(call_list[i]);//for test
+                        updateCallBackInfo(message,call_list[i]);
+                        return;
+                    }
+                }
+                break;
+            }
+            default:
+                break;
+            }
+    }
+    LYDBGLOG("[%S] time_call is %d \n",__FUNCTION__,time_call);
+    if(time_call<0)
+    {
+        message->call_state=LYNQ_CALL_DACTIVE;
+        message->base.e = -1;
+    }
+    return ;
+
+}
+void checkParcelCallInfo(lynqCallList *message,const char *UserPhonyNum,int32_t token,int time)
+{
+    int resplen=0;
+    int time_call =time;
+    lynqQueue *temp=NULL;
+    //enum{RUN,EXIT}state;
+    //state=RUN;
+    message->base.e=-1;
+    printf("checkCallInfo start\n");
+    lynq_call_list ** call_list=NULL;
+    lynqQueue * node = NULL;
+    while(time_call--)
+    {
+        millli_sleep_with_restart(10);
+        temp=LynqQueueHead;
+        if (temp != NULL)
+        {
+            node = searchTokeninQueue(token, temp);
+            if(node ==NULL)
+            {
+                RLOGD("can not find token %x in this queue",token);
+                continue;
+            }
+            message->base.e = node->t_Errno;
+            /*if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+            {
+                RLOGD("RIL_E_GENERIC_FAILURE");
+                return;
+            }
+            */
+            //printf("token=%x Error_tok=%d,request is %d\n", node->token, node->t_Errno,node->request);
+            switch (node->request)
+            {
+                case RIL_REQUEST_DIAL:
+                {
+                    if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                    {
+                        RLOGD("RIL_E_GENERIC_FAILURE");
+                        message->call_state=LYNQ_CALL_DACTIVE;
+                        message->base.e = node->t_Errno;
+                        return;
+                    }
+                    call_list = parcelToCallList(node->parcel, resplen);
+                    if(call_list==NULL)
+                    {
+                        RLOGD("call lists is null");
+                        break;
+                     }
+                    //printf("----resplen %d----\n",resplen);
+                    for(int i=0;i<resplen;i++)
+                    {
+                        printf("temp->token %x,input token is %x\n",node->token,token);
+                        if((node->token==token)&&(call_list[i]->callState==2))
+                        {
+                            //showCallList(call_list[i]);//for test
+                            if(strcmp(call_list[i]->addr, UserPhonyNum)==0)
+                            {
+                                updateCallBackInfo(message,call_list[i]);
+                                return;
+                            }
+                        }
+                     }
+                    break;
+                }
+                case RIL_REQUEST_ANSWER:
+                {
+                    call_list = parcelToCallList(node->parcel, resplen);
+                    if(call_list==NULL)
+                    {
+                        RLOGD("incoming call lists is null");
+                        break;
+                     }
+                    if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                    {
+                        RLOGD("RIL_E_GENERIC_FAILURE");
+                        for(int i=0;i<resplen;i++)
+                        {
+                            if(call_list[i]->isMT==1)
+                            {
+                                message->call_state=(lynqCallState)call_list[i]->callState;
+                                break;
+                            }
+                        }
+                        message->base.e = node->t_Errno;
+                        return;
+                    }
+                    //printf("----resplen %d----\n",resplen);
+                    for(int i=0;i<resplen;i++)
+                    {
+                        printf("temp->token %x,input token is %x\n",node->token,token);
+                        if((call_list[i]->isMT==1)&&(call_list[i]->callState==0))
+                        {
+                            showCallList(call_list[i]);//for test
+                            updateCallBackInfo(message,call_list[i]);
+                            return;
+                        }
+                     }
+                    break;
+                }
+                case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+                {
+                    call_list = parcelToCallList(node->parcel, resplen);
+                    if(call_list==NULL)
+                    {
+                        RLOGD("call lists is null");
+                        break;
+                    }
+                    if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                    {
+                        RLOGD("RIL_E_GENERIC_FAILURE");
+                        message->base.e = node->t_Errno;
+                        return;
+                    }
+                    //printf("----resplen %d----\n",resplen);
+                    if(resplen == 1)
+                    {
+                        showCallList(call_list[0]);//for test
+                        message->call_id=call_list[0]->callid;
+                        message->call_state=(lynqCallState)call_list[0]->callState;
+                        message->toa=call_list[0]->toa;
+                        message->addr = call_list[0]->addr;
+                        //updateCallBackInfo(message,call_list[0]);
+                        message->base.e = node->t_Errno;
+                        //printf("message->call_state is %d\n",message->call_state);
+                        //printf("test pass\n");
+                        return;
+                    }
+                    break;
+                }
+                default:
+                    break;
+                }
+
+        }
+        else
+        {
+            RLOGD("call info link head is null");
+            continue;
+        }
+    }
+    printf("time_call is %d \n",time_call);
+    if(time_call<0)
+    {
+        message->call_state=LYNQ_CALL_DACTIVE;
+        message->base.e = -1;
+    }
+    return ;
+}
+
+
+int lynq_call_old(RIL_Dial *pRilDail)//function:dial;address:callnumber,clir:0 is default value,uusInfo:NULL or Pointer to User-User Signaling Information
+{
+    int lenth;
+    char *argv[MAX_LEN] = {};
+    char indexStr[MAX_QUEST_LEN] = "";
+    char uusType[MAX_QUEST_LEN] = "";
+    char uusDcs[MAX_QUEST_LEN] = "";
+    char uusLength[MAX_QUEST_LEN] = "";
+    
+    sprintf(indexStr, "%d", pRilDail->clir);
+
+    argv[0] = "RIL_REQUEST_DIAL";
+    argv[1] = pRilDail->address;
+    argv[2] = indexStr;
+    
+    if(pRilDail->uusInfo)
+    {
+        //printf("=========>[%s,%d],uusInfo exist!!!\n",__FUNCTION__,__LINE__);
+        sprintf(uusType,"%d",pRilDail->uusInfo->uusType);
+        sprintf(uusDcs,"%d",pRilDail->uusInfo->uusDcs);
+        sprintf(uusLength,"%d",pRilDail->uusInfo->uusLength);
+    
+        argv[3] = uusType;
+        argv[4] = uusDcs;
+        argv[5] = uusLength;
+        argv[6] = pRilDail->uusInfo->uusData;
+        lenth = 7;
+    }
+    else
+    {
+        //printf("=========>[%s,%d],uusInfo is NULL!!!\n",__FUNCTION__,__LINE__);
+        lenth = 3;
+    }
+    
+    return android::getRequestData(argv, lenth);
+}
+int lynq_call(const char *addr,lynqCallList* msg)//function:dial;address:callnumber,clir:0 is default value,uusInfo:NULL or Pointer to User-User Signaling Information
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue *node = NULL;
+    const char *argv[MAX_LEN]={};
+    char indexStr[MAX_QUEST_LEN] = "";
+    argv[0] = "RIL_REQUEST_DIAL";
+    if(addr==NULL)
+    {
+        RLOGD("addr is null!");
+        LYDBGLOG("addr is null!\n");
+        msg->call_state=LYNQ_CALL_DACTIVE;
+        msg->base.e = -1;
+        return 0;
+    }
+    argv[1] = addr;
+    argv[2]= "0";
+    if(token = android::getRequestData(argv, 3))
+    {
+        msg->base.token=token;
+        msg->base.request=RIL_REQUEST_DIAL;
+        node = commonUpdateEstatus(token,500, err);//wait 5s
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("lynq_call error code is %d!",err);
+            msg->call_state=LYNQ_CALL_DACTIVE;
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(addr,msg,node,9000);//wait 90s
+        //setCallStatus(LYNQ_CALL_ON);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+int lynq_call_answer(lynqCallList* msg)//function:answer a call
+{
+    int lenth;
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue *node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_ANSWER"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_HANGUP;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token=lynqNoneParame(requestStr))
+    {
+        msg->base.token=token;
+        msg->base.request=RIL_REQUEST_ANSWER;
+        node = commonUpdateEstatus(token,500, err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("lynq_call_answer error code is %d!",err);
+            msg->call_state=LYNQ_CALL_DACTIVE;
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_call_hang_up(const int callId,lynqBase *base)//function:hang up a call
+{
+    char *argv[MAX_LEN] = {};
+    char indexStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    sprintf(indexStr, "%d", callId);
+    argv[0] = "RIL_REQUEST_HANGUP";
+    argv[1] = indexStr;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_HANGUP;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request = RIL_REQUEST_HANGUP;
+        base->token=token;
+        node = commonUpdateEstatus(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_reject_call(lynqBase *base)//function:hang up all call or reject call
+{
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_UDUB"};
+    int32_t token=0;
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_UDUB;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        base->request = RIL_REQUEST_UDUB;
+        base->token=token;
+        node = commonUpdateEstatus(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_set_auto_answercall(int mode,int *status)// 1:enable,0:disable
+{
+    char *argv[MAX_LEN] = {};
+    char modeStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    sprintf(modeStr, "%d", mode);
+    argv[0] = "RIL_REQUEST_AUTO_ANSWER";
+    argv[1] = modeStr;
+    token = android::getRequestData(argv, 2);
+    *status = autoAnswerMode;
+    return token;
+}
+
+int lynq_get_mute_status(int *status) 
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token;
+    char enableStr[MAX_QUEST_LEN] = "";
+    ///sprintf(enableStr, "%d", enable);
+    argv[0] = "RIL_REQUEST_GET_MUTE";
+    //argv[1] = enableStr;
+    *status = android::specialRequestController(argv, 1,&token);
+    return token;
+
+}
+int lynq_get_mute_mic(int *status) // 1:enable  0:disable
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token;
+    char enableStr[MAX_QUEST_LEN] = "";
+    argv[0] = "RIL_REQUEST_GET_MUTE";
+    *status = android::specialRequestController(argv, 1,&token);
+    return 0;
+}
+int lynq_set_mute_mic(const int enable,int *status) // 1:enable  0:disable
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token;
+    char enableStr[MAX_QUEST_LEN] = "";
+    sprintf(enableStr, "%d", enable);
+    argv[0] = "RIL_REQUEST_SET_MUTE";
+    argv[1] = enableStr;
+    int ret = android::specialRequestController(argv, 2,&token);
+    if(ret)
+    {
+        LYDBGLOG("set mute failed !!");
+        *status = -1;
+        return token;
+    }
+    lynq_get_mute_mic(status);
+    *status = (enable>0)?1:0;
+    return token;
+}
+
+int lynq_set_DTMF(const char callnum,lynqBase *base)//callnum:  0-9,*,#
+{
+    char *argv[MAX_LEN] = {};
+    char callnumStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    //int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_DTMF;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if (INDEX_IS_NUMBER(callnum) || (callnum == '#') || (callnum == '*'))
+    {
+        sprintf(callnumStr, "%c", callnum);
+        argv[0] = "RIL_REQUEST_DTMF";
+        argv[1] = callnumStr;
+        if(token =android::getRequestData(argv, 2))
+        {
+            base->request = RIL_REQUEST_DTMF;
+            base->token=token;
+            node = commonUpdateEstatus(token,500,err);
+            base->e=err;
+            lynqDeQueue(token);
+        }
+        return token;
+    }
+    else
+    {
+        base->e=err;
+        LYERRLOG("[%s][%d][%s] invalid parameter!!! \n",__FUNCTION__,__LINE__,__FILE__);
+        return -1;
+    }
+}
+int lynq_set_DTMF_volume(const int         volume)//volume : 0 to 36
+{
+    char *argv[MAX_LEN] = {};
+    char volumeStr[MAX_QUEST_LEN] = "";
+
+    if((volume<=36) && (volume>=0))
+    {
+        argv[0] = "RIL_REQUEST_SET_DTMF_VOLUME";
+        sprintf(volumeStr, "%d", volume);
+        argv[1] = volumeStr;
+
+        return  android::getRequestData(argv, 2);
+    }
+    else{
+        LYERRLOG("[%s][%d][%s] invalid parameter!!! \n",__FUNCTION__,__LINE__,__FILE__);
+        return -1;
+    }
+}
+
+int lynq_do_multi_conference(lynqCallList *msg)
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_CONFERENCE"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_CONFERENCE;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_CONFERENCE;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_othercall_hold(const int callindex,lynqBase *base)//other select call turn hold
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char *argv[MAX_LEN] = {};
+    char callindexStr[MAX_QUEST_LEN] = "";
+    sprintf(callindexStr, "%d", callindex);
+    argv[0] = "RIL_REQUEST_SEPARATE_CONNECTION";
+    argv[1] = callindexStr;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_SEPARATE_CONNECTION;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request=RIL_REQUEST_SEPARATE_CONNECTION;
+        base->token=token;
+        node = commonUpdateEstatus(token,500,err);
+        base->e = err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_hangup_wating_for_call(lynqCallList *msg)
+{
+    int lenth;
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    //status_call = CHECK;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    //token=lynqNoneParame(requestStr);
+    //msg->base.token=token;
+    //msg->base.request=RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_hangup_foreground_resume_background(lynqCallList *msg)
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_switch_hold_and_active_call(lynqCallList *msg)
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+} 
+//AT< +CEER.
+int lynq_get_last_call_fail_cause(lynqLastCallFailCause *msg)
+{
+    int32_t token;
+    int time=500;
+    RIL_Errno err = -1;
+    int num=0;
+    int res=0;
+    lynqQueue * node = NULL;
+    lynqQueue * temp = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_LAST_CALL_FAIL_CAUSE"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        msg->base.token = token;
+        msg->base.request = RIL_REQUEST_LAST_CALL_FAIL_CAUSE;
+        node = commonUpdateEstatus(token,time,err);
+        msg->base.e=err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        if(node)
+        {
+            node->parcel.setDataPosition(0);
+            if (node->parcel.dataAvail() > 0)
+            {
+                node->parcel.readInt32(&num);
+                node->parcel.readInt32(&res);
+                msg->cause_code = (RIL_LastCallFailCause)res;
+                char * vendor_cause = strdupReadString(node->parcel);
+                memcpy(msg->vendor_cause,vendor_cause,strlen(vendor_cause)+1);
+                msg->base.e = node->t_Errno;
+                lynqDeQueue(token);
+                return token;
+            }
+        }
+    }
+    msg->cause_code = -1;
+    msg->base.e=-1;
+    lynqDeQueue(token);
+}
+/*
+void lynq_incoming_call_cb(RIL_SOCKET_ID soc_id,int index, char * addr, RIL_CallState state, int toa)
+{
+    printf("[SIM%d]index is %d,addr is %s,state is %d,toa is %d\n",soc_id,index,addr,state,toa);
+}
+*/