[asterisk-commits] rmudgett: branch 12 r413210 - in /branches/12: ./ channels/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 2 11:34:09 CDT 2014


Author: rmudgett
Date: Fri May  2 11:33:59 2014
New Revision: 413210

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=413210
Log:
res_pjsip_refer: Add Referred-By header on INVITE for blind transfers.

Per rfc3892, the Referred-By header in a REFER must be copied into the
referenced request (IE.  The outgoing INVITE to the transfer target).

* Automatically put the Referred-By header in the outgoing INVITE message
if the SIPREFERREDBYHDR channel variable is defined with a value.

* Made chan_sip.c:get_refer_info() set SIPREFERREDBYHDR for inheritance so
chan_pjsip has a better chance to interoperate.

* Fixed refer_blind_callback() and refer_incoming_refer_request() to not
modify the data in the pointer returned by pjsip_msg_find_hdr_by_name().
It seems wrong to modify that data since the calling routine doesn't own
the buffer.

ASTERISK-23501 #close
Reported by: John Bigelow

Review: https://reviewboard.asterisk.org/r/3514/

Modified:
    branches/12/UPGRADE.txt
    branches/12/channels/chan_sip.c
    branches/12/res/res_pjsip_refer.c

Modified: branches/12/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/branches/12/UPGRADE.txt?view=diff&rev=413210&r1=413209&r2=413210
==============================================================================
--- branches/12/UPGRADE.txt (original)
+++ branches/12/UPGRADE.txt Fri May  2 11:33:59 2014
@@ -24,6 +24,10 @@
 
  - The asterisk command line -I option and the asterisk.conf internal_timing
    option are removed and always enabled if any timing module is loaded.
+
+chan_sip:
+ - Made set SIPREFERREDBYHDR as inheritable for better chan_pjsip
+   interoperability.
 
 From 12.1.0 to 12.2.0:
 

Modified: branches/12/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/channels/chan_sip.c?view=diff&rev=413210&r1=413209&r2=413210
==============================================================================
--- branches/12/channels/chan_sip.c (original)
+++ branches/12/channels/chan_sip.c Fri May  2 11:33:59 2014
@@ -18203,8 +18203,10 @@
 
 		peer = ast_channel_bridge_peer(owner_ref);
 		if (peer) {
-			pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context);
-			pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by);
+			pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT",
+				S_OR(transferer->context, NULL));
+			pbx_builtin_setvar_helper(peer, "__SIPREFERREDBYHDR",
+				S_OR(p_referred_by, NULL));
 			ast_channel_unlock(peer);
 		}
 

Modified: branches/12/res/res_pjsip_refer.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip_refer.c?view=diff&rev=413210&r1=413209&r2=413210
==============================================================================
--- branches/12/res/res_pjsip_refer.c (original)
+++ branches/12/res/res_pjsip_refer.c Fri May  2 11:33:59 2014
@@ -476,8 +476,9 @@
 static void refer_blind_callback(struct ast_channel *chan, void *user_data, enum ast_transfer_type transfer_type)
 {
 	struct refer_blind *refer = user_data;
-	const pj_str_t str_referred_by = { "Referred-By", 11 };
-	pjsip_generic_string_hdr *referred_by = pjsip_msg_find_hdr_by_name(refer->rdata->msg_info.msg, &str_referred_by, NULL);
+	pjsip_generic_string_hdr *referred_by;
+
+	static const pj_str_t str_referred_by = { "Referred-By", 11 };
 
 	pbx_builtin_setvar_helper(chan, "SIPTRANSFER", "yes");
 
@@ -544,29 +545,36 @@
 		}
 	}
 
-	if (!ast_strlen_zero(refer->context)) {
-		pbx_builtin_setvar_helper(chan, "SIPREFERRINGCONTEXT", refer->context);
-	}
-
+	pbx_builtin_setvar_helper(chan, "SIPREFERRINGCONTEXT", S_OR(refer->context, NULL));
+
+	referred_by = pjsip_msg_find_hdr_by_name(refer->rdata->msg_info.msg,
+		&str_referred_by, NULL);
 	if (referred_by) {
-		char *uri = referred_by->hvalue.ptr;
-
-		uri[referred_by->hvalue.slen] = '\0';
-		pbx_builtin_setvar_helper(chan, "SIPREFERREDBYHDR", uri);
+		size_t uri_size = pj_strlen(&referred_by->hvalue) + 1;
+		char *uri = ast_alloca(uri_size);
+
+		ast_copy_pj_str(uri, &referred_by->hvalue, uri_size);
+		pbx_builtin_setvar_helper(chan, "__SIPREFERREDBYHDR", S_OR(uri, NULL));
+	} else {
+		pbx_builtin_setvar_helper(chan, "SIPREFERREDBYHDR", NULL);
 	}
 
 	if (refer->replaces) {
 		char replaces[512];
 
 		pjsip_hdr_print_on(refer->replaces, replaces, sizeof(replaces));
-		pbx_builtin_setvar_helper(chan, "SIPREPLACESHDR", replaces);
+		pbx_builtin_setvar_helper(chan, "__SIPREPLACESHDR", S_OR(replaces, NULL));
+	} else {
+		pbx_builtin_setvar_helper(chan, "SIPREPLACESHDR", NULL);
 	}
 
 	if (refer->refer_to) {
 		char refer_to[PJSIP_MAX_URL_SIZE];
 
 		pjsip_uri_print(PJSIP_URI_IN_REQ_URI, refer->refer_to, refer_to, sizeof(refer_to));
-		pbx_builtin_setvar_helper(chan, "SIPREFERTOHDR", refer_to);
+		pbx_builtin_setvar_helper(chan, "SIPREFERTOHDR", S_OR(refer_to, NULL));
+	} else {
+		pbx_builtin_setvar_helper(chan, "SIPREFERTOHDR", NULL);
 	}
 }
 
@@ -811,16 +819,16 @@
 
 static int refer_incoming_refer_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 {
-	const pj_str_t str_refer_to = { "Refer-To", 8 };
 	pjsip_generic_string_hdr *refer_to;
-	char *uri;
-	const pj_str_t str_to = { "To", 2 };
 	pjsip_fromto_hdr *target;
 	pjsip_sip_uri *target_uri;
 	RAII_VAR(struct refer_progress *, progress, NULL, ao2_cleanup);
-	const pj_str_t str_replaces = { "Replaces", 8 };
 	pjsip_param *replaces;
 	int response;
+
+	static const pj_str_t str_refer_to = { "Refer-To", 8 };
+	static const pj_str_t str_to = { "To", 2 };
+	static const pj_str_t str_replaces = { "Replaces", 8 };
 
 	if (!session->endpoint->allowtransfer) {
 		pjsip_dlg_respond(session->inv_session->dlg, rdata, 603, NULL, NULL, NULL);
@@ -830,18 +838,25 @@
 	}
 
 	/* A Refer-To header is required */
-	if (!(refer_to = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL))) {
+	refer_to = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL);
+	if (!refer_to) {
 		pjsip_dlg_respond(session->inv_session->dlg, rdata, 400, NULL, NULL, NULL);
 		ast_debug(3, "Received a REFER without Refer-To on channel '%s' from endpoint '%s'\n",
 			ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint));
 		return 0;
 	}
-	uri = refer_to->hvalue.ptr;
-	uri[refer_to->hvalue.slen] = '\0';
 
 	/* Parse the provided URI string as a To header so we can get the target */
-	if (!(target = pjsip_parse_hdr(rdata->tp_info.pool, &str_to, refer_to->hvalue.ptr, refer_to->hvalue.slen, NULL)) ||
-		(!PJSIP_URI_SCHEME_IS_SIP(target->uri) && !PJSIP_URI_SCHEME_IS_SIPS(target->uri))) {
+	target = pjsip_parse_hdr(rdata->tp_info.pool, &str_to,
+		(char *) pj_strbuf(&refer_to->hvalue), pj_strlen(&refer_to->hvalue), NULL);
+	if (!target
+		|| (!PJSIP_URI_SCHEME_IS_SIP(target->uri)
+			&& !PJSIP_URI_SCHEME_IS_SIPS(target->uri))) {
+		size_t uri_size = pj_strlen(&refer_to->hvalue) + 1;
+		char *uri = ast_alloca(uri_size);
+
+		ast_copy_pj_str(uri, &refer_to->hvalue, uri_size);
+
 		pjsip_dlg_respond(session->inv_session->dlg, rdata, 400, NULL, NULL, NULL);
 		ast_debug(3, "Received a REFER without a parseable Refer-To ('%s') on channel '%s' from endpoint '%s'\n",
 			uri, ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint));
@@ -910,16 +925,25 @@
 
 static void refer_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
 {
-	const char *replaces;
-
-	if (pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_invite_method) ||
-		!session->channel ||
-		(session->inv_session->state != PJSIP_INV_STATE_CALLING) ||
-		!(replaces = pbx_builtin_getvar_helper(session->channel, "SIPREPLACESHDR"))) {
+	const char *hdr;
+
+	if (pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_invite_method)
+		|| !session->channel
+		|| session->inv_session->state != PJSIP_INV_STATE_NULL) {
 		return;
 	}
 
-	ast_sip_add_header(tdata, "Replaces", replaces);
+	ast_channel_lock(session->channel);
+	hdr = pbx_builtin_getvar_helper(session->channel, "SIPREPLACESHDR");
+	if (!ast_strlen_zero(hdr)) {
+		ast_sip_add_header(tdata, "Replaces", hdr);
+	}
+
+	hdr = pbx_builtin_getvar_helper(session->channel, "SIPREFERREDBYHDR");
+	if (!ast_strlen_zero(hdr)) {
+		ast_sip_add_header(tdata, "Referred-By", hdr);
+	}
+	ast_channel_unlock(session->channel);
 }
 
 static struct ast_sip_session_supplement refer_supplement = {




More information about the asterisk-commits mailing list