[Bugfix][API-551][ecall] bug fix in lab certification test, from GSW-ECALL to main branch
Change-Id: Idf83ae02ee7d309efabc6b5782a063116b83b164
diff --git a/lib/liblynq-call/lynq_call.cpp b/lib/liblynq-call/lynq_call.cpp
index b90b44b..b0ba48a 100755
--- a/lib/liblynq-call/lynq_call.cpp
+++ b/lib/liblynq-call/lynq_call.cpp
@@ -179,9 +179,12 @@
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;
LYNQ_ECall_Indication g_lynqIncomingEcallIndication;
-int g_lynqIncomingEcallId;
+int g_lynqIncomingEcallId=INVALID_ID;
+LYNQ_ECall_Variant g_lynqEcallVariant=LYNQ_ECALL_VAR_NONE;
+int g_ecall_whether_preempt=0;
void sendSignalIncomingECallEvent()
{
@@ -196,7 +199,7 @@
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_T5_TIMER_OUT == lynqIncomingEcallIndication ||
LYNQ_ECALL_T6_TIMER_OUT == lynqIncomingEcallIndication ||
LYNQ_ECALL_T7_TIMER_OUT == lynqIncomingEcallIndication)
{
@@ -208,7 +211,22 @@
int lynq_ecall_is_running()
{
- return (is_ecall_dial!=LYNQ_ECALL_DAILING_STATE_NONE) || (g_ecallId !=INVALID_ID);
+ return (is_ecall_dial!=LYNQ_ECALL_DAILING_STATE_NONE) || (g_ecallId !=INVALID_ID || g_lynqEcallVariant == 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__,is_ecall_dial,g_ecallId,g_lynqEcallVariant,g_lynqIncomingEcallIndication,g_lynqIncomingEcallId,g_ecall_whether_preempt);
+}
+
+int lynq_ecall_is_permit_in_call(int ecall_id)
+{
+ return g_lynqEcallVariant == LYNQ_ECALL_CALLBACK && (g_ecallId ==INVALID_ID || g_ecallId ==ecall_id);
+}
+
+int lynq_ecall_is_in_voice()
+{
+ return (is_ecall_dial==LYNQ_ECALL_DAILING_STATE_NONE) && (g_ecallId !=INVALID_ID);
}
#endif
@@ -481,6 +499,9 @@
int update=0;
int cnt;
int i,n;
+#ifdef ECALL_SUPPORT
+ int handupIncomingMT=0;
+#endif
while(call_list_loop)
{
@@ -550,16 +571,21 @@
**LYNQ_CALL_INCOMING = 4,
**LYNQ_CALL_WAITING = 5,
*/
+#ifdef ECALL_SUPPORT
if((call_list[i].call_state ==4) || (call_list[i].call_state ==5))
{
-#ifdef ECALL_SUPPORT
- if(lynq_ecall_is_running())
+
+ pthread_mutex_lock(&s_ecall_variable_mutex);
+ handupIncomingMT=lynq_ecall_is_running() && (lynq_ecall_is_permit_in_call(call_list[i].call_id)==false);
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
+ LYINFLOG("handupIncomingMT is %d",handupIncomingMT);
+ if(handupIncomingMT)
{
lynq_call_hungup(&(call_list[i].call_id));
continue;
- }
-#endif
+ }
}
+#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)
@@ -741,6 +767,8 @@
int ecall_ind;
int ecallId;
int unused_callid;
+ int send_signal_to_wait_call_state;
+ int handup_ecall_id;
#endif
LYINFLOG("thread_urc_recv in running....");
@@ -794,6 +822,9 @@
#ifdef ECALL_SUPPORT
case RIL_UNSOL_ECALL_INDICATIONS:
{
+ pthread_mutex_lock(&s_ecall_variable_mutex);
+ send_signal_to_wait_call_state = false;
+ handup_ecall_id=false;
p->readInt32(&ecall_ind);
g_lynqIncomingEcallIndication = ecall_ind;
p->readInt32(&ecallId);
@@ -807,10 +838,17 @@
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);
+ g_lynqIncomingEcallIndication = 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:
+ //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(is_ecall_dial)
@@ -823,13 +861,13 @@
g_ecallId = ecallId;
unused_callid=addAddr("ecall");
lynq_call_lists[unused_callid].call_id=g_ecallId;
- }
- sendSignalToWaitCallStateChange();
+ }
+ send_signal_to_wait_call_state=true;
}
- else if(ecallId >0 && (find_call_id_with_call_id(ecallId)==INVALID_ID))
+ else if(ecallId >0 && (find_call_id_with_call_id(ecallId)==INVALID_ID) && (g_lynqEcallVariant != LYNQ_ECALL_CALLBACK))
{
LYERRLOG("ecall is not in dialing and first recv suc indication, hangup");
- lynq_call_hungup(&ecallId);
+ handup_ecall_id=true;
}
else
{
@@ -839,25 +877,26 @@
case LYNQ_ECALL_PSAP_CALLBACK_START:
if(lynq_ecall_is_running()==0)
{
- LYINFLOG("ecall is not running, recv psap call back msd start, set ecall in dialing");
- if(find_call_id_with_call_id(ecallId)!=INVALID_ID)
- {
+ if(ecallId>0)
+ {
+ LYINFLOG("ecall is not running, recv psap call back msd start, set ecall running");
+ g_lynqEcallVariant = LYNQ_ECALL_CALLBACK;
g_ecallId = ecallId;
if(isDial)
{
LYINFLOG("stop normal dial");
- sendSignalToWaitCallStateChange();
+ send_signal_to_wait_call_state=true;
}
else
{
LYINFLOG("no normal dial");
- }
+ }
}
else
{
- LYERRLOG("can't find ecall id in local list");
- }
- }
+ LYERRLOG("ecallId is abnormal in psap callback");
+ }
+ }
else
{
LYERRLOG("ecall is running, recv psap call back msd start");
@@ -873,7 +912,7 @@
{
LYERRLOG("ecall is in dialing state, recv no answer, recv abnormal hangup, dont' redial");
g_ecallId = INVALID_ID;
- sendSignalToWaitCallStateChange();
+ send_signal_to_wait_call_state=true;
}
else {
LYINFLOG("ecall is in dialing and recv answer, recv abnormal hangup");
@@ -882,13 +921,17 @@
case LYNQ_ECALL_DISCONNECTED:
case LYNQ_ECALL_REDIAL_TIMER_OUT:
case LYNQ_ECALL_T2_TIMER_OUT :
- case LYNQ_ECALL_IMS_DISCONNECTED:
+ case LYNQ_ECALL_IMS_DISCONNECTED:
g_ecallId = INVALID_ID;
+ if(g_lynqEcallVariant == LYNQ_ECALL_CALLBACK)
+ {
+ g_lynqEcallVariant = LYNQ_ECALL_VAR_NONE; /*other type, needn't re-initialize*/
+ }
if(is_ecall_dial != LYNQ_ECALL_DAILING_STATE_NONE)
{
LYERRLOG("ecall is in dialing, recv like disconnect indication");
- is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
- sendSignalToWaitCallStateChange();
+ is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
+ send_signal_to_wait_call_state=true;
}
else
{
@@ -897,8 +940,17 @@
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", g_ecallId);
break;
}
@@ -1380,6 +1432,21 @@
return 0;
}
+int lynq_get_current_call_number()
+{
+ int cnt=0;
+ int i;
+ for(i = 0;i < LYNQ_CALL_MAX;i++)
+ {
+ if(lynq_call_lists[i].used !=0)
+ {
+ cnt++;
+ }
+ }
+
+ return cnt;
+}
+
/*audio begin*/
static int judge_mic(const int enable){
switch(enable){
@@ -1645,24 +1712,137 @@
return error;
}
+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 = (g_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;
+ if(lynq_call_hungup_all()!=0)
+ {
+ LYERRLOG("ecall clear conflict call, hangup all failure");
+ return -1;
+ }
+ cnt=0;
+ while(lynq_get_current_call_number()!=0 && cnt<80)
+ {
+ lynqRespWatingEvent();
+ 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 -2;
+ }
+
+ LYINFLOG("ecall clear conflict call, after %d 0.2s, call list is cleared", cnt);
+ return 0;
+}
+
+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(g_ecall_whether_preempt & 0x02)
+ {
+ ret=lynq_clear_current_call();
+ LYERRLOG("ecall clear conflict call, relase current normal call ret is %d",ret);
+ }
+ return 0;
+ }
+
+ 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,g_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 -1;
+ }
+
+ ret=lynq_clear_current_call();
+ LYINFLOG("ecall clear conflict call, relase current call(including ecall) ret is %d",ret);
+
+ if(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 0;
+}
+
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;
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(lynq_ecall_is_running())
+ unsigned int i;
+
+ if(msd_length > MSD_MAX_LENGTH || msd_length <=0 || lynq_ecall_variant >=LYNQ_ECALL_MO_MAX)
{
- 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);
+ LYERRLOG("lynq_fast_ecall msd_length %d or ecall variant %d parameter error",msd_length,lynq_ecall_variant);
return LYNQ_E_ECALL_MSD_LENGTH_ERROR;
- }
+ }
+
+ if(lynq_clear_current_conflict_call(g_lynqEcallVariant,lynq_ecall_variant)!=0)
+ {
+ LYERRLOG("%s call lynq_clear_current_conflict_call false, old is %d, new is %d",__func__,g_lynqEcallVariant,lynq_ecall_variant);
+ return LYNQ_E_ECALL_BEING_RUNNING;
+ }
+
+ pthread_mutex_lock(&s_ecall_variable_mutex);
+ is_ecall_dial = LYNQ_ECALL_DAILING_STATE_STARTED;
+ g_lynqEcallVariant = lynq_ecall_variant;
+ g_ecallId = INVALID_ID;
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
for(i =0; i<msd_length;i++)
{
@@ -1676,20 +1856,23 @@
if(error==0)
{
- is_ecall_dial = LYNQ_ECALL_DAILING_STATE_STARTED;
if(waitCallstateChange(270000)==ETIMEDOUT)//4.5 min, dailing 1 min, alerting 1 min, sending msd 30s, redial 2min
{
- LYERRLOG("lynq_fast_ecall timeout:wait Call state time out!!!");
- is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
- lynqRespWatingEvent();
+ pthread_mutex_lock(&s_ecall_variable_mutex);
+ LYERRLOG("lynq_fast_ecall timeout:wait Call state time out!!!");
+ is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
+ lynqRespWatingEvent();
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
return LYNQ_E_TIME_OUT;
}
+ pthread_mutex_lock(&s_ecall_variable_mutex);
if(is_ecall_dial == LYNQ_ECALL_DAILING_STATE_STARTED)
{
/*just dail, no recv answer*/
LYERRLOG("lynq_fast_ecall, no answer!");
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
- lynqRespWatingEvent();
+ lynqRespWatingEvent();
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
return LYNQ_E_ECALL_DAILING_NO_ANSWER;
}
@@ -1700,15 +1883,21 @@
{
*handle=g_ecallId;
LYINFLOG("lynq_fast_ecall id is %d",g_ecallId);
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
return 0;
}
- else
- {
- LYERRLOG("lynq_fast_ecall service return fail");
- return LYNQ_E_INVALID_ID_ANONALY;
- }
+
+ LYERRLOG("lynq_fast_ecall service return fail");
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
+ return LYNQ_E_INVALID_ID_ANONALY;
}
+ pthread_mutex_lock(&s_ecall_variable_mutex);
+ is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
+ g_lynqEcallVariant = LYNQ_ECALL_VAR_NONE;
+ g_ecallId = INVALID_ID;
+ pthread_mutex_unlock(&s_ecall_variable_mutex);
+
return error;
}
@@ -1761,7 +1950,7 @@
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)
+ 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 -1;
@@ -1774,16 +1963,29 @@
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);
+ return lynq_set_common_request(RIL_REQUEST_ECALL_SET_MSD,2,"%d %s",*handle,lynq_msd_data);
}
int lynq_set_ivs(int enable)
{
+#ifdef ECALL_SUPPORT
if(enable<0)
{
- lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);
+ if(enable >-100)
+ {
+ lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);
+ }
+ else if(enable== -1000)
+ {
+ print_ecall_info();
+ }
+ else
+ {
+ g_ecall_whether_preempt= ((-100-enable) & 0x11);
+ }
return 0;
}
+#endif
return lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);
}
@@ -1870,14 +2072,14 @@
sprintf(cmd,RTP_FROM_CMD, \
g_rtp_client_info.port,g_rtp_client_info.clockrate,g_rtp_client_info.channels, \
g_rtp_client_info.latency);
- LYINFLOG("start from rtp play: cmd is %s",cmd);
+ // LYINFLOG("start from rtp play: cmd is %s",cmd);
system(cmd);
}
else if ((*rtp_mode) == RTP_SERVER)
{
sprintf(cmd,RTP_TO_CMD, \
g_rtp_server_info.ip,g_rtp_server_info.port);
- LYINFLOG("start to rtp play: cmd is %s",cmd);
+ // LYINFLOG("start to rtp play: cmd is %s",cmd);
system(cmd);
}
return NULL;