[Asterisk-code-review] pjsip: New function PJSIP PARSE URI to parse URI and return ... (asterisk[13])
George Joseph
asteriskteam at digium.com
Sun Nov 18 16:12:11 CST 2018
George Joseph has submitted this change and it was merged. ( 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, 205 insertions(+), 0 deletions(-)
Approvals:
George Joseph: Looks good to me, approved; Approved for Submit
diff --git a/CHANGES b/CHANGES
index 5c254a8..398e084 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,6 +18,11 @@
extensions.conf. Variables are processed in the order they are found
and duplicate variables overwrite the previous value.
+chan_pjsip
+------------------
+ * New dialplan function PJSIP_PARSE_URI added to parse an URI and return
+ a specified part of the URI.
+
res_pjsip
------------------
* New options 'trust_connected_line' and 'send_connected_line' have been
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 5bbd025..062fb7c 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2774,6 +2774,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,
@@ -2825,6 +2830,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;
@@ -2897,6 +2907,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);
@@ -2921,6 +2932,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..c6971c8 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 uri and return a type 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,127 @@
return 0;
}
+/*! \brief Struct used to push PJSIP_PARSE_URI function arguments to task processor */
+struct parse_uri_args {
+ const char *uri;
+ const char *type;
+ char *buf;
+ size_t buflen;
+ int ret;
+};
+
+/*! \internal \brief Taskprocessor callback that handles the PJSIP_PARSE_URI on a PJSIP thread */
+static int parse_uri_cb(void *data)
+{
+ struct parse_uri_args *args = data;
+ pj_pool_t *pool;
+ pjsip_name_addr *uri;
+ pjsip_sip_uri *sip_uri;
+ pj_str_t tmp;
+
+ args->ret = 0;
+
+ 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");
+ args->ret = -1;
+ return 0;
+ }
+
+ pj_strdup2_with_null(pool, &tmp, args->uri);
+ 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);
+ pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+ args->ret = -1;
+ return 0;
+ }
+
+ if (!strcmp(args->type, "scheme")) {
+ ast_copy_pj_str(args->buf, pjsip_uri_get_scheme(uri), args->buflen);
+ pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+ return 0;
+ } else if (!strcmp(args->type, "display")) {
+ ast_copy_pj_str(args->buf, &uri->display, args->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 an URI object for '%s'\n", args->uri);
+ pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+ args->ret = -1;
+ return 0;
+ }
+
+ if (!strcmp(args->type, "user")) {
+ ast_copy_pj_str(args->buf, &sip_uri->user, args->buflen);
+ } else if (!strcmp(args->type, "passwd")) {
+ ast_copy_pj_str(args->buf, &sip_uri->passwd, args->buflen);
+ } else if (!strcmp(args->type, "host")) {
+ ast_copy_pj_str(args->buf, &sip_uri->host, args->buflen);
+ } else if (!strcmp(args->type, "port")) {
+ snprintf(args->buf, args->buflen, "%d", sip_uri->port);
+ } else if (!strcmp(args->type, "user_param")) {
+ ast_copy_pj_str(args->buf, &sip_uri->user_param, args->buflen);
+ } else if (!strcmp(args->type, "method_param")) {
+ ast_copy_pj_str(args->buf, &sip_uri->method_param, args->buflen);
+ } else if (!strcmp(args->type, "transport_param")) {
+ ast_copy_pj_str(args->buf, &sip_uri->transport_param, args->buflen);
+ } else if (!strcmp(args->type, "ttl_param")) {
+ snprintf(args->buf, args->buflen, "%d", sip_uri->ttl_param);
+ } else if (!strcmp(args->type, "lr_param")) {
+ snprintf(args->buf, args->buflen, "%d", sip_uri->lr_param);
+ } else if (!strcmp(args->type, "maddr_param")) {
+ ast_copy_pj_str(args->buf, &sip_uri->maddr_param, args->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);
+ args->ret = -1;
+ return 0;
+ }
+
+ pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+
+ return 0;
+}
+
+int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
+{
+ struct parse_uri_args func_args = { 0, };
+
+ 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;
+ }
+
+ memset(buf, 0, buflen);
+
+ func_args.uri = args.uri_str;
+ func_args.type = args.type;
+ func_args.buf = buf;
+ func_args.buflen = buflen;
+ if (ast_sip_push_task_wait_serializer(NULL, parse_uri_cb, &func_args)) {
+ ast_log(LOG_WARNING, "Unable to parse URI: failed to push task\n");
+ return -1;
+ }
+
+ return func_args.ret;
+}
+
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: merged
Gerrit-Change-Id: I5d828fb87f6803b6c1152bb7b44835f027bb9d5a
Gerrit-Change-Number: 10577
Gerrit-PatchSet: 6
Gerrit-Owner: Alexei Gradinari <alex2grad at gmail.com>
Gerrit-Reviewer: Alexei Gradinari <alex2grad at gmail.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Jenkins2 (1000185)
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20181118/49c6119b/attachment-0001.html>
More information about the asterisk-code-review
mailing list