mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 12:36:58 +00:00
Merge "chan_sip: Add dialplan function SIP_HEADERS"
This commit is contained in:
10
CHANGES
10
CHANGES
@@ -8,6 +8,14 @@
|
|||||||
===
|
===
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
--- Functionality changes from Asterisk 15 to Asterisk 16 --------------------
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
chan_sip
|
||||||
|
------------------
|
||||||
|
* New function SIP_HEADERS() enumerates all headers in the incoming INVITE.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
--- Functionality changes from Asterisk 14 to Asterisk 15 --------------------
|
--- Functionality changes from Asterisk 14 to Asterisk 15 --------------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@@ -1539,7 +1547,7 @@ res_pjsip_endpoint_identifer_ip
|
|||||||
------------------
|
------------------
|
||||||
* New CLI commands have been added: "pjsip show identif(y|ies)", which lists
|
* New CLI commands have been added: "pjsip show identif(y|ies)", which lists
|
||||||
all configured PJSIP identify objects
|
all configured PJSIP identify objects
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
--- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
|
--- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@@ -380,6 +380,37 @@
|
|||||||
<para>Please observe that contents of the SDP (an attachment to the
|
<para>Please observe that contents of the SDP (an attachment to the
|
||||||
SIP request) can't be accessed with this function.</para>
|
SIP request) can't be accessed with this function.</para>
|
||||||
</description>
|
</description>
|
||||||
|
<see-also>
|
||||||
|
<ref type="function">SIP_HEADERS</ref>
|
||||||
|
</see-also>
|
||||||
|
</function>
|
||||||
|
<function name="SIP_HEADERS" language="en_US">
|
||||||
|
<synopsis>
|
||||||
|
Gets the list of SIP header names from an incoming INVITE message.
|
||||||
|
</synopsis>
|
||||||
|
<syntax>
|
||||||
|
<parameter name="prefix">
|
||||||
|
<para>If specified, only the headers matching the given prefix are returned.</para>
|
||||||
|
</parameter>
|
||||||
|
</syntax>
|
||||||
|
<description>
|
||||||
|
<para>Returns a comma-separated list of header names (without values) from the
|
||||||
|
INVITE message that originated the current channel. Multiple headers with the
|
||||||
|
same name are included in the list only once. The returned list can be iterated
|
||||||
|
over using the functions POP() and SIP_HEADER().</para>
|
||||||
|
<para>For example, <literal>${SIP_HEADERS(Co)}</literal> might return
|
||||||
|
<literal>Contact,Content-Length,Content-Type</literal>. As a practical example,
|
||||||
|
you may use <literal>${SIP_HEADERS(X-)}</literal> to enumerate optional extended
|
||||||
|
headers.</para>
|
||||||
|
<para>This function does not access headers from the incoming SIP REFER message;
|
||||||
|
see the documentation of the function SIP_HEADER for how to access them.</para>
|
||||||
|
<para>Please observe that contents of the SDP (an attachment to the
|
||||||
|
SIP request) can't be accessed with this function.</para>
|
||||||
|
</description>
|
||||||
|
<see-also>
|
||||||
|
<ref type="function">SIP_HEADER</ref>
|
||||||
|
<ref type="function">POP</ref>
|
||||||
|
</see-also>
|
||||||
</function>
|
</function>
|
||||||
<function name="SIPPEER" language="en_US">
|
<function name="SIPPEER" language="en_US">
|
||||||
<synopsis>
|
<synopsis>
|
||||||
@@ -22995,6 +23026,7 @@ static int func_header_read(struct ast_channel *chan, const char *function, char
|
|||||||
{
|
{
|
||||||
struct sip_pvt *p;
|
struct sip_pvt *p;
|
||||||
const char *content = NULL;
|
const char *content = NULL;
|
||||||
|
char *mutable_data = ast_strdupa(data);
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(header);
|
AST_APP_ARG(header);
|
||||||
AST_APP_ARG(number);
|
AST_APP_ARG(number);
|
||||||
@@ -23018,7 +23050,7 @@ static int func_header_read(struct ast_channel *chan, const char *function, char
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_STANDARD_APP_ARGS(args, data);
|
AST_STANDARD_APP_ARGS(args, mutable_data);
|
||||||
if (!args.number) {
|
if (!args.number) {
|
||||||
number = 1;
|
number = 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -23054,6 +23086,91 @@ static struct ast_custom_function sip_header_function = {
|
|||||||
.read = func_header_read,
|
.read = func_header_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*! \brief Read unique list of SIP headers (dialplan function) */
|
||||||
|
static int func_headers_read2(struct ast_channel *chan, const char *function, char *data, struct ast_str **buf, ssize_t maxlen)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct sip_pvt *pvt;
|
||||||
|
char *mutable_data = ast_strdupa(data);
|
||||||
|
struct ast_str *token = ast_str_alloca(100);
|
||||||
|
AST_DECLARE_APP_ARGS(args,
|
||||||
|
AST_APP_ARG(pattern);
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!chan) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_channel_lock(chan);
|
||||||
|
|
||||||
|
if (!IS_SIP_TECH(ast_channel_tech(chan))) {
|
||||||
|
ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pvt = ast_channel_tech_pvt(chan);
|
||||||
|
if (!pvt) {
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_STANDARD_APP_ARGS(args, mutable_data);
|
||||||
|
if (!args.pattern || strcmp(args.pattern, "*") == 0) {
|
||||||
|
args.pattern = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pvt->initreq.headers; i++) {
|
||||||
|
const char *header = REQ_OFFSET_TO_STR(&pvt->initreq, header[i]);
|
||||||
|
if (ast_begins_with(header, args.pattern)) {
|
||||||
|
int hdrlen = strcspn(header, " \t:,"); /* Comma will break our logic, and illegal per RFC. */
|
||||||
|
const char *term = ast_skip_blanks(header + hdrlen);
|
||||||
|
if (hdrlen > 0 && *term == ':') { /* Header is malformed otherwise! */
|
||||||
|
const char *s = NULL;
|
||||||
|
|
||||||
|
/* Return short headers in full form always. */
|
||||||
|
if (hdrlen == 1) {
|
||||||
|
char short_hdr[2] = { header[0], '\0' };
|
||||||
|
s = find_full_alias(short_hdr, NULL);
|
||||||
|
}
|
||||||
|
if (s) {
|
||||||
|
/* Short header was found and expanded. */
|
||||||
|
ast_str_set(&token, -1, "%s,", s);
|
||||||
|
} else {
|
||||||
|
/* Return the header as is, whether 1-character or not. */
|
||||||
|
ast_str_set(&token, -1, "%.*s,", hdrlen, header);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Has the same header been already added? */
|
||||||
|
s = ast_str_buffer(*buf);
|
||||||
|
while ((s = strstr(s, ast_str_buffer(token))) != NULL) {
|
||||||
|
/* Found suffix, but is it the full token? */
|
||||||
|
if (s == ast_str_buffer(*buf) || s[-1] == ',')
|
||||||
|
break;
|
||||||
|
/* Only suffix matched, go on with the search after the comma. */
|
||||||
|
s += hdrlen + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s is null iff not broken from the loop, hence header not yet added. */
|
||||||
|
if (s == NULL) {
|
||||||
|
ast_str_append(buf, maxlen, "%s", ast_str_buffer(token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_str_truncate(*buf, -1); /* Trim the last comma. Safe if empty. */
|
||||||
|
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ast_custom_function sip_headers_function = {
|
||||||
|
.name = "SIP_HEADERS",
|
||||||
|
.read2 = func_headers_read2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Dial plan function to check if domain is local */
|
/*! \brief Dial plan function to check if domain is local */
|
||||||
static int func_check_sipdomain(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
|
static int func_check_sipdomain(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
|
||||||
{
|
{
|
||||||
@@ -35201,6 +35318,7 @@ static int load_module(void)
|
|||||||
|
|
||||||
/* Register dialplan functions */
|
/* Register dialplan functions */
|
||||||
ast_custom_function_register(&sip_header_function);
|
ast_custom_function_register(&sip_header_function);
|
||||||
|
ast_custom_function_register(&sip_headers_function);
|
||||||
ast_custom_function_register(&sippeer_function);
|
ast_custom_function_register(&sippeer_function);
|
||||||
ast_custom_function_register(&checksipdomain_function);
|
ast_custom_function_register(&checksipdomain_function);
|
||||||
|
|
||||||
@@ -35301,6 +35419,7 @@ static int unload_module(void)
|
|||||||
|
|
||||||
/* Unregister dial plan functions */
|
/* Unregister dial plan functions */
|
||||||
ast_custom_function_unregister(&sippeer_function);
|
ast_custom_function_unregister(&sippeer_function);
|
||||||
|
ast_custom_function_unregister(&sip_headers_function);
|
||||||
ast_custom_function_unregister(&sip_header_function);
|
ast_custom_function_unregister(&sip_header_function);
|
||||||
ast_custom_function_unregister(&checksipdomain_function);
|
ast_custom_function_unregister(&checksipdomain_function);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user