summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-12-31 22:51:04 +0000
committerJoshua Colp <jcolp@digium.com>2013-12-31 22:51:04 +0000
commitf720a9ac89f2045f4a60325b661ce85afec95081 (patch)
tree1696346739424c2f87fad9fe128e406a6c5b6658
parente583dca9dd7823489067a67311d30583ba1ad3c6 (diff)
chan_pjsip: Handle hanging up before calling.
Channel creation in Asterisk is broken up into two steps: requesting and calling. In some cases a channel may be requested but never called. This happens in the ChanIsAvail dialplan application for determining if something is reachable or not. The PJSIP channel driver did not take this situation into account and attempted to end a session that was never called out on. The code now checks the session state to determine if the session has been called out on and if not terminates it instead of ending it. (closes issue ASTERISK-23074) Reported by: Kilburn ........ Merged revisions 404652 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@404653 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_pjsip.c21
-rw-r--r--res/res_pjsip_session.c10
2 files changed, 21 insertions, 10 deletions
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index a560d7706..0fbfd9ea5 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -1429,8 +1429,6 @@ static void clear_session_and_channel(struct ast_sip_session *session, struct as
static int hangup(void *data)
{
- pj_status_t status;
- pjsip_tx_data *packet = NULL;
struct hangup_data *h_data = data;
struct ast_channel *ast = h_data->chan;
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
@@ -1438,12 +1436,19 @@ static int hangup(void *data)
struct ast_sip_session *session = channel->session;
int cause = h_data->cause;
- if (!session->defer_terminate &&
- ((status = pjsip_inv_end_session(session->inv_session, cause ? cause : 603, NULL, &packet)) == PJ_SUCCESS) && packet) {
- if (packet->msg->type == PJSIP_RESPONSE_MSG) {
- ast_sip_session_send_response(session, packet);
- } else {
- ast_sip_session_send_request(session, packet);
+ if (!session->defer_terminate) {
+ pj_status_t status;
+ pjsip_tx_data *packet = NULL;
+
+ if (session->inv_session->state == PJSIP_INV_STATE_NULL) {
+ pjsip_inv_terminate(session->inv_session, cause ? cause : 603, PJ_TRUE);
+ } else if (((status = pjsip_inv_end_session(session->inv_session, cause ? cause : 603, NULL, &packet)) == PJ_SUCCESS)
+ && packet) {
+ if (packet->msg->type == PJSIP_RESPONSE_MSG) {
+ ast_sip_session_send_response(session, packet);
+ } else {
+ ast_sip_session_send_request(session, packet);
+ }
}
}
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 04220094f..caaed317a 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -1826,14 +1826,20 @@ static int session_end(struct ast_sip_session *session)
static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
{
struct ast_sip_session *session = inv->mod_data[session_module.id];
+ pjsip_event_id_e type;
- print_debug_details(inv, NULL, e);
+ if (e) {
+ print_debug_details(inv, NULL, e);
+ type = e->type;
+ } else {
+ type = PJSIP_EVENT_UNKNOWN;
+ }
if (!session) {
return;
}
- switch(e->type) {
+ switch(type) {
case PJSIP_EVENT_TX_MSG:
handle_outgoing(session, e->body.tx_msg.tdata);
break;