[Bugfix][API-597][call] lib call\network wait service response Architecture Refactoring

Change-Id: I0ab6f59d468f3ec4ffebe01944fea3548977fc96
diff --git a/lib/liblynq-call/lynq_call_ecall.cpp b/lib/liblynq-call/lynq_call_ecall.cpp
new file mode 100755
index 0000000..0c76262
--- /dev/null
+++ b/lib/liblynq-call/lynq_call_ecall.cpp
@@ -0,0 +1,703 @@
+#include <stdio.h>

+#include <sys/types.h>

+#include <sys/socket.h>

+#include <arpa/inet.h>

+#include <fcntl.h>

+#include <string.h>

+#include <stdlib.h>

+#include <unistd.h>

+#include <binder/Parcel.h>

+#include <log/log.h>

+#include <cutils/jstring.h>

+#include <pthread.h>

+#include "liblog/lynq_deflog.h"

+#include <sys/time.h>

+#include <string.h>

+#include <vendor-ril/telephony/ril.h>

+#include <vendor-ril/telephony/mtk_ril_sp.h>

+#include <vendor-ril/telephony/mtk_ril_ivt.h>

+#include "lynq_call.h"

+#include "lynq_module_common.h"

+#include "lynq_module_socket.h"

+#include "lynq_call_common.h"

+

+#define USER_LOG_TAG "LYNQ_CALL"

+

+using ::android::Parcel;

+

+#ifdef ECALL_SUPPORT

+typedef enum{        

+    LYNQ_ECALL_TYPE_TEST = 0,     /* Test eCall */

+    LYNQ_ECALL_TYPE_RECONFIG = 1,    /*    Reconfiguration eCall */    

+    LYNQ_ECALL_MANUAL_EMERGENCY = 2,   /*Manual Emergency eCall */

+    LYNQ_ECALL_TYPE_AUTO_EMERGENCY = 3,   /* Automatic Emergency eCall */

+}LYNQ_ECall_Type;

+typedef enum{   

+    LYNQ_ECALL_DAILING_STATE_NONE =0,

+    LYNQ_ECALL_DAILING_STATE_STARTED = 1,    

+    LYNQ_ECALL_DAILING_STATE_ANSWERED = 2,      

+}LYNQ_ECall_Dailing_State;

+static LYNQ_ECall_Dailing_State s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;

+int IsECallDialing()

+{

+    return s_module_is_ecall_dial != LYNQ_ECALL_DAILING_STATE_NONE;

+}

+static int s_ecallId = INVALID_ID;

+char e_call_addr[LYNQ_ECALL_VAR_MAX][LYNQ_PHONE_NUMBER_MAX]={"test_ecall","emergency_ecall","reconf_ecall"};

+

+static pthread_mutex_t s_incoming_e_call_mutex = PTHREAD_MUTEX_INITIALIZER;

+static pthread_cond_t s_incoming_e_call_cond = PTHREAD_COND_INITIALIZER;

+static pthread_mutex_t s_ecall_variable_mutex = PTHREAD_MUTEX_INITIALIZER;

+

+static LYNQ_ECall_Indication s_IncomingEcallIndication;

+int s_IncomingEcallId=INVALID_ID;

+LYNQ_ECall_Variant s_EcallVariant=LYNQ_ECALL_VAR_NONE;

+int s_ecall_whether_preempt=0;

+

+void sendSignalIncomingECallEvent()

+{

+    LYINFLOG("send incoming ecall event signal");

+    pthread_mutex_lock(&s_incoming_e_call_mutex);

+    pthread_cond_signal(&s_incoming_e_call_cond);

+    pthread_mutex_unlock(&s_incoming_e_call_mutex);

+}

+

+int lynq_is_msd_suc(LYNQ_ECall_Indication lynqIncomingEcallIndication)

+{

+    if(LYNQ_ECALL_LLACK_RECEIVED == lynqIncomingEcallIndication ||

+       LYNQ_ECALL_ALACK_POSITIVE_RECEIVED == lynqIncomingEcallIndication ||

+       LYNQ_ECALL_ALACK_CLEARDOWN_RECEIVED == lynqIncomingEcallIndication ||

+     //LYNQ_ECALL_T5_TIMER_OUT  == lynqIncomingEcallIndication ||

+       LYNQ_ECALL_T6_TIMER_OUT  == lynqIncomingEcallIndication ||

+       LYNQ_ECALL_T7_TIMER_OUT  == lynqIncomingEcallIndication)

+    {

+           return 1;

+    }

+

+    return 0;

+}

+

+int lynq_ecall_is_running()

+{

+    return (s_module_is_ecall_dial!=LYNQ_ECALL_DAILING_STATE_NONE) || (s_ecallId !=INVALID_ID || s_EcallVariant == LYNQ_ECALL_CALLBACK);

+}

+

+void print_ecall_info()

+{

+     LYERRLOG("%s is ecall dial is %d, ecall id is %d, ecall vairant is %d, incoming ecall ind is %d, incoming ecall id is %d, whether preempt is %d",__func__,s_module_is_ecall_dial,s_ecallId,s_EcallVariant,s_IncomingEcallIndication,s_IncomingEcallId,s_ecall_whether_preempt);

+}

+

+int lynq_ecall_is_permit_in_call(int ecall_id)

+{

+    return s_EcallVariant == LYNQ_ECALL_CALLBACK && (s_ecallId ==INVALID_ID || s_ecallId ==ecall_id);

+}

+

+int Is_handup_IncomingMT(int ecall_id)

+{

+    pthread_mutex_lock(&s_ecall_variable_mutex);

+    int handupIncomingMT=lynq_ecall_is_running() && (lynq_ecall_is_permit_in_call(ecall_id)==false);   

+    pthread_mutex_unlock(&s_ecall_variable_mutex);  

+    return handupIncomingMT;

+}

+

+int lynq_ecall_is_in_voice()

+{

+    return (s_module_is_ecall_dial==LYNQ_ECALL_DAILING_STATE_NONE) && (s_ecallId !=INVALID_ID);

+}

+

+LYNQ_ECall_Variant lynq_get_lynq_ecall_variant_from_lynq_type(LYNQ_ECall_Type type)

+{

+    switch(type)

+    {

+        case LYNQ_ECALL_TYPE_TEST:

+            return LYNQ_ECALL_TEST;

+        case LYNQ_ECALL_TYPE_RECONFIG:

+            return LYNQ_ECALL_RECONFIG;

+        default:

+            return LYNQ_ECALL_EMERGENCY;

+    }

+}

+

+RIL_ECall_Variant lynq_get_ril_ecall_variant_from_lynq_variant(LYNQ_ECall_Variant type)

+{

+    switch(type)

+    {

+        case LYNQ_ECALL_TEST:

+            return ECALL_TEST;

+        case LYNQ_ECALL_RECONFIG:

+            return ECALL_RECONFIG;

+        default:

+            return ECALL_EMERGENCY;

+    }

+}

+

+RIL_ECall_Category lynq_get_ril_ecall_cat_from_lynq_cat(LYNQ_ECall_Category cat)

+{

+    switch(cat)

+    {

+        case LYNQ_EMER_CAT_MANUAL_ECALL:

+            return EMER_CAT_MANUAL_ECALL;        

+        default:

+            return EMER_CAT_AUTO_ECALL;

+    }

+}

+

+

+int lynq_set_test_num(LYNQ_ECall_Set_Type type, const char *test_num, int test_num_length)

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+    if(test_num==NULL || test_num_length > LYNQ_PHONE_NUMBER_MAX )

+    {

+       LYERRLOG("test_num is null or test_num_length %d s greater than %d ",test_num_length,LYNQ_PHONE_NUMBER_MAX);

+       return LYNQ_E_PARAMETER_ANONALY;

+    }       

+    

+//    error=lynq_set_common_request(RIL_REQUEST_ECALL_SET_TEST_NUM,2,"%d %s",type,test_num);

+

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_SET_TEST_NUM,2,"%d %s",type,test_num);

+    if(ret==RESULT_OK)

+    {

+        snprintf(e_call_addr[LYNQ_ECALL_TEST],LYNQ_PHONE_NUMBER_MAX,"%s",test_num);

+        delete p;        

+    }

+    return ret;    

+}

+

+int lynq_ecall_can_be_preempted(LYNQ_ECall_Variant old_variant,LYNQ_ECall_Variant new_variant)

+{

+    int ret;

+

+    if(old_variant == LYNQ_ECALL_EMERGENCY)

+    {

+        return false;

+    }

+    else if(new_variant == LYNQ_ECALL_EMERGENCY)

+    {

+        return true;

+    }

+    else if(old_variant==LYNQ_ECALL_DAILING_STATE_NONE)

+    {

+        return true;

+    }        

+    else 

+    {

+        ret = (s_ecall_whether_preempt & 0x01);

+    }

+    LYINFLOG("ecall clear conflict call, lynq_ecall_can_be_preempted is true");

+    return ret;

+}

+

+int lynq_clear_current_call()

+{

+    int cnt;

+    int ret=lynq_call_hungup_all();

+    

+    if(ret!=RESULT_OK)

+    {

+        LYERRLOG("ecall clear conflict call,  hangup all failure");

+        return ret;

+    }       

+    cnt=0;

+    while(lynq_get_current_call_number()!=0 && cnt<80)

+    {

+        lynqNoticeGetModuleCallList();  

+        usleep(200 * 1000);//200ms

+        cnt++;                

+    }

+    if(lynq_get_current_call_number()!=0)

+    {

+        LYERRLOG("ecall clear conflict call, current call list can't cleared after 15s");

+        return LYNQ_E_INNER_ERROR;

+    } 

+

+    LYINFLOG("ecall clear conflict call, after %d 0.2s, call list  is cleared", cnt);         

+    return RESULT_OK;   

+}

+

+int lynq_clear_current_conflict_call(LYNQ_ECall_Variant old_variant,LYNQ_ECall_Variant new_variant)

+{

+    int cnt;

+    int ret;

+

+    if(lynq_ecall_is_running()==false)

+    {

+        if(lynq_get_current_call_number()==0)

+        {

+            LYINFLOG("ecall clear conflict call, no conflict ecall and normal call");

+        }

+        else if(s_ecall_whether_preempt & 0x02)

+        {

+            ret=lynq_clear_current_call();

+            LYERRLOG("ecall clear conflict call, relase current normal call ret is %d",ret);                         

+        }

+        return RESULT_OK;          

+    }

+

+    LYINFLOG("ecall clear conflict call, two ecall occure at the same time, new is %d, old is %d, g_preempt is %d",new_variant,old_variant,s_ecall_whether_preempt);

+

+    if(lynq_ecall_can_be_preempted(old_variant,new_variant)==false)

+    {

+        LYERRLOG("ecall clear conflict call, new ecall %d can't preempt old ecall %d",new_variant,old_variant);

+        return LYNQ_E_CONFLICT;

+    }    

+

+    ret=lynq_clear_current_call();

+    LYINFLOG("ecall clear conflict call, relase current call(including ecall) ret is %d",ret);    

+

+    if(s_module_is_ecall_dial != LYNQ_ECALL_DAILING_STATE_NONE)

+    {

+        sendSignalToWaitCallStateChange();  

+        LYINFLOG("ecall clear conflict call, stop ecall in dailing status");

+    }             

+    

+    cnt=0;

+    while(lynq_ecall_is_running() && cnt<80)

+    {

+        usleep(200 * 1000);//200ms

+        cnt++;

+    }

+  

+    if(lynq_ecall_is_running())

+    {

+        LYERRLOG("ecall clear conflict call, after 16s, lynq ecall is still running");        

+    }

+    else

+    {

+        LYINFLOG("ecall clear conflict call, after %d 0.2s, ecall info is cleared", cnt);           

+    }

+

+    sleep(3);// for ecall disconnect

+    print_ecall_info();        

+    return RESULT_OK;   

+}

+

+int lynq_fast_ecall(int* handle, LYNQ_ECall_Category lynq_ecall_cat, LYNQ_ECall_Variant lynq_ecall_variant,  const char *addr, int addr_length, const unsigned char *msd_data,int msd_length)

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+    RIL_ECall_Variant ril_ecall_variant = lynq_get_ril_ecall_variant_from_lynq_variant (lynq_ecall_variant);

+    RIL_ECall_Category ril_ecall_cat = lynq_get_ril_ecall_cat_from_lynq_cat(lynq_ecall_cat);

+    char lynq_msd_data[MSD_MAX_LENGTH*2+1]={0};

+    unsigned int i;          

+   

+    if(msd_length > MSD_MAX_LENGTH || msd_length <=0 || lynq_ecall_variant >=LYNQ_ECALL_MO_MAX)

+    {

+        LYERRLOG("lynq_fast_ecall msd_length %d or ecall variant %d parameter error",msd_length,lynq_ecall_variant);

+        return LYNQ_E_PARAMETER_ANONALY;

+    }     

+

+    if(lynq_clear_current_conflict_call(s_EcallVariant,lynq_ecall_variant)!=0)

+    {

+         LYERRLOG("%s call lynq_clear_current_conflict_call false, old is %d, new is %d",__func__,s_EcallVariant,lynq_ecall_variant);

+         return LYNQ_E_CONFLICT;

+    }  

+

+    pthread_mutex_lock(&s_ecall_variable_mutex);

+    s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_STARTED;

+    s_EcallVariant = lynq_ecall_variant;

+    s_ecallId = INVALID_ID;

+    pthread_mutex_unlock(&s_ecall_variable_mutex);

+

+    for(i =0; i<msd_length;i++)

+    {

+        sprintf(&(lynq_msd_data[i<<1]),"%02x",msd_data[i]);

+    }    

+

+

+    LYINFLOG("lynq_fast_ecall addr is %s",e_call_addr[lynq_ecall_variant]);

+

+//  error=lynq_set_common_request(RIL_REQUEST_ECALL_FAST_MAKE_ECALL,4,"%d %d %s %s",ril_ecall_cat, ril_ecall_variant, "null", lynq_msd_data);

+

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_FAST_MAKE_ECALL,4,"%d %d %s %s",ril_ecall_cat, ril_ecall_variant, "null", lynq_msd_data);

+    if(ret!=RESULT_OK)

+    {

+        pthread_mutex_lock(&s_ecall_variable_mutex);

+        s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;

+        s_EcallVariant = LYNQ_ECALL_VAR_NONE;

+        s_ecallId = INVALID_ID;

+        pthread_mutex_unlock(&s_ecall_variable_mutex);

+        return ret;      

+    }

+    

+    delete p;   

+    if(waitCallstateChange(270000)==ETIMEDOUT)//4.5 min, dailing 1 min, alerting 1 min, sending msd 30s, redial 2min

+    {

+        pthread_mutex_lock(&s_ecall_variable_mutex);

+        LYERRLOG("lynq_fast_ecall timeout:wait Call state time out!!!");                   

+        s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;            

+        lynqNoticeGetModuleCallList();  

+        pthread_mutex_unlock(&s_ecall_variable_mutex);

+        return LYNQ_E_TIME_OUT;

+    }

+    pthread_mutex_lock(&s_ecall_variable_mutex);

+    if(s_module_is_ecall_dial == LYNQ_ECALL_DAILING_STATE_STARTED)

+    {

+        /*just dail, no recv answer*/

+        LYERRLOG("lynq_fast_ecall, no answer!");   

+        s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;

+        lynqNoticeGetModuleCallList();   

+        pthread_mutex_unlock(&s_ecall_variable_mutex);

+        return LYNQ_E_ECALL_DAILING_NO_ANSWER;            

+    }

+    

+    s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;

+    lynqNoticeGetModuleCallList();        

+    

+    if(s_ecallId != INVALID_ID)

+    {

+        *handle=s_ecallId;         

+        LYINFLOG("lynq_fast_ecall id is %d",s_ecallId);

+        pthread_mutex_unlock(&s_ecall_variable_mutex);

+        return RESULT_OK;   

+    }

+

+    LYERRLOG("lynq_fast_ecall service return fail");

+    pthread_mutex_unlock(&s_ecall_variable_mutex);      

+    return LYNQ_E_INVALID_ID_ANONALY;                       

+    

+}

+

+int lynq_set_psap(int enable)

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+//  return lynq_set_common_request(RIL_REQUEST_ECALL_SET_PSAP,1,"%d",enable);    

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_SET_PSAP,1,"%d",enable);

+    if(ret==RESULT_OK)

+    {

+        delete p;        

+    }

+    return ret;

+}

+

+int lynq_psap_pull_msd()

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+//    return lynq_set_common_request(RIL_REQUEST_ECALL_PSAP_PULL_MSD,0,"");  

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_PSAP_PULL_MSD,0,"");

+    if(ret==RESULT_OK)

+    {

+        delete p;        

+    }

+    return ret;

+}

+

+int lynq_make_ecall(int* handle, LYNQ_ECall_Type type)

+{

+    return RESULT_OK;   

+#if 0

+    LYNQ_ECall_Variant lynq_ecall_variant;

+    int error = -1;

+    int lynq_call_id = -1;

+

+    if(handle==NULL)

+    {

+        LYERRLOG("handle is NULL, parameter error  ");

+           return -1;

+    }

+    

+    error=lynq_set_common_request(RIL_REQUEST_ECALL_MAKE_ECALL,1,"%d",type);   

+    

+    if(error==0)

+    {

+        lynq_ecall_variant=lynq_get_lynq_ecall_variant_from_lynq_type(type);

+      

+        lynq_call_id = addAddr(e_call_addr[lynq_ecall_variant]);

+        s_module_isDial = 1;

+        if(waitCallstateChange(10000)==ETIMEDOUT)//10000ms

+        {

+            error = LYNQ_E_TIME_OUT;

+            LYERRLOG("timeout:wait Call state fail!!!");

+            return error;

+        }

+ 

+        *handle = lynq_call_id;

+    }

+

+    return error;

+#endif

+}

+

+

+int lynq_set_msd(int* handle, const unsigned char *msd_data, int msd_length)

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+    char lynq_msd_data[MSD_MAX_LENGTH*2+1]={0};

+    unsigned int i;

+

+    if(handle==NULL || ((*handle) >= LYNQ_CALL_MAX) || msd_length > MSD_MAX_LENGTH || msd_length <= 0 || msd_data ==NULL)

+    {

+        LYERRLOG("lynq_set_msd handle is NULL or *handle %d is greater or equeal to %d or msd_length %d is greater than %d or msd_data %s is NULL, parameter error",*handle,LYNQ_CALL_MAX,msd_length,MSD_MAX_LENGTH, msd_data);

+        return LYNQ_E_PARAMETER_ANONALY;

+    }    

+

+    for(i=0; i<msd_length;i++)

+    {

+        sprintf(&(lynq_msd_data[i<<1]),"%02x",msd_data[i]);

+    }   

+

+    LYINFLOG("lynq_set_msd ");    

+

+//    return lynq_set_common_request(RIL_REQUEST_ECALL_SET_MSD,2,"%d %s",*handle,lynq_msd_data);

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_SET_MSD,2,"%d %s",*handle,lynq_msd_data);

+    if(ret==RESULT_OK)

+    {

+        delete p;        

+    }

+    return ret;

+}

+

+int lynq_set_ivs(int enable)

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+    if(enable<0)

+    {

+       if(enable >-100)

+       {

+           goto set_ivs_end;

+//         lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);

+       }

+       else  if(enable== -1000)

+       {

+           print_ecall_info();

+       } 

+       else

+       {

+           s_ecall_whether_preempt= ((-100-enable) & 0x11);           

+       }

+       return RESULT_OK;   

+    }

+

+//  return lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);  

+set_ivs_end:

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);

+    if(ret==RESULT_OK)

+    {

+        delete p;        

+    }

+    return ret;

+}

+

+int lynq_reset_ivs()

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+//  return lynq_set_common_request(RIL_REQUEST_ECALL_RESET_IVS,0,"");

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_RESET_IVS,0,"");

+    if(ret==RESULT_OK)

+    {

+        delete p;        

+    }

+    return ret;

+}

+

+int lynq_ivs_push_msd()

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+//  return lynq_set_common_request(RIL_REQUEST_ECALL_IVS_PUSH_MSD,0,"");  

+    Parcel* p=NULL;

+    int ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_ECALL_IVS_PUSH_MSD,0,"");

+    if(ret==RESULT_OK)

+    {

+        delete p;        

+    }

+    return ret;

+}

+

+int wait_ecall_event()

+{

+    int ret = 0;

+    pthread_mutex_lock(&s_incoming_e_call_mutex);

+    ret = pthread_cond_wait(&s_incoming_e_call_cond,&s_incoming_e_call_mutex);

+    pthread_mutex_unlock(&s_incoming_e_call_mutex); 

+    return ret;

+}

+

+int lynq_wait_ecall_indication(int* handle, LYNQ_ECall_Indication *eCall_Indication)

+{

+    if(g_module_init_flag != MODULE_RUNNING)

+    {

+        LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

+        return LYNQ_E_CONFLICT;

+    }

+    wait_ecall_event();

+    *handle = s_IncomingEcallId;

+    *eCall_Indication = s_IncomingEcallIndication;  

+    LYINFLOG("lynq_wait_ecall_indication handle %d, Ind id: %d", *handle, *eCall_Indication);

+    return RESULT_OK;  

+}

+void urc_ecall_msg_process(Parcel *p)

+{ 

+    int ecall_ind;

+    int ecallId;

+    int send_signal_to_wait_call_state;

+    int handup_ecall_id;

+    

+    pthread_mutex_lock(&s_ecall_variable_mutex);

+    send_signal_to_wait_call_state = false;

+    handup_ecall_id=false;

+    p->readInt32(&ecall_ind);   

+    s_IncomingEcallIndication = ecall_ind;

+    p->readInt32(&ecallId);

+    s_IncomingEcallId = ecallId;

+    LYINFLOG("**************:RIL_UNSOL_ECALL_INDICATIONS ,Id %d, ind %d, ecall dialing is %d, normal dialing is %d, local ecall id is %d",ecallId,ecall_ind,s_module_is_ecall_dial,IsNormalCallDailing(),s_ecallId);

+    switch (s_IncomingEcallIndication) 

+    {

+       case LYNQ_ECALL_ACTIVE:

+            if(s_module_is_ecall_dial)

+            {

+                s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_ANSWERED;

+            }

+            break;

+       case LYNQ_ECALL_SENDING_START:

+            if(lynq_ecall_is_in_voice())

+            {

+                LYINFLOG("recv msd in voice, ind is changed to %d",LYNQ_ECALL_SENDING_START_IN_VOICE);

+                s_IncomingEcallIndication = LYNQ_ECALL_SENDING_START_IN_VOICE; 

+            }

+            break;

+       case LYNQ_ECALL_LLACK_RECEIVED:

+       case LYNQ_ECALL_ALACK_POSITIVE_RECEIVED:

+       case LYNQ_ECALL_ALACK_CLEARDOWN_RECEIVED:

+       //case LYNQ_ECALL_T5_TIMER_OUT:  /*when Certificate CP 1.1.10.2, no msd start (ind 1), so T5 timeout is not regard as success*/

+       case LYNQ_ECALL_T6_TIMER_OUT:

+       case LYNQ_ECALL_T7_TIMER_OUT:                          

+           if(s_module_is_ecall_dial)

+           {

+               LYINFLOG("ecall is dialing, recv suc indication");

+               s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;

+               if(ecallId >0 && find_call_id_with_call_id(ecallId)==INVALID_ID)

+               {

+                     LYINFLOG("add ecall in loacl list");

+                     s_ecallId = ecallId;

+                     addAddr("ecall",s_ecallId);               

+               } 

+               send_signal_to_wait_call_state=true;                             

+           }        

+           else if(ecallId >0 && (find_call_id_with_call_id(ecallId)==INVALID_ID) &&  (s_EcallVariant != LYNQ_ECALL_CALLBACK))

+           {

+               LYERRLOG("ecall is not in dialing and first recv suc indication, hangup");

+               handup_ecall_id=true;

+           }   

+           else 

+           {

+               LYERRLOG("ecall is not in dialing and not first recv suc indication");

+           }

+           break;

+       case LYNQ_ECALL_PSAP_CALLBACK_START:                            

+           if(lynq_ecall_is_running()==0)

+           {

+               if(ecallId>0)

+               {                                

+                   LYINFLOG("ecall is not running, recv psap call back msd start, set ecall running");

+                   s_EcallVariant = LYNQ_ECALL_CALLBACK;

+                   s_ecallId = ecallId;

+                   if(IsNormalCallDailing())

+                   {

+                       LYINFLOG("stop normal dial");

+                       send_signal_to_wait_call_state=true;                               

+                   }

+                   else 

+                   {

+                       LYINFLOG("no normal dial");

+                   }  

+               }

+               else 

+               {

+                   LYERRLOG("ecallId is abnormal in psap callback");

+               }

+           }                           

+           else 

+           {

+               LYERRLOG("ecall is running, recv psap call back msd start");

+           }

+           break;                       

+       case LYNQ_ECALL_ABNORMAL_HANGUP:

+           if(s_module_is_ecall_dial == LYNQ_ECALL_DAILING_STATE_NONE)                             

+           {

+               LYERRLOG("ecall is not in dialing , recv abnormal hangup");

+               s_ecallId = INVALID_ID;

+           }

+           else if (s_module_is_ecall_dial == LYNQ_ECALL_DAILING_STATE_STARTED)

+           {

+               LYERRLOG("ecall is in dialing state, recv no answer, recv abnormal hangup, dont' redial");

+               s_ecallId = INVALID_ID;

+               send_signal_to_wait_call_state=true;                                                    

+           }    

+           else {

+               LYINFLOG("ecall is in dialing and recv answer, recv abnormal hangup");

+           }

+           break;

+       case LYNQ_ECALL_DISCONNECTED:

+       case LYNQ_ECALL_REDIAL_TIMER_OUT:

+       case LYNQ_ECALL_T2_TIMER_OUT :

+       case LYNQ_ECALL_IMS_DISCONNECTED:                           

+           s_ecallId = INVALID_ID;

+           if(s_EcallVariant == LYNQ_ECALL_CALLBACK)

+           {

+               s_EcallVariant = LYNQ_ECALL_VAR_NONE; /*other type, needn't re-initialize*/

+           }

+           if(s_module_is_ecall_dial != LYNQ_ECALL_DAILING_STATE_NONE)

+           {

+               LYERRLOG("ecall is in dialing, recv like disconnect indication");

+               s_module_is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;                         

+               send_signal_to_wait_call_state=true;                               

+           }

+           else 

+           {

+               LYINFLOG("ecall is not in dialing, recv like disconnect indication");

+           }

+           break;

+       default:                          

+           LYINFLOG("not special indication");

+    }                         

+    pthread_mutex_unlock(&s_ecall_variable_mutex);

+    if(send_signal_to_wait_call_state)

+    {

+        sendSignalToWaitCallStateChange();

+    }                    

+    sendSignalIncomingECallEvent();

+    if(handup_ecall_id)

+    {

+        lynq_call_hungup(&ecallId);

+    }

+    LYINFLOG("**************:RIL_UNSOL_ECALL_INDICATIONS, local ecall id is %d", s_ecallId);

+    return;

+}

+#endif