Various SIP headers permit a URI to be prefaced with a `display-name`
production that can include characters (like commas and parentheses)
that are problematic for Asterisk's dialplan parser and, specifically
in the case of this patch, the PJSIP_PARSE_URI function.
This patch introduces a new function - `PJSIP_PARSE_URI_FROM` - that
behaves identically to `PJSIP_PARSE_URI` except that the first
argument is now a variable name and not a literal URI.
Fixes #756
(cherry picked from commit
78d63bc11c6a34de681b614384cb3d551b4f096c)
.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,
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;
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);
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);
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);
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;
}
<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">
</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>