[feature] ecall add abnormal process and cs call handle changed from index to call id

Change-Id: Iffc5ae14b06fa96c3ad3b6a1c77f9784654dce04
diff --git a/src/lynq/lib/liblynq-call/lynq_call.cpp b/src/lynq/lib/liblynq-call/lynq_call.cpp
index 48266b8..fd07b15 100755
--- a/src/lynq/lib/liblynq-call/lynq_call.cpp
+++ b/src/lynq/lib/liblynq-call/lynq_call.cpp
@@ -25,6 +25,7 @@
 #define LYNQ_REC_BUF 8192

 #define LYNQ_REQUEST_PARAM_BUF 8192

 #define LYQN_SEDN_BUF 1024*8+sizeof(int)*3

+#define INVALID_ID (-1)

 #define USER_LOG_TAG "LYNQ_CALL"

 

 using ::android::Parcel;

@@ -54,7 +55,6 @@
     int toa;

     int direction;/*0: MO call,1:MT call*/

     char addr[LYNQ_PHONE_NUMBER_MAX];

-    int hasTimeout;

 }lynq_call_list_e_t;

 typedef struct

 {

@@ -106,7 +106,13 @@
     /* The logic conflict*/

     LYNQ_E_CONFLICT=9000,

     /*Null anomaly*/

-    LYNQ_E_NULL_ANONALY=9001

+    LYNQ_E_NULL_ANONALY=9001,

+     /*Invalid id anomaly*/

+    LYNQ_E_INVALID_ID_ANONALY=9002,

+#ifdef ECALL_SUPPORT

+    LYNQ_E_ECALL_BEING_RUNNING =9003,

+    LYNQ_E_ECALL_MSD_LENGTH_ERROR =9004,

+#endif

 }LYNQ_E;

 typedef enum{

     LYNQ_E_VOLUMN_SET_DTMF,

@@ -124,6 +130,9 @@
 int lynqIncomingCallId = 0;

 

 #ifdef ECALL_SUPPORT

+int lynq_set_common_request(int request_id, int argc, const char* format,...);

+int is_ecall_dial = 0;

+int g_ecallId = INVALID_ID;

 typedef enum{        

     LYNQ_ECALL_TYPE_TEST = 0,     /* Test eCall */

     LYNQ_ECALL_TYPE_RECONFIG = 1,    /*    Reconfiguration eCall */    

@@ -131,22 +140,41 @@
     LYNQ_ECALL_TYPE_AUTO_EMERGENCY = 3,   /* Automatic Emergency eCall */\

 }LYNQ_ECall_Type;

 

-char e_call_addr[LYNQ_ECALL_VAR_MAX][LYNQ_PHONE_NUMBER_MAX]={"","null","112"};

-

-

+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;

 

-LYNQ_ECall_Indication lynqIncomingEcallIndication;

-int lynqEcallId;

+LYNQ_ECall_Indication g_lynqIncomingEcallIndication;

 

 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 (is_ecall_dial!=0) || (g_ecallId !=INVALID_ID);

+}

+

 #endif

 

 /**

@@ -177,7 +205,7 @@
     ret = sendto(sockfd, client_tmp, client_size, 0, (struct sockaddr *)&addr_serv, len_addr_serv);

     if(ret==-1)

     {

-        LYERRLOG("sendto error\n");

+        LYERRLOG("sendto error");

         return -1;

     }

     return 0;

@@ -192,7 +220,7 @@
     len = recvfrom(sockfd,recvline,LYNQ_REC_BUF, 0, (struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);

     if(len == -1)

     {

-        LYERRLOG("recvfrom error\n");

+        LYERRLOG("recvfrom error");

         return -1;

     }

     if (recvline != NULL) {

@@ -225,7 +253,7 @@
     client.request = 9;//RIL_REQUEST_GET_CURRENT_CALLS

     client.paramLen = 0;

     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);

-    LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s\n",client.uToken,client.request,client.paramLen,client.param);

+    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

@@ -245,7 +273,7 @@
             return 0;

         }

         lynq_call_state = CALL_ON;

-        LYINFLOG("lynq_call_state:%d",lynq_call_state);

+        LYINFLOG("lynq_call_state:%d, call num is %d ",lynq_call_state,call_num);

         for(int i = 0;i < call_num;i++)

         {

             p.readInt32(&temp);

@@ -281,12 +309,12 @@
 

 void cleanCallList(int lynq_call_id)

 {

+    LYINFLOG("cleanCall local idx is %d, id is %d",lynq_call_id,lynq_call_lists[lynq_call_id].call_id);

     lynq_call_lists[lynq_call_id].call_id = 0;

     lynq_call_lists[lynq_call_id].call_state = (int)LYNQ_CALL_END;

     lynq_call_lists[lynq_call_id].toa = 0;

     lynq_call_lists[lynq_call_id].direction = 0;

     lynq_call_lists[lynq_call_id].used = 0;

-    lynq_call_lists[lynq_call_id].hasTimeout = 0;

     memset(lynq_call_lists[lynq_call_id].addr,0,sizeof(lynq_call_lists[lynq_call_id].addr));

 }

 int getUnusedElement()

@@ -300,23 +328,22 @@
     }

     return -1;

 }

-int updateAddr(char addr[])

+int addAddr(char addr[])

 {

     int ret = 0;

     ret = getUnusedElement();

     memcpy(lynq_call_lists[ret].addr,addr,strlen(addr)+1);

     lynq_call_lists[ret].used = 1;

+    LYINFLOG("add local idx is %d addr is %s",ret,addr);

     return ret;

 }

 void updateCallList(lynq_call_list_e_t *callList,    int call_id,int call_state,int toa,int direction)

 {

-    LYINFLOG("Update Call List");

+    LYINFLOG("Update original local id is %d, new local id is %d",callList->call_id,call_id);

     callList->call_id = call_id;

     callList->call_state = call_state;

     callList->toa = toa;

-    callList->direction = direction;

-    callList->used = 1;

-    callList->hasTimeout = 0;

+    callList->direction = direction;   

     return;

 }

 int waitCallstateChange(int mtime)

@@ -348,28 +375,43 @@
 }

 int checkHasCall(char addr[])

 {

-    LYINFLOG("check has call");

     for(int i = 0;i<LYNQ_CALL_MAX;i++)

     {

         if(strcmp(lynq_call_lists[i].addr,addr)==0)

         {

+            LYINFLOG("checkHasCall addr is %s idx is %d id is %d",addr,i,lynq_call_lists[i].call_id);

             return 1;

         }

     }

+    LYINFLOG("checkHasCall addr is %s , no idx is found",addr);

     return 0;

 }

 int find_call_id_with_addr(char *addr)

 {

-    LYINFLOG("find call id with addr!!!");

     for(int id = 0; id < LYNQ_CALL_MAX; id++)

     {

-        if(strcmp(lynq_call_lists[id].addr,addr) == 0)

+        if(lynq_call_lists[id].used && (strcmp(lynq_call_lists[id].addr,addr) == 0))

         {

+            LYINFLOG("find addr  %s in local list, local idx is %d id is %d",addr,id,lynq_call_lists[id].call_id);

             return id;

         }

     }

+    LYINFLOG("find addr  %s in local list , not found",addr);

     return -1;

 }

+int find_call_id_with_call_id(int call_id)

+{

+    for(int id = 0; id < LYNQ_CALL_MAX; id++)

+    {

+        if(lynq_call_lists[id].used && (lynq_call_lists[id].call_id == call_id))

+        {

+            LYINFLOG("find id  %d in local list, local idx is %d, addr is %s",call_id,id,lynq_call_lists[id].addr);

+            return id;

+        }

+    }

+    LYINFLOG("find id  %d in local list , not found",call_id);

+    return INVALID_ID;

+}

 void sendSignalToWaitCallStateChange()

 {

     LYINFLOG("send Signal To Wait Call State Change");

@@ -393,7 +435,6 @@
     callList->direction = direction;

     memcpy(callList->addr,addr,strlen(addr)+1);

     callList->used = 1;

-    callList->hasTimeout = 0;

     return;

 }

 

@@ -401,120 +442,173 @@
 {

     int ret=0;

     bool call_end;

-    call_end = 0;//0:this call end,1:call on

     lynq_call_list_t call_list[LYNQ_CALL_MAX];

     int update=0;

+    int cnt;

+    int i,n;

+    

     while(call_list_loop)

     {

         update=0;

         pthread_mutex_lock(&s_urc_call_state_change_mutex);

         pthread_cond_wait(&s_urc_call_state_change_cond, &s_urc_call_state_change_mutex);

-        LYDBGLOG("triggerGetCallList event!!!\n");

+        LYDBGLOG("triggerGetCallList event!!!");

         memset(call_list,0,sizeof(call_list));

         ret = lynq_get_current_call_list(call_list);

         if(ret != 0)

         {

-            LYDBGLOG("get current call list failure!!!\n");

+            LYDBGLOG("get current call list failure!!!");

             continue;

         }

         LYINFLOG("++++++++++++++triggerGetCallList++++++++++++++");

-        for(int i = 0;i < LYNQ_CALL_MAX;i++)

+        LYINFLOG("clear local index begin");

+        cnt=0;

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

         {

-            if(strlen(lynq_call_lists[i].addr) != 0)

+            if(lynq_call_lists[i].used ==0)

+            {

+                continue;

+            }

+            cnt++;

+            LYINFLOG("local idx is %d id is %d addr is %s state is %d direction is %d",i,lynq_call_lists[i].call_id,lynq_call_lists[i].addr,lynq_call_lists[i].call_state,lynq_call_lists[i].direction);

+            

+            if(lynq_call_lists[i].call_id > 0)

             {

                 call_end = 0;

-                for(int id = 0; id < LYNQ_CALL_MAX; id++)

+                for(n = 0; n < LYNQ_CALL_MAX; n++)

                 {

-                    if(strcmp(call_list[id].addr,lynq_call_lists[i].addr) == 0)

+                    if(call_list[n].call_id == lynq_call_lists[i].call_id)

                     {

                         call_end = 1;

-                        LYINFLOG("find lynq call i %d, id %d!!!",i,id);

+                        LYINFLOG("find lynq call local idx %d, service idx %d  id is %d!!!",i,n,lynq_call_lists[i].call_id);

+                        break;

                     }

                 }

                 if(call_end == 0)

                 {

-                    LYINFLOG("MT hungup,then clean call info");

-                    cleanCallList(i);

-                    continue;

+                    LYINFLOG("MT hungup,then clean call info local idx is %d id is %d",i, lynq_call_lists[i].call_id);

+                    cleanCallList(i);                   

                 }

             } //fix bug API-54

+            else 

+            {

+                LYINFLOG("local id is 0");

+            }

+        }

+        LYINFLOG("clear local index end, local used cnt is %d", cnt);

+

+        LYINFLOG("add or update local index begin ");

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

+        {    

+            if(call_list[i].call_id==0)

+            {

+                break;

+            }

+

+            LYINFLOG("servie idx %d begin: call_id=%d, call_state=%d, direction=%d, addr=%s, toa=%d",i,call_list[i].call_id, call_list[i].call_state,

+                call_list[i].direction,call_list[i].addr,call_list[i].toa);

+        

             if(call_list[i].direction == 1)//MT call

             {

+                 LYINFLOG("This is a MT CALL");

                  /*MT CALL state code

                  **LYNQ_CALL_INCOMING = 4,

                  **LYNQ_CALL_WAITING = 5,

                  */

                 if((call_list[i].call_state ==4) || (call_list[i].call_state ==5))

                 {

-                    /*you call me, and i call you,One party failed to dial*/

-                    if(!checkHasCall(call_list[i].addr))

+#ifdef ECALL_SUPPORT

+                    if(lynq_ecall_is_running())

                     {

-                        lynqIncomingCallId = getUnusedElement();

-                        addCallListToLynqCallList(&lynq_call_lists[lynqIncomingCallId],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction,call_list[i].addr);

-                        sendSignalIncomingCall();

+                        lynq_call_hungup(&(call_list[i].call_id));

+                        continue;

                     }

-                    else

+#endif          

+                }

+                /*you call me, and i call you,One party failed to dial*/

+                n = find_call_id_with_addr(call_list[i].addr);

+                if(n ==INVALID_ID)

+                {

+                    n = addAddr(call_list[i].addr);

+                    updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

+                    lynqIncomingCallId = call_list[i].call_id;

+                    sendSignalIncomingCall();

+                }

+                else if(lynq_call_lists[n].call_state == call_list[i].call_state)

+                {

+                    LYINFLOG("state not changed, state is %d ",call_list[i].call_state);

+                    if(call_list[i].call_state ==4 || call_list[i].call_state ==5)

                     {

-                        int temp_call_id = find_call_id_with_addr(call_list[i].addr);

                         /*if call state not change,Maybe this call was ignored, so we need to continue to inform the user of 

                         **an incoming call until the status changes.

                         **fix bug API-54

                         */

-                        if((temp_call_id > 0) && (lynq_call_lists[temp_call_id].call_state == call_list[i].call_state))

-                        {

-                            sendSignalIncomingCall();

-                        }

+                        LYINFLOG("resend incoming call signal");

+                        sendSignalIncomingCall();

                     }

                 }

-                /*if state changed*/

-                else

+                else 

                 {

-                    /*update call state*/

-                    for(int n = 0 ; n < LYNQ_CALL_MAX; n++)

-                    {

-                        if(strcmp(call_list[i].addr,lynq_call_lists[n].addr)==0)

-                        {

-                            updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

-                            break;

-                        }

-                    }

-                }

+                    LYINFLOG("state changed from %d to %d",lynq_call_lists[n].call_state,call_list[i].call_state);

+                    

+                    updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

+                }                               

             }

             else

-            {

-                if(call_list[i].call_id==0)

+            {     

+                LYINFLOG("This is a MO CALL");

+                call_end = 0;

+                for(n = 0 ; n < LYNQ_CALL_MAX; n++)

                 {

-                    break;

-                }

-                for(int n = 0 ; n < LYNQ_CALL_MAX; n++)

-                {

-                    if((lynq_call_lists[n].hasTimeout == 1) && (strcmp(lynq_call_lists[n].addr,call_list[i].addr) == 0))

+                    if(lynq_call_lists[n].used && ((strcmp(call_list[i].addr,lynq_call_lists[n].addr)==0)||(call_list[i].call_id==lynq_call_lists[n].call_id)))

                     {

-                        cleanCallList(n);//if this call time out,need clean lynq call list.

-                        /*hangup call with call id*/

-                        lynq_call_hungup(&call_list[i].call_id);

-                        lynq_call_lists[n].hasTimeout==0;

+                        if(lynq_call_lists[n].call_id==0)

+                        {

+                             LYINFLOG("add a call id");

+                             update=1;

+                        }

+                        LYINFLOG("local idx %d updated, original call id is %d origial addr is %s original state is %d",n,lynq_call_lists[n].call_id,lynq_call_lists[n].addr,lynq_call_lists[n].call_state);                    

+                        updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

+                        call_end = 1;

+                        break;

+                    }                    

+                }

+

+                if(call_end == 0)

+                {  

+                    LYINFLOG("need to hangup id %d", call_list[i].call_id);

+#ifdef ECALL_SUPPORT

+                    if(is_ecall_dial==1)

+                    {

+                        LYINFLOG("ecall is dialing, for the timebeing, don't huangup");

                         continue;

                     }

-                    LYDBGLOG("lynq_call_lists n is %d, used is %d, addr is %s addr2 %s\n",

-                    n,lynq_call_lists[n].used,call_list[i].addr,lynq_call_lists[n].addr);

-                    if(lynq_call_lists[n].used && (strcmp(call_list[i].addr,lynq_call_lists[n].addr)==0))

-                    {

-                        LYINFLOG("updated\n");                    

-                        updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

-                        update=1;

-                        break;

-                    }

+#endif

+                    LYINFLOG("hang up service call id %d",call_list[i].call_id); 

+                    lynq_call_hungup(&(call_list[i].call_id));

                 }

-                LYDBGLOG("[count:%d]call_id=%d,call_state=%d,direction=%d,addr=%s,toa=%d",i,call_list[i].call_id,call_list[i].call_state,

-                call_list[i].direction,call_list[i].addr,call_list[i].toa);

             }

+            LYDBGLOG("servie idx %d end",i);

         }

+        LYINFLOG("add or update local index end ");

         s_call_urc_event_complete = 1;

-        if((isDial==1) && (update==1))

+        if(isDial==1)

         {

-            sendSignalToWaitCallStateChange();

-            isDial = 0;

+            LYINFLOG("now is dialing");

+            if(update==1)

+            {

+                LYINFLOG("find added call");

+                sendSignalToWaitCallStateChange();

+                isDial = 0;

+            }    

+            else

+            {

+                LYINFLOG("not find added call");

+            }                

+        }

+        else 

+        {

+            LYINFLOG("now is not dialing");

         }

         pthread_mutex_unlock(&s_urc_call_state_change_mutex);

     }

@@ -547,14 +641,14 @@
     /*

     if(inet_pton(AF_INET,"127.0.0.1", &lynq_socket_server_addr.sin_addr) <= 0)

     {

-        LYDBGLOG("[%s] is not a valid IPaddress\n", argv[1]);

+        LYDBGLOG("[%s] is not a valid IPaddress", argv[1]);

         exit(1);

     }

 */

     lynq_call_client_sockfd = socket(AF_INET, SOCK_DGRAM, 0);

     if(connect(lynq_call_client_sockfd, (struct sockaddr *)&lynq_socket_server_addr, sizeof(lynq_socket_server_addr)) == -1)

     {

-        LYERRLOG("connect error\n");

+        LYERRLOG("connect error");

         return -1;

     }

     #endif

@@ -583,10 +677,11 @@
         LYERRLOG("lynq_update_call_list_loop fail!!!");

         return -1;

     }

-    LYDBGLOG("lynq_update_call_list_loop success!!!\n");

+    LYDBGLOG("lynq_update_call_list_loop success!!!");

     return 0;

 

 }

+

 void *thread_urc_recv(void *parg)

 {

     int socket_fd = (int64_t)parg;

@@ -600,10 +695,12 @@
     Parcel *p = NULL;

     struct sockaddr_in dest_addr;

 #ifdef ECALL_SUPPORT

-    int ecall_ind;    

+    int ecall_ind;

+    int ecallId;

+    int unused_callid;

 #endif

 

-    LYINFLOG("thread_urc_recv in running....\n");

+    LYINFLOG("thread_urc_recv in running....");

     while(urc_call_recive_status)

     {

         bzero(urc_data,LYNQ_REC_BUF);

@@ -611,10 +708,10 @@
         len = recvfrom(socket_fd,urc_data,LYNQ_REC_BUF,0,(struct sockaddr *)&dest_addr,&addr_len);

         if(len <= 0)

         {

-            LYERRLOG("thread_urc_recv step2 fail\n");

+            LYERRLOG("thread_urc_recv step2 fail");

             break;

         }

-        LYDBGLOG("=====>urc data len<=====:%d\n",len);

+        LYDBGLOG("=====>urc data len<=====:%d",len);

         p = new Parcel();

         if(p==NULL)

         {

@@ -628,12 +725,12 @@
             p->readInt32(&resp_type);

             p->readInt32(&urcid);

             p->readInt32(&slot_id);

-            //LYDBGLOG("*******Warren test*******:resp_type=%d,urcid=%d,slot_id=%d\n",resp_type,urcid,slot_id);

+            //LYDBGLOG("*******Warren test*******:resp_type=%d,urcid=%d,slot_id=%d",resp_type,urcid,slot_id);

             switch (urcid)

             {

                 case 1001://RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED

                 {

-                    LYINFLOG("**************:resp_type=%d,urcid=%d,slot_id=%d\n",resp_type,urcid,slot_id);

+                    LYINFLOG("**************:resp_type=%d,urcid=%d,slot_id=%d",resp_type,urcid,slot_id);

                     lynqRespWatingEvent();

                     break;

                 }

@@ -648,24 +745,95 @@
                 case 1029://RIL_UNSOL_RINGBACK_TONE

                 case 3049://RIL_UNSOL_CALL_INFO_INDICATION

                 {

-                     LYINFLOG("**************:resp_type=%d,urcid=%d,slot_id=%d\n",resp_type,urcid,slot_id);

+                    LYINFLOG("**************:resp_type=%d,urcid=%d,slot_id=%d",resp_type,urcid,slot_id);

                     break;

                 }

 #ifdef ECALL_SUPPORT

                 case RIL_UNSOL_ECALL_INDICATIONS:

                 {

-                    p->readInt32(&ecall_ind);                  

-                    lynqIncomingEcallIndication=ecall_ind;

-                    if(LYNQ_ECALL_ACTIVE==lynqIncomingEcallIndication)

-                    {

-                        if(isDial==1)

-                        {                               

-                            p->readInt32(&lynqEcallId);

+                    p->readInt32(&ecall_ind);   

+                    g_lynqIncomingEcallIndication = ecall_ind;

+                    p->readInt32(&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,is_ecall_dial,isDial,g_ecallId);

+                    if(lynq_is_msd_suc(g_lynqIncomingEcallIndication)) 

+                    {                        

+                        if(is_ecall_dial)

+                        {

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

+                            is_ecall_dial=0;

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

+                            {

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

+                                  g_ecallId = ecallId;

+                                  unused_callid=addAddr("ecall");

+                                  lynq_call_lists[unused_callid].call_id=g_ecallId;

+                            }        

                             sendSignalToWaitCallStateChange();

-                            usleep(300*1000);

-                        }                              

-                    }     

+                        }        

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

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

+                            lynq_call_hungup(&ecallId);

+                        }   

+                        else 

+                        {

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

+                        }

+                    } 

+                    else if (LYNQ_ECALL_PSAP_CALLBACK_START == g_lynqIncomingEcallIndication)

+                    {

+                        if(lynq_ecall_is_running()==0)

+                        {

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

+                            is_ecall_dial=1;

+                            if(isDial)

+                            {

+                                LYINFLOG("stop normal dial");

+                                sendSignalToWaitCallStateChange();

+                            }

+                            else 

+                            {

+                                LYINFLOG("no normal dial");

+                            }                            

+                        }

+                        else 

+                        {

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

+                        }

+                    }

+                    else if (LYNQ_ECALL_ABNORMAL_HANGUP == g_lynqIncomingEcallIndication)

+                    {

+                        if(is_ecall_dial==0)                             

+                        {

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

+                            g_ecallId = INVALID_ID;

+                        }

+                        else 

+                        {

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

+                        }

+                    }

+                    else if (LYNQ_ECALL_DISCONNECTED == g_lynqIncomingEcallIndication ||

+                            LYNQ_ECALL_REDIAL_TIMER_OUT == g_lynqIncomingEcallIndication ||

+                            LYNQ_ECALL_T2_TIMER_OUT == g_lynqIncomingEcallIndication)

+                    {

+                        g_ecallId = INVALID_ID;

+                        if(is_ecall_dial)

+                        {

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

+                            is_ecall_dial=0;

+                            sendSignalToWaitCallStateChange();

+                        }

+                        else 

+                        {

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

+                        }

+                    }

+                    else 

+                    {

+                        LYINFLOG("not special indication");

+                    }                    

                     sendSignalIncomingECallEvent();

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

                     break;

                  }

 #endif

@@ -689,7 +857,7 @@
     socket_fd = socket(AF_INET,SOCK_DGRAM,0);

     if(socket_fd < 0)

     {

-        LYERRLOG("creaet socket for udp fail\n");

+        LYERRLOG("creaet socket for udp fail");

         return -1;

     }

     urc_local_addr.sin_family = AF_INET;

@@ -699,7 +867,7 @@
     rt = setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);

     if(rt<0)

     {

-        LYERRLOG("SO_REUSEADDR fail\n");

+        LYERRLOG("SO_REUSEADDR fail");

         return -1;

     }

     rt = bind(socket_fd ,(struct sockaddr*)&urc_local_addr, sizeof(urc_local_addr));

@@ -713,10 +881,10 @@
     rt = pthread_create(&lynq_call_urc_tid,&attr,thread_urc_recv,(void *)socket_fd);

     if(rt < 0)

     {

-        LYERRLOG("urc loop failure!!!\n");

+        LYERRLOG("urc loop failure!!!");

         return -1;

     }

-    LYDBGLOG("urc loop success!!!\n");

+    LYDBGLOG("urc loop success!!!");

     return 0;

 }

 int getSelfElement(char addr[])

@@ -737,7 +905,7 @@
 

 void lynq_call_state_change_test(int soc_id)

 {

-    LYDBGLOG("call state change,sim:%d\n",soc_id);

+    LYDBGLOG("call state change,sim:%d",soc_id);

 }

 int lynq_init_call(int uToken)

 {   

@@ -773,6 +941,7 @@
 }

 int lynq_deinit_call()

 {

+    int ret;

     if(g_lynq_call_init_flag == 0)

     {

         LYDBGLOG("lynq_deinit_call failed!!!");

@@ -781,7 +950,7 @@
     else

     {   

         g_lynq_call_init_flag = 0;

-        int ret = -1;

+        lynq_call_hungup_all();       

         if(lynq_call_client_sockfd>0)

         {

             close(lynq_call_client_sockfd);

@@ -824,7 +993,7 @@
         vsnprintf(client.param, LYNQ_REQUEST_PARAM_BUF, format, args);

         va_end(args);    

     }

-    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s\n",client.uToken,client.request,client.paramLen,client.param);

+    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

@@ -855,7 +1024,7 @@
     client.request = request_id;

     client.paramLen = 0;

     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);

-    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s\n",client.uToken,client.request,client.paramLen,client.param);

+    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

@@ -879,27 +1048,45 @@
     int slot_id = -1;

     int error = -1;

     int lynq_call_id = -1;

+

+    LYINFLOG("lynq_call begin addr %s",addr);

     if(addr==NULL)

     {

         LYERRLOG("Phone num is null!!!");

         return -1;

     }

+

+    if(find_call_id_with_addr(addr)!=INVALID_ID)

+    {

+        LYERRLOG("addr %s exists",addr);

+        return LYNQ_E_CONFLICT;

+    }

+

+#ifdef ECALL_SUPPORT

+    if(lynq_ecall_is_running())

+    {

+        LYERRLOG("lynq_fast_ecall ecall is running");

+        return LYNQ_E_ECALL_BEING_RUNNING;

+    }

+#endif   

+    

     client.uToken = Global_uToken_call;

     client.request = 10;//RIL_REQUEST_DIAL

     client.paramLen = 2;

     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);

     memcpy(client.param,addr,strlen(addr)+1);

     strcat(client.param," 0");

-    LYERRLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

+    lynq_call_id = addAddr(addr);

+    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

+        cleanCallList(lynq_call_id);   

         return -1;

     }

     get_response(lynq_call_client_sockfd,p);

     JumpHeader(p,&resp_type,&request,&slot_id,&error);

     LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);

-    lynq_call_id = updateAddr(addr);

     if(error==0)

     {

         isDial = 1;

@@ -907,14 +1094,28 @@
         {

             //if timeout,this call need destroy.

             isDial = 0;

-

             error = LYNQ_E_TIME_OUT;

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

-            lynq_call_lists[lynq_call_id].hasTimeout = 1;

+            LYERRLOG("lynq_call timeout:wait Call state fail!!! clear local idx %d",lynq_call_id);

+            cleanCallList(lynq_call_id);            

             return error;

         }

-    *handle = lynq_call_id;

+         isDial = 0;

+        *handle = lynq_call_lists[lynq_call_id].call_id;

+        if(*handle > 0)

+        {

+            LYINFLOG("lynq_call dial addr %s suc, id is %d",addr,*handle);

+            return 0;

+        }

+        else 

+        {   

+            LYERRLOG("lynq_call dial addr %s fail, invalid id",addr);

+            cleanCallList(lynq_call_id);      

+            return LYNQ_E_INVALID_ID_ANONALY;

+        }      

+        

     }

+    LYERRLOG("lynq_call dial addr %s fail, service error %d",addr, error);

+    cleanCallList(lynq_call_id);      

     return error;

 }

 int lynq_call_answer()

@@ -929,7 +1130,7 @@
     client.request = 40;//RIL_REQUEST_DIAL

     client.paramLen = 0;

     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);

-    LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s\n",client.uToken,client.request,client.paramLen,client.param);

+    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

@@ -949,7 +1150,7 @@
     int slot_id = -1;

     int error = -1;

     int call_id = 0;

-    int lynq_call_id = 0;

+    int lynq_call_id;

     if(handle==NULL||!((*handle>=0)&&(*handle<10)))

     {

         LYERRLOG("[%s] illegal input!!!!",__FUNCTION__);

@@ -959,10 +1160,9 @@
     client.request = 12;//RIL_REQUEST_HUNGUP

     client.paramLen = 1;

     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);

-    lynq_call_id = *handle;

-    call_id = lynq_call_lists[lynq_call_id].call_id;

+    call_id = *handle;

     sprintf(client.param,"%d",call_id);

-    LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s\n",client.uToken,client.request,client.paramLen,client.param);

+    LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

@@ -973,7 +1173,11 @@
     LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);

     if(error==0)

     {

-        cleanCallList(lynq_call_id);

+        lynq_call_id=find_call_id_with_call_id(call_id);

+        if(lynq_call_id!=INVALID_ID)

+        {

+            cleanCallList(lynq_call_id);

+        }        

     }

     return error;

 }

@@ -989,7 +1193,7 @@
     client.request = 17;//RIL_REQUEST_UDUB

     client.paramLen = 0;

     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);

-    LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s\n",client.uToken,client.request,client.paramLen,client.param);

+    LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);

     if(send_request(lynq_call_client_sockfd,&client)==-1)

     {

         LYERRLOG("send request fail");

@@ -1017,11 +1221,17 @@
 int lynq_get_current_call_state(int *handle,    int *call_state,int *toa,int *direction,char addr[])

 {

     int lynq_call_id = 0;

+    LYINFLOG("lynq_get_current_call_state begin ");

     if(handle==NULL)

     {

+        LYERRLOG("handle is NULL");

         return LYNQ_E_NULL_ANONALY;

     }

-    lynq_call_id = *handle;

+    lynq_call_id = find_call_id_with_call_id(*handle);

+    if(lynq_call_id==INVALID_ID)

+    {

+        return LYNQ_E_INVALID_ID_ANONALY;

+    }

     *call_state = lynq_call_lists[lynq_call_id].call_state;

     *toa = lynq_call_lists[lynq_call_id].toa;

     *direction = lynq_call_lists[lynq_call_id].direction;

@@ -1124,7 +1334,7 @@
 } 

 int lynq_incall_record_start(const char* file_path)

 {

-	return lynq_set_common_request(8011,2,"%s %s","1",file_path); //LYNQ_REQUEST_RECORD

+    return lynq_set_common_request(8011,2,"%s %s","1",file_path); //LYNQ_REQUEST_RECORD

 }

 int lynq_incall_record_stop()

 {

@@ -1178,7 +1388,7 @@
 

     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\n ",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 -1;

     }       

     

@@ -1192,20 +1402,23 @@
     return error;

 }

 

-

 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)

 {

-    int error = -1;

-    int lynq_call_id = -1;

+    int error;

     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)

+    if(lynq_ecall_is_running())

     {

-        LYERRLOG("msd_length %d is greater than %d, parameter error\n",msd_length,MSD_MAX_LENGTH);

-        return -1;

+        LYERRLOG("lynq_fast_ecall ecall is running");

+        return LYNQ_E_ECALL_BEING_RUNNING;

+    }

+

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

+    {

+        LYERRLOG("lynq_fast_ecall msd_length %d is greater than %d or <= 0, parameter error",msd_length,MSD_MAX_LENGTH);

+        return LYNQ_E_ECALL_MSD_LENGTH_ERROR;

     }    

 

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

@@ -1213,33 +1426,35 @@
         sprintf(&(lynq_msd_data[i<<1]),"%02x",msd_data[i]);

     }    

 

-    lynq_call_id = updateAddr(e_call_addr[lynq_ecall_variant]);

 

-    LYINFLOG("e_call_addr is %s\n",e_call_addr[lynq_ecall_variant]);

+    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);

    

     if(error==0)

-    {        

-        isDial = 1;

-        if(waitCallstateChange(30000)==ETIMEDOUT)//30000ms

+    {   

+        is_ecall_dial = 1;

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

         {

-            isDial = 0;

-            error = LYNQ_E_TIME_OUT;

-            cleanCallList(lynq_call_id);

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

-            return error;

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

+            is_ecall_dial = 0;

+            lynqRespWatingEvent();                

+            return LYNQ_E_TIME_OUT;

         }

-         

-        *handle = lynq_call_id;

-        if(lynq_ecall_variant==LYNQ_ECALL_EMERGENCY){

-            lynq_call_lists[lynq_call_id].call_id=lynqEcallId;

-        }

-        LYINFLOG("lynq_fast_ecall handle is:%d, call id is %d",lynq_call_id,lynq_call_lists[lynq_call_id].call_id);

+        is_ecall_dial = 0;

+        lynqRespWatingEvent();        

         

-    }

-    else {

-        cleanCallList(lynq_call_id);

+        if(g_ecallId != INVALID_ID)

+        {

+            *handle=g_ecallId;         

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

+            return 0;

+        }

+        else 

+        {

+            LYERRLOG("lynq_fast_ecall service return fail");

+            return LYNQ_E_INVALID_ID_ANONALY;

+        }               

     }

 

     return error;

@@ -1263,7 +1478,7 @@
 

     if(handle==NULL)

     {

-        LYERRLOG("handle is NULL, parameter error \n ");

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

            return -1;

     }

     

@@ -1273,13 +1488,12 @@
     {

         lynq_ecall_variant=lynq_get_lynq_ecall_variant_from_lynq_type(type);

       

-        lynq_call_id = updateAddr(e_call_addr[lynq_ecall_variant]);

+        lynq_call_id = addAddr(e_call_addr[lynq_ecall_variant]);

         isDial = 1;

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

         {

             error = LYNQ_E_TIME_OUT;

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

-            lynq_call_lists[lynq_call_id].hasTimeout = 1;

             return error;

         }

  

@@ -1295,23 +1509,31 @@
     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)

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

     {

-        LYERRLOG("handle is NULL or *handle %d is greater or equeal to %d or msd_length %d is greater than %d, parameter error\n",*handle,LYNQ_CALL_MAX,msd_length,MSD_MAX_LENGTH);

+        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 -1;

     }    

 

     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",lynq_call_lists[(*handle)].call_id,lynq_msd_data);

 }

 

 int lynq_set_ivs(int enable)

 {

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

+    if(enable<0)

+    {

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

+       return 0;

+    }

+

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

 }

 

 int lynq_reset_ivs()

@@ -1329,15 +1551,15 @@
     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);

+    pthread_mutex_unlock(&s_incoming_e_call_mutex); 

     return ret;

 }

 

 int lynq_wait_ecall_indication(LYNQ_ECall_Indication *eCall_Indication)

 {

     wait_ecall_event();

-    *eCall_Indication = lynqIncomingEcallIndication;

-    LYINFLOG("lynq incoming e-call indication id:%d",lynqIncomingEcallIndication);

+    *eCall_Indication = g_lynqIncomingEcallIndication;

+    LYINFLOG("lynq_wait_ecall_indication id: %d",g_lynqIncomingEcallIndication);

     return 0;

 }

 

@@ -1350,10 +1572,10 @@
     n = lynq_init_call(lynq_call_state_change_test,2222);

     if(n<0)

     {

-        LYDBGLOG("lynq init call fail!!!\n");

+        LYDBGLOG("lynq init call fail!!!");

         return -1;

     }

-    LYDBGLOG("lynq call init success!!!\n");

+    LYDBGLOG("lynq call init success!!!");

     char phoneNum[LYNQ_PHONE_NUMBER_MAX];

     sprintf(phoneNum,"18180053406 0",strlen("18180053406 0")+1);

     lynq_call(phoneNum);