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
This commit is contained in:
parent
6e1471c0b2
commit
e6005f1227
5
CHANGES
5
CHANGES
|
@ -18,6 +18,11 @@ pbx_config
|
|||
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
|
||||
|
|
|
@ -3052,6 +3052,11 @@ static struct ast_custom_function chan_pjsip_dial_contacts_function = {
|
|||
.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,
|
||||
|
@ -3101,6 +3106,11 @@ static int load_module(void)
|
|||
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;
|
||||
|
@ -3155,6 +3165,7 @@ end:
|
|||
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);
|
||||
|
@ -3179,6 +3190,7 @@ static int unload_module(void)
|
|||
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);
|
||||
|
|
|
@ -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">
|
||||
|
@ -1041,6 +1095,127 @@ static struct session_refresh_state *session_refresh_state_get_or_alloc(struct a
|
|||
return state;
|
||||
}
|
||||
|
||||
/*! \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)
|
||||
{
|
||||
|
|
|
@ -110,4 +110,17 @@ int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, c
|
|||
*/
|
||||
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 */
|
Loading…
Reference in New Issue