summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-06-25 11:17:17 +0000
committerBenny Prijono <bennylp@teluu.com>2009-06-25 11:17:17 +0000
commit797aabda451c71a989fad33d56443f63cd07d0b5 (patch)
tree97d55428725918a6dfac94625e9dcdc38e5ccbfa
parent97bef91a7682036ee3f43f072eec5e9a325a5d66 (diff)
Ticket #799: UAC disconnect call when receiving BYE in early state (thanks Gang Liu for the suggestion)
- backported changes from #798 git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.0@2800 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/pjsua/pjsua_app.c23
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c16
-rw-r--r--tests/pjsua/scripts-sipp/uas-early-bye.xml68
-rw-r--r--tests/pjsua/scripts-sipp/uas-forked-200.xml143
4 files changed, 246 insertions, 4 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index 95aa3bba..7caf8c2a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -3759,9 +3759,15 @@ void console_app_main(const pj_str_t *uri_to_call)
ui_input_url("Destination URI", buf, sizeof(buf), &result);
if (result.nb_result != NO_NB) {
- if (result.nb_result == -1 || result.nb_result == 0) {
+ if (result.nb_result == -1) {
puts("Sorry you can't do that!");
continue;
+ } else if (result.nb_result == 0) {
+ uri = NULL;
+ if (current_call == PJSUA_INVALID_ID) {
+ puts("No current call");
+ continue;
+ }
} else {
pjsua_buddy_info binfo;
pjsua_buddy_get_info(result.nb_result-1, &binfo);
@@ -3772,9 +3778,18 @@ void console_app_main(const pj_str_t *uri_to_call)
uri = result.uri_result;
}
- tmp = pj_str(uri);
-
- send_request(text, &tmp);
+ if (uri) {
+ tmp = pj_str(uri);
+ send_request(text, &tmp);
+ } else {
+ /* If you send call control request using this method
+ * (such requests includes BYE, CANCEL, etc.), it will
+ * not go well with the call state, so don't do it
+ * unless it's for testing.
+ */
+ pj_str_t method = pj_str(text);
+ pjsua_call_send_request(current_call, &method, NULL);
+ }
break;
case 'e':
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 0b3ba5ff..e2062ef4 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -3359,6 +3359,22 @@ static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e)
/* Generic handling for UAC tsx completion */
handle_uac_tsx_response(inv, e);
+
+ } else if (tsx->role == PJSIP_ROLE_UAS &&
+ tsx->method.id == PJSIP_BYE_METHOD &&
+ tsx->status_code < 200 &&
+ e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
+ {
+ /* Received BYE before the 2xx/OK response to INVITE.
+ * Assume that the 2xx/OK response is lost and the BYE
+ * arrives earlier.
+ */
+ inv_respond_incoming_bye(inv, tsx, e->body.tsx_state.src.rdata, e);
+
+ /* Set timer just in case we will never get the final response
+ * for INVITE.
+ */
+ pjsip_tsx_set_timeout(inv->invite_tsx, 64*pjsip_cfg()->tsx.t1);
}
}
diff --git a/tests/pjsua/scripts-sipp/uas-early-bye.xml b/tests/pjsua/scripts-sipp/uas-early-bye.xml
new file mode 100644
index 00000000..216b8b45
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-early-bye.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="Early BYE">
+ <recv request="INVITE" crlf="true">
+ <action>
+ <ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
+ <ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
+ <assign assign_to="4" variable="5" />
+ </action>
+ </recv>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 100 Trying
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 180 Ringing
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ BYE sip:[$5] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+ To[$3]
+ Call-ID: [call_id]
+ Cseq: 1 BYE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <recv response="200">
+ </recv>
+
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/pjsua/scripts-sipp/uas-forked-200.xml b/tests/pjsua/scripts-sipp/uas-forked-200.xml
new file mode 100644
index 00000000..229f7d89
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-forked-200.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program is free software; you can redistribute it and/or -->
+<!-- modify it under the terms of the GNU General Public License as -->
+<!-- published by the Free Software Foundation; either version 2 of the -->
+<!-- License, or (at your option) any later version. -->
+<!-- -->
+<!-- This program is distributed in the hope that it will be useful, -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
+<!-- GNU General Public License for more details. -->
+<!-- -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with this program; if not, write to the -->
+<!-- Free Software Foundation, Inc., -->
+<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
+<!-- -->
+<!-- Sipp default 'uas' scenario. -->
+<!-- -->
+
+<scenario name="Forked INVITE, one of them require PRACK">
+ <recv request="INVITE" crlf="true">
+ <action>
+ <ereg regexp="branch=([0-9a-zA-Z]*)"
+ search_in="hdr"
+ header="Via"
+ assign_to="1,2"/>
+ <assign assign_to="1" variable="2"/>
+ </action>
+ </recv>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 100 Trying
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ ]]>
+ </send>
+
+ <!-- Call leg 1: 200/OK -->
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ Via: SIP/2.0/UDP 127.0.0.1;received=127.0.0.1;rport=5080;branch=[$2]
+ [last_From:]
+ [last_To:];tag=UA_1
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:UA_1@[local_ip]:[local_port]>
+ Content-Type: application/sdp
+
+ v=0
+ o=- 3442013205 3442013205 IN IP4 192.168.0.13
+ s=pjsip
+ c=IN IP4 192.168.0.13
+ t=0 0
+ m=audio 4002 RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+ ]]>
+ </send>
+
+ <!-- Call leg 2: 200/OK -->
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ Via: SIP/2.0/UDP 127.0.0.1;received=127.0.0.1;rport=5080;branch=[$2]
+ [last_From:]
+ [last_To:];tag=UA_2
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:UA_2@[local_ip]:[local_port]>
+ Content-Type: application/sdp
+
+ v=0
+ o=- 3442013205 3442013205 IN IP4 192.168.0.13
+ s=pjsip
+ c=IN IP4 192.168.0.13
+ t=0 0
+ m=audio 4002 RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+ ]]>
+ </send>
+
+ <!-- Receive ACK -->
+ <recv request="ACK"
+ optional="false"
+ rtd="true"
+ crlf="true">
+ </recv>
+
+ <!-- Receive BYE -->
+ <recv request="BYE" crlf="true">
+ </recv>
+
+ <!-- Send 200/OK to BYE -->
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ ]]>
+ </send>
+
+
+
+ <!-- Receive ACK -->
+ <recv request="ACK"
+ optional="false"
+ rtd="true"
+ crlf="true">
+ </recv>
+
+ <!-- Receive BYE -->
+ <recv request="BYE" crlf="true">
+ </recv>
+
+ <!-- Send 200/OK to BYE -->
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ ]]>
+ </send>
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+