diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 18a46ab2dd..52d8634348 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -3243,6 +3243,11 @@ static struct ast_custom_function chan_pjsip_parse_uri_function = { .read = pjsip_acf_parse_uri_read, }; +static struct ast_custom_function chan_pjsip_parse_uri_from_function = { + .name = "PJSIP_PARSE_URI_FROM", + .read = pjsip_acf_parse_uri_read, +}; + static struct ast_custom_function media_offer_function = { .name = "PJSIP_MEDIA_OFFER", .read = pjsip_acf_media_offer_read, @@ -3305,6 +3310,11 @@ static int load_module(void) goto end; } + if (ast_custom_function_register(&chan_pjsip_parse_uri_from_function)) { + ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI_FROM 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; @@ -3378,6 +3388,7 @@ end: 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(&chan_pjsip_parse_uri_from_function); ast_custom_function_unregister(&session_refresh_function); ast_unregister_application(app_pjsip_hangup); ast_manager_unregister(app_pjsip_hangup); @@ -3410,6 +3421,7 @@ static int unload_module(void) 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(&chan_pjsip_parse_uri_from_function); ast_custom_function_unregister(&session_refresh_function); ast_unregister_application(app_pjsip_hangup); ast_manager_unregister(app_pjsip_hangup); diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c index f1365adba9..7d0484c9ae 100644 --- a/channels/pjsip/dialplan_functions.c +++ b/channels/pjsip/dialplan_functions.c @@ -724,6 +724,7 @@ static int parse_uri_cb(void *data) 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, }; + int reading_uri_from_var; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(uri_str); @@ -732,8 +733,29 @@ int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *da AST_STANDARD_APP_ARGS(args, data); + reading_uri_from_var = !strcasecmp(cmd, "PJSIP_PARSE_URI_FROM"); + + if (reading_uri_from_var) { + const char *var; + + if (ast_strlen_zero(args.uri_str)) { + ast_log(LOG_WARNING, "The name of a variable containing a URI must be specified when using the '%s' dialplan function\n", cmd); + return -1; + } + + ast_channel_lock(chan); + if ((var = pbx_builtin_getvar_helper(chan, args.uri_str))) { + args.uri_str = ast_strdupa(var); + } + ast_channel_unlock(chan); + } + if (ast_strlen_zero(args.uri_str)) { - ast_log(LOG_WARNING, "An URI must be specified when using the '%s' dialplan function\n", cmd); + if (reading_uri_from_var) { + ast_log(LOG_WARNING, "The variable provided to the '%s' dialplan function must contain a URI\n", cmd); + } else { + ast_log(LOG_WARNING, "A URI must be specified when using the '%s' dialplan function\n", cmd); + } return -1; } diff --git a/channels/pjsip/dialplan_functions_doc.xml b/channels/pjsip/dialplan_functions_doc.xml index be4ce91b96..3d19d929ba 100644 --- a/channels/pjsip/dialplan_functions_doc.xml +++ b/channels/pjsip/dialplan_functions_doc.xml @@ -223,7 +223,7 @@ <version>17.0.0</version> </since> <synopsis> - Parse an uri and return a type part of the URI. + Parse a URI and return a type part of the URI. </synopsis> <syntax> <parameter name="uri" required="true"> @@ -272,7 +272,66 @@ </parameter> </syntax> <description> - <para>Parse an URI and return a specified part of the URI.</para> + <para>Parse a URI and return a specified part of the URI.</para> + </description> + </function> + <function name="PJSIP_PARSE_URI_FROM" language="en_US"> + <since> + <version>18.24.0</version> + <version>20.9.0</version> + <version>21.4.0</version> + </since> + <synopsis> + Parse the contents of a variable as a URI and return a type part of the URI. + </synopsis> + <syntax> + <parameter name="uri" required="true"> + <para>Name of a variable that contains a 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 the contents of the provided variable as a URI and return a specified part of the URI.</para> </description> </function>