diff options
author | Benny Prijono <bennylp@teluu.com> | 2009-06-25 11:17:17 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2009-06-25 11:17:17 +0000 |
commit | 797aabda451c71a989fad33d56443f63cd07d0b5 (patch) | |
tree | 97d55428725918a6dfac94625e9dcdc38e5ccbfa | |
parent | 97bef91a7682036ee3f43f072eec5e9a325a5d66 (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.c | 23 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 16 | ||||
-rw-r--r-- | tests/pjsua/scripts-sipp/uas-early-bye.xml | 68 | ||||
-rw-r--r-- | tests/pjsua/scripts-sipp/uas-forked-200.xml | 143 |
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> + |