Merge "chan_sip: Add dialplan function SIP_HEADERS"
This commit is contained in:
commit
1f01106cfc
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 --------------------
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -1539,7 +1547,7 @@ res_pjsip_endpoint_identifer_ip
|
|||
------------------
|
||||
* New CLI commands have been added: "pjsip show identif(y|ies)", which lists
|
||||
all configured PJSIP identify objects
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
|
||||
------------------------------------------------------------------------------
|
||||
|
|
|
@ -380,6 +380,37 @@
|
|||
<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_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 name="SIPPEER" language="en_US">
|
||||
<synopsis>
|
||||
|
@ -22995,6 +23026,7 @@ static int func_header_read(struct ast_channel *chan, const char *function, char
|
|||
{
|
||||
struct sip_pvt *p;
|
||||
const char *content = NULL;
|
||||
char *mutable_data = ast_strdupa(data);
|
||||
AST_DECLARE_APP_ARGS(args,
|
||||
AST_APP_ARG(header);
|
||||
AST_APP_ARG(number);
|
||||
|
@ -23018,7 +23050,7 @@ static int func_header_read(struct ast_channel *chan, const char *function, char
|
|||
return -1;
|
||||
}
|
||||
|
||||
AST_STANDARD_APP_ARGS(args, data);
|
||||
AST_STANDARD_APP_ARGS(args, mutable_data);
|
||||
if (!args.number) {
|
||||
number = 1;
|
||||
} else {
|
||||
|
@ -23054,6 +23086,91 @@ static struct ast_custom_function sip_header_function = {
|
|||
.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 */
|
||||
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 */
|
||||
ast_custom_function_register(&sip_header_function);
|
||||
ast_custom_function_register(&sip_headers_function);
|
||||
ast_custom_function_register(&sippeer_function);
|
||||
ast_custom_function_register(&checksipdomain_function);
|
||||
|
||||
|
@ -35301,6 +35419,7 @@ static int unload_module(void)
|
|||
|
||||
/* Unregister dial plan functions */
|
||||
ast_custom_function_unregister(&sippeer_function);
|
||||
ast_custom_function_unregister(&sip_headers_function);
|
||||
ast_custom_function_unregister(&sip_header_function);
|
||||
ast_custom_function_unregister(&checksipdomain_function);
|
||||
|
||||
|
|
Loading…
Reference in New Issue