[Asterisk-code-review] pjsip: New function PJSIP PARSE URI to parse URI and return ... (asterisk[13])

Alexei Gradinari asteriskteam at digium.com
Wed Oct 31 12:21:02 CDT 2018


Alexei Gradinari has uploaded this change for review. ( https://gerrit.asterisk.org/10577


Change subject: pjsip: New function PJSIP_PARSE_URI to parse URI and return part of URI
......................................................................

pjsip: New function PJSIP_PARSE_URI to parse URI and return part of URI

New dialplan function PJSIP_PARSE_URI added to parse an URI and return
a specified part of the URI.

This is useful when need to get part of the URI instead of cutting it
using a CUT function.

For example to get 'user' part of Remote URI
${PJSIP_PARSE_URI(${CHANNEL(pjsip,remote_uri)},user)}

ASTERISK-28144 #close

Change-Id: I5d828fb87f6803b6c1152bb7b44835f027bb9d5a
---
M CHANGES
M channels/chan_pjsip.c
M channels/pjsip/dialplan_functions.c
M channels/pjsip/include/dialplan_functions.h
4 files changed, 170 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/77/10577/1

diff --git a/CHANGES b/CHANGES
index 45c964e..78df99d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,11 @@
 --- Functionality changes from Asterisk 13.23.0 to Asterisk 13.24.0 ----------
 ------------------------------------------------------------------------------
 
+chan_pjsip
+------------------
+ * New dialplan function PJSIP_PARSE_URI added to parse an URI and return
+   a specified part of the URI.
+
 res_rtp_asterisk
 ------------------
  * The existing strictrtp option in rtp.conf has a new choice availabe, called
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 4da0361..1d74db6 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2773,6 +2773,11 @@
 	.read = pjsip_acf_dial_contacts_read,
 };
 
+static struct ast_custom_function chan_pjsip_parse_uri_function = {
+	.name = "PJSIP_PARSE_URI",
+	.read = pjsip_acf_parse_uri_read,
+};
+
 static struct ast_custom_function media_offer_function = {
 	.name = "PJSIP_MEDIA_OFFER",
 	.read = pjsip_acf_media_offer_read,
@@ -2824,6 +2829,11 @@
 		goto end;
 	}
 
+	if (ast_custom_function_register(&chan_pjsip_parse_uri_function)) {
+		ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
+		goto end;
+	}
+
 	if (ast_custom_function_register(&media_offer_function)) {
 		ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
 		goto end;
@@ -2896,6 +2906,7 @@
 	ast_custom_function_unregister(&dtmf_mode_function);
 	ast_custom_function_unregister(&media_offer_function);
 	ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
+	ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
 	ast_custom_function_unregister(&session_refresh_function);
 	ast_channel_unregister(&chan_pjsip_tech);
 	ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
@@ -2920,6 +2931,7 @@
 	ast_custom_function_unregister(&dtmf_mode_function);
 	ast_custom_function_unregister(&media_offer_function);
 	ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
+	ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
 	ast_custom_function_unregister(&session_refresh_function);
 
 	ast_channel_unregister(&chan_pjsip_tech);
diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c
index b7a7460..8ef4f7f 100644
--- a/channels/pjsip/dialplan_functions.c
+++ b/channels/pjsip/dialplan_functions.c
@@ -121,6 +121,60 @@
 		<ref type="function">PJSIP_MEDIA_OFFER</ref>
 	</see-also>
 </function>
+<function name="PJSIP_PARSE_URI" language="en_US">
+	<synopsis>
+		Parse an <literal>uri</literal> and return a <literal>type</literal> part of the URI.
+	</synopsis>
+	<syntax>
+		<parameter name="uri" required="true">
+			<para>URI to parse</para>
+		</parameter>
+		<parameter name="type" required="true">
+			<para>The <literal>type</literal> parameter specifies which URI part to read</para>
+			<enumlist>
+				<enum name="display">
+					<para>Display name.</para>
+				</enum>
+				<enum name="scheme">
+					<para>URI scheme.</para>
+				</enum>
+				<enum name="user">
+					<para>User part.</para>
+				</enum>
+				<enum name="passwd">
+					<para>Password part.</para>
+				</enum>
+				<enum name="host">
+					<para>Host part.</para>
+				</enum>
+				<enum name="port">
+					<para>Port number, or zero.</para>
+				</enum>
+				<enum name="user_param">
+					<para>User parameter.</para>
+				</enum>
+				<enum name="method_param">
+					<para>Method parameter.</para>
+				</enum>
+				<enum name="transport_param">
+					<para>Transport parameter.</para>
+				</enum>
+				<enum name="ttl_param">
+					<para>TTL param, or -1.</para>
+				</enum>
+				<enum name="lr_param">
+					<para>Loose routing param, or zero.</para>
+				</enum>
+				<enum name="maddr_param">
+					<para>Maddr param.</para>
+				</enum>
+			</enumlist>
+		</parameter>
+	</syntax>
+	<description>
+		<para>Parse an URI and return a specified part of the URI.</para>
+	</description>
+</function>
 <info name="CHANNEL" language="en_US" tech="PJSIP">
 	<enumlist>
 		<enum name="rtp">
@@ -987,6 +1041,92 @@
 	return 0;
 }
 
+int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
+{
+	pj_pool_t *pool;
+	pjsip_name_addr *uri;
+	pjsip_sip_uri *sip_uri;
+	pj_str_t tmp;
+
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(uri_str);
+		AST_APP_ARG(type);
+	);
+
+	AST_STANDARD_APP_ARGS(args, data);
+
+	if (ast_strlen_zero(args.uri_str)) {
+		ast_log(LOG_WARNING, "An URI must be specified when using the '%s' dialplan function\n", cmd);
+		return -1;
+	}
+
+	if (ast_strlen_zero(args.type)) {
+		ast_log(LOG_WARNING, "A type part of the URI must be specified when using the '%s' dialplan function\n", cmd);
+		return -1;
+	}
+
+	pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "ParseUri", 128, 128);
+	if (!pool) {
+		ast_log(LOG_ERROR, "Failed to allocate ParseUri endpoint pool.\n");
+		return -1;
+	}
+
+	pj_strdup2_with_null(pool, &tmp, args.uri_str);
+	uri = (pjsip_name_addr *)pjsip_parse_uri(pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+	if (!uri) {
+		ast_log(LOG_WARNING, "Failed to parse URI '%s'\n", args.uri_str);
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return -1;
+	}
+
+	if (!strcmp(args.type, "scheme")) {
+		ast_copy_pj_str(buf, pjsip_uri_get_scheme(uri), buflen);
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return 0;
+	} else if (!strcmp(args.type, "display")) {
+		ast_copy_pj_str(buf, &uri->display, buflen);
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return 0;
+	}
+
+	sip_uri = pjsip_uri_get_uri(uri);
+	if (!sip_uri) {
+		ast_log(LOG_ERROR, "Failed to get SIP URI\n");
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return -1;
+	}
+
+	if (!strcmp(args.type, "user")) {
+		ast_copy_pj_str(buf, &sip_uri->user, buflen);
+	} else if (!strcmp(args.type, "passwd")) {
+		ast_copy_pj_str(buf, &sip_uri->passwd, buflen);
+	} else if (!strcmp(args.type, "host")) {
+		ast_copy_pj_str(buf, &sip_uri->host, buflen);
+	} else if (!strcmp(args.type, "port")) {
+		snprintf(buf, buflen, "%d", sip_uri->port);
+	} else if (!strcmp(args.type, "user_param")) {
+		ast_copy_pj_str(buf, &sip_uri->user_param, buflen);
+	} else if (!strcmp(args.type, "method_param")) {
+		ast_copy_pj_str(buf, &sip_uri->method_param, buflen);
+	} else if (!strcmp(args.type, "transport_param")) {
+		ast_copy_pj_str(buf, &sip_uri->transport_param, buflen);
+	} else if (!strcmp(args.type, "ttl_param")) {
+		snprintf(buf, buflen, "%d", sip_uri->ttl_param);
+	} else if (!strcmp(args.type, "lr_param")) {
+		snprintf(buf, buflen, "%d", sip_uri->lr_param);
+	} else if (!strcmp(args.type, "maddr_param")) {
+		ast_copy_pj_str(buf, &sip_uri->maddr_param, buflen);
+	} else {
+		ast_log(AST_LOG_WARNING, "Unknown type part '%s' specified\n", args.type);
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return -1;
+	}
+
+	pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+
+	return 0;
+}
+
 static int media_offer_read_av(struct ast_sip_session *session, char *buf,
 			       size_t len, enum ast_media_type media_type)
 {
diff --git a/channels/pjsip/include/dialplan_functions.h b/channels/pjsip/include/dialplan_functions.h
index 731e91d..a9332a2 100644
--- a/channels/pjsip/include/dialplan_functions.h
+++ b/channels/pjsip/include/dialplan_functions.h
@@ -110,4 +110,17 @@
  */
 int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
 
+/*!
+ * \brief PJSIP_PARSE_URI function read callback
+ * \param chan The channel the function is called on
+ * \param cmd The name of the function
+ * \param data Arguments passed to the function
+ * \param buf Out buffer that should be populated with the data
+ * \param len Size of the buffer
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
+
 #endif /* _PJSIP_DIALPLAN_FUNCTIONS */
\ No newline at end of file

-- 
To view, visit https://gerrit.asterisk.org/10577
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5d828fb87f6803b6c1152bb7b44835f027bb9d5a
Gerrit-Change-Number: 10577
Gerrit-PatchSet: 1
Gerrit-Owner: Alexei Gradinari <alex2grad at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20181031/40d159a9/attachment-0001.html>


More information about the asterisk-code-review mailing list