From 22810fc63558bcc9e1af248f48480c2ba10faf99 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 7 Dec 2017 17:51:08 -0600 Subject: [PATCH] chan_pjsip/res_pjsip: Add CHANNEL(pjsip,request_uri) This patch does three things associated with the initial incoming INVITE request URI. 1) Add access to the full initial incoming INVITE request URI. 2) We were not setting DNID on incoming PJSIP channels. The DNID is the user portion of the initial incoming INVITE Request-URI. The value is accessed by reading CALLERID(dnid). 3) Fix CHANNEL(pjsip,target_uri) documentation. * The initial incoming INVITE request URI is now available using CHANNEL(pjsip,request_uri). * Set the DNID on PJSIP channel creation so CALLERID(dnid) can return the initial incoming INVITE request URI user portion. * CHANNEL(pjsip,target_uri) now correctly documents that the target URI is the contact URI. * Refactored print_escaped_uri() out of channel_read_pjsip() to handle pjsip_uri_print() error condition when the buffer is too small. ASTERISK-27478 Change-Id: I512e60d1f162395c946451becb37af3333337b33 --- channels/chan_pjsip.c | 5 +++ channels/pjsip/dialplan_functions.c | 50 ++++++++++++++++++++++------ include/asterisk/res_pjsip_session.h | 2 ++ res/res_pjsip_session.c | 6 ++++ 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index e4e8fa586b..69bcc187fd 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -605,6 +605,11 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id); ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id); + if (!ast_strlen_zero(exten)) { + /* Set provided DNID on the new channel. */ + ast_channel_dialed(chan)->number.str = ast_strdup(exten); + } + ast_channel_priority_set(chan, 1); ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup); diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c index 861edf72d3..aa376f8921 100644 --- a/channels/pjsip/dialplan_functions.c +++ b/channels/pjsip/dialplan_functions.c @@ -388,7 +388,7 @@ - The request URI of the INVITE request associated with the creation of this channel. + The contact URI where requests are sent. The local URI. @@ -402,6 +402,10 @@ Tag in To header + + The request URI of the incoming INVITE + associated with the creation of this channel. + The current state of any T.38 fax on this channel. @@ -656,6 +660,27 @@ static int channel_read_rtcp(struct ast_channel *chan, const char *type, const c return 0; } +static int print_escaped_uri(struct ast_channel *chan, const char *type, + pjsip_uri_context_e context, const void *uri, char *buf, size_t size) +{ + int res; + char *buf_copy; + + res = pjsip_uri_print(context, uri, buf, size); + if (res < 0) { + ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n", + ast_channel_name(chan), type, (int) size); + + /* Empty buffer that likely is not terminated. */ + buf[0] = '\0'; + return -1; + } + + buf_copy = ast_strdupa(buf); + ast_escape_quoted(buf_copy, buf, size); + return 0; +} + /*! * \internal \brief Handle reading signalling information */ @@ -664,6 +689,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); char *buf_copy; pjsip_dialog *dlg; + int res = 0; if (!channel) { ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan)); @@ -689,25 +715,27 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const return -1; #endif } else if (!strcmp(type, "target_uri")) { - pjsip_uri_print(PJSIP_URI_IN_REQ_URI, dlg->target, buf, buflen); - buf_copy = ast_strdupa(buf); - ast_escape_quoted(buf_copy, buf, buflen); + res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf, + buflen); } else if (!strcmp(type, "local_uri")) { - pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri, buf, buflen); - buf_copy = ast_strdupa(buf); - ast_escape_quoted(buf_copy, buf, buflen); + res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri, + buf, buflen); } else if (!strcmp(type, "local_tag")) { ast_copy_pj_str(buf, &dlg->local.info->tag, buflen); buf_copy = ast_strdupa(buf); ast_escape_quoted(buf_copy, buf, buflen); } else if (!strcmp(type, "remote_uri")) { - pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->remote.info->uri, buf, buflen); - buf_copy = ast_strdupa(buf); - ast_escape_quoted(buf_copy, buf, buflen); + res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, + dlg->remote.info->uri, buf, buflen); } else if (!strcmp(type, "remote_tag")) { ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen); buf_copy = ast_strdupa(buf); ast_escape_quoted(buf_copy, buf, buflen); + } else if (!strcmp(type, "request_uri")) { + if (channel->session->request_uri) { + res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, + channel->session->request_uri, buf, buflen); + } } else if (!strcmp(type, "t38state")) { ast_copy_string(buf, t38state_to_string[channel->session->t38state], buflen); } else if (!strcmp(type, "local_addr")) { @@ -743,7 +771,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const return -1; } - return 0; + return res; } /*! \brief Struct used to push function arguments to task processor */ diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index a0fc9650ee..732243f837 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -211,6 +211,8 @@ struct ast_sip_session { unsigned int ended_while_deferred:1; /*! DTMF mode to use with this session, from endpoint but can change */ enum ast_sip_dtmf_mode dtmf; + /*! Initial incoming INVITE Request-URI. NULL otherwise. */ + pjsip_uri *request_uri; }; typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 781d3e4eb7..55b91208a3 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2818,6 +2818,12 @@ static enum sip_get_destination_result get_destination(struct ast_sip_session *s ast_copy_pj_str(domain, &sip_ruri->host, size); pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain); + /* + * Save off the INVITE Request-URI in case it is + * needed: CHANNEL(pjsip,request_uri) + */ + session->request_uri = pjsip_uri_clone(session->inv_session->pool, ruri); + return SIP_GET_DEST_EXTEN_FOUND; }