Merge "res_pjsip: Add XML documentation for "use_callerid_contact""
[asterisk/asterisk.git] / res / res_pjsip_header_funcs.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Fairview 5 Engineering, LLC
5  *
6  * George Joseph <george.joseph@fairview5.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*** MODULEINFO
20         <depend>pjproject</depend>
21         <depend>res_pjsip</depend>
22         <depend>res_pjsip_session</depend>
23         <support_level>core</support_level>
24  ***/
25
26 #include "asterisk.h"
27
28 #include <pjsip.h>
29 #include <pjsip_ua.h>
30
31 #include "asterisk/res_pjsip.h"
32 #include "asterisk/res_pjsip_session.h"
33 #include "asterisk/channel.h"
34 #include "asterisk/pbx.h"
35 #include "asterisk/app.h"
36 #include "asterisk/module.h"
37 #include "asterisk/utils.h"
38
39 /*** DOCUMENTATION
40         <function name="PJSIP_HEADER" language="en_US">
41                 <synopsis>
42                         Gets headers from an inbound PJSIP channel. Adds, updates or removes the
43                         specified SIP header from an outbound PJSIP channel.
44                 </synopsis>
45                 <syntax>
46                         <parameter name="action" required="true">
47                                 <enumlist>
48                                         <enum name="read"><para>Returns instance <replaceable>number</replaceable>
49                                         of header <replaceable>name</replaceable>.</para></enum>
50
51                                         <enum name="add"><para>Adds a new header <replaceable>name</replaceable>
52                                         to this session.</para></enum>
53
54                                         <enum name="update"><para>Updates instance <replaceable>number</replaceable>
55                                         of header <replaceable>name</replaceable> to a new value.
56                                         The header must already exist.</para></enum>
57
58                                         <enum name="remove"><para>Removes all instances of previously added headers
59                                         whose names match <replaceable>name</replaceable>. A <literal>*</literal>
60                                         may be appended to <replaceable>name</replaceable> to remove all headers
61                                         <emphasis>beginning with</emphasis> <replaceable>name</replaceable>.
62                                         <replaceable>name</replaceable> may be set to a single <literal>*</literal>
63                                         to clear <emphasis>all</emphasis> previously added headers. In all cases,
64                                         the number of headers actually removed is returned.</para></enum>
65                                 </enumlist>
66                         </parameter>
67
68                         <parameter name="name" required="true"><para>The name of the header.</para></parameter>
69
70                         <parameter name="number" required="false">
71                                 <para>If there's more than 1 header with the same name, this specifies which header
72                                 to read or update.  If not specified, defaults to <literal>1</literal> meaning
73                                 the first matching header.  Not valid for <literal>add</literal> or
74                                 <literal>remove</literal>.</para>
75                         </parameter>
76
77                 </syntax>
78                 <description>
79                         <para>PJSIP_HEADER allows you to read specific SIP headers from the inbound
80                         PJSIP channel as well as write(add, update, remove) headers on the outbound
81                         channel. One exception is that you can read headers that you have already
82                         added on the outbound channel.</para>
83                         <para>Examples:</para>
84                         <para>;</para>
85                         <para>; Set 'somevar' to the value of the 'From' header.</para>
86                         <para>exten => 1,1,Set(somevar=${PJSIP_HEADER(read,From)})</para>
87                         <para>;</para>
88                         <para>; Set 'via2' to the value of the 2nd 'Via' header.</para>
89                         <para>exten => 1,1,Set(via2=${PJSIP_HEADER(read,Via,2)})</para>
90                         <para>;</para>
91                         <para>; Add an 'X-Myheader' header with the value of 'myvalue'.</para>
92                         <para>exten => 1,1,Set(PJSIP_HEADER(add,X-MyHeader)=myvalue)</para>
93                         <para>;</para>
94                         <para>; Add an 'X-Myheader' header with an empty value.</para>
95                         <para>exten => 1,1,Set(PJSIP_HEADER(add,X-MyHeader)=)</para>
96                         <para>;</para>
97                         <para>; Update the value of the header named 'X-Myheader' to 'newvalue'.</para>
98                         <para>; 'X-Myheader' must already exist or the call will fail.</para>
99                         <para>exten => 1,1,Set(PJSIP_HEADER(update,X-MyHeader)=newvalue)</para>
100                         <para>;</para>
101                         <para>; Remove all headers whose names exactly match 'X-MyHeader'.</para>
102                         <para>exten => 1,1,Set(PJSIP_HEADER(remove,X-MyHeader)=)</para>
103                         <para>;</para>
104                         <para>; Remove all headers that begin with 'X-My'.</para>
105                         <para>exten => 1,1,Set(PJSIP_HEADER(remove,X-My*)=)</para>
106                         <para>;</para>
107                         <para>; Remove all previously added headers.</para>
108                         <para>exten => 1,1,Set(PJSIP_HEADER(remove,*)=)</para>
109                         <para>;</para>
110
111                         <note><para>The <literal>remove</literal> action can be called by reading
112                         <emphasis>or</emphasis> writing PJSIP_HEADER.</para>
113                         <para>;</para>
114                         <para>; Display the number of headers removed</para>
115                         <para>exten => 1,1,Verbose( Removed ${PJSIP_HEADER(remove,X-MyHeader)} headers)</para>
116                         <para>;</para>
117                         <para>; Set a variable to the number of headers removed</para>
118                         <para>exten => 1,1,Set(count=${PJSIP_HEADER(remove,X-MyHeader)})</para>
119                         <para>;</para>
120                         <para>; Just remove them ignoring any count</para>
121                         <para>exten => 1,1,Set(=${PJSIP_HEADER(remove,X-MyHeader)})</para>
122                         <para>exten => 1,1,Set(PJSIP_HEADER(remove,X-MyHeader)=)</para>
123                         <para>;</para>
124                         </note>
125
126                         <note><para>If you call PJSIP_HEADER in a normal dialplan context you'll be
127                         operating on the <emphasis>caller's (incoming)</emphasis> channel which
128                         may not be what you want. To operate on the <emphasis>callee's (outgoing)</emphasis>
129                         channel call PJSIP_HEADER in a pre-dial handler. </para>
130                         <para>Example:</para>
131                         <para>;</para>
132                         <para>[handler]</para>
133                         <para>exten => addheader,1,Set(PJSIP_HEADER(add,X-MyHeader)=myvalue)</para>
134                         <para>exten => addheader,2,Set(PJSIP_HEADER(add,X-MyHeader2)=myvalue2)</para>
135                         <para>;</para>
136                         <para>[somecontext]</para>
137                         <para>exten => 1,1,Dial(PJSIP/${EXTEN},,b(handler^addheader^1))</para>
138                         <para>;</para>
139                         </note>
140                 </description>
141         </function>
142  ***/
143
144 /*! \brief Linked list for accumulating headers */
145 struct hdr_list_entry {
146         pjsip_hdr *hdr;
147         AST_LIST_ENTRY(hdr_list_entry) nextptr;
148 };
149 AST_LIST_HEAD_NOLOCK(hdr_list, hdr_list_entry);
150
151 /*! \brief Datastore for saving headers */
152 static const struct ast_datastore_info header_datastore = {
153         .type = "header_datastore",
154 };
155
156 /*! \brief Data structure used for ast_sip_push_task_wait_serializer  */
157 struct header_data {
158         struct ast_sip_channel_pvt *channel;
159         char *header_name;
160         const char *header_value;
161         char *buf;
162         int header_number;
163         size_t len;
164 };
165
166 /*!
167  * \internal
168  * \brief Insert the header pointers into the linked list.
169  *
170  * For each header in the message, allocate a list entry,
171  * clone the header, then insert the entry.
172  */
173 static int insert_headers(pj_pool_t * pool, struct hdr_list *list, pjsip_msg * msg)
174 {
175         pjsip_hdr *hdr = msg->hdr.next;
176         struct hdr_list_entry *le;
177
178         while (hdr && hdr != &msg->hdr) {
179                 le = pj_pool_zalloc(pool, sizeof(struct hdr_list_entry));
180                 le->hdr = pjsip_hdr_clone(pool, hdr);
181                 AST_LIST_INSERT_TAIL(list, le, nextptr);
182                 hdr = hdr->next;
183         }
184
185         return 0;
186 }
187
188 /*!
189  * \internal
190  * \brief Session supplement callback on an incoming INVITE request
191  *
192  * Retrieve the header_datastore from the session or create one if it doesn't exist.
193  * Create and initialize the list if needed.
194  * Insert the headers.
195  */
196 static int incoming_request(struct ast_sip_session *session, pjsip_rx_data * rdata)
197 {
198         pj_pool_t *pool = session->inv_session->dlg->pool;
199         RAII_VAR(struct ast_datastore *, datastore,
200                          ast_sip_session_get_datastore(session, header_datastore.type), ao2_cleanup);
201
202         if (!datastore) {
203                 if (!(datastore =
204                           ast_sip_session_alloc_datastore(&header_datastore, header_datastore.type))
205                         ||
206                         !(datastore->data = pj_pool_alloc(pool, sizeof(struct hdr_list))) ||
207                         ast_sip_session_add_datastore(session, datastore)) {
208                         ast_log(AST_LOG_ERROR, "Unable to create datastore for header functions.\n");
209                         return 0;
210                 }
211                 AST_LIST_HEAD_INIT_NOLOCK((struct hdr_list *) datastore->data);
212         }
213         insert_headers(pool, (struct hdr_list *) datastore->data, rdata->msg_info.msg);
214
215         return 0;
216 }
217
218 /*!
219  * \internal
220  * \brief Search list for nth occurrence of specific header.
221  */
222 static pjsip_hdr *find_header(struct hdr_list *list, const char *header_name,
223                                                           int header_number)
224 {
225         struct hdr_list_entry *le;
226         pjsip_hdr *hdr = NULL;
227         int i = 1;
228
229         if (!list || ast_strlen_zero(header_name) || header_number < 1) {
230                 return NULL;
231         }
232
233         AST_LIST_TRAVERSE(list, le, nextptr) {
234                 if (pj_stricmp2(&le->hdr->name, header_name) == 0 && i++ == header_number) {
235                         hdr = le->hdr;
236                         break;
237                 }
238         }
239
240         return hdr;
241 }
242
243
244 /*!
245  * \internal
246  * \brief Implements PJSIP_HEADER 'read' by searching the for the requested header.
247  *
248  * Retrieve the header_datastore.
249  * Search for the nth matching header.
250  * Validate the pjsip_hdr found.
251  * Parse pjsip_hdr into a name and value.
252  * Return the value.
253  */
254 static int read_header(void *obj)
255 {
256         struct header_data *data = obj;
257         pjsip_hdr *hdr = NULL;
258         char *pj_hdr_string;
259         size_t pj_hdr_string_len;
260         char *p;
261         size_t plen;
262         RAII_VAR(struct ast_datastore *, datastore,
263                          ast_sip_session_get_datastore(data->channel->session, header_datastore.type),
264                          ao2_cleanup);
265
266         if (!datastore || !datastore->data) {
267                 ast_debug(1, "There was no datastore from which to read headers.\n");
268                 return -1;
269         }
270
271         hdr = find_header((struct hdr_list *) datastore->data, data->header_name,
272                                           data->header_number);
273
274         if (!hdr) {
275                 ast_debug(1, "There was no header named %s.\n", data->header_name);
276                 return -1;
277         }
278
279         pj_hdr_string = ast_alloca(data->len);
280         pj_hdr_string_len = pjsip_hdr_print_on(hdr, pj_hdr_string, data->len);
281         pj_hdr_string[pj_hdr_string_len] = '\0';
282
283         p = strchr(pj_hdr_string, ':');
284         if (!p) {
285                 ast_log(AST_LOG_ERROR,
286                                 "A malformed header was returned from pjsip_hdr_print_on.\n");
287                 return -1;
288         }
289
290         ++p;
291         p = ast_strip(p);
292         plen = strlen(p);
293         if (plen + 1 > data->len) {
294                 ast_log(AST_LOG_ERROR,
295                                 "Buffer isn't big enough to hold header value.  %zu > %zu\n", plen + 1,
296                                 data->len);
297                 return -1;
298         }
299
300         ast_copy_string(data->buf, p, data->len);
301
302         return 0;
303 }
304
305 /*!
306  * \internal
307  * \brief Implements PJSIP_HEADER 'add' by inserting the specified header into thge list.
308  *
309  * Retrieve the header_datastore from the session or create one if it doesn't exist.
310  * Create and initialize the list if needed.
311  * Create the pj_strs for name and value.
312  * Create pjsip_msg and hdr_list_entry.
313  * Add the entry to the list.
314  */
315 static int add_header(void *obj)
316 {
317         struct header_data *data = obj;
318         struct ast_sip_session *session = data->channel->session;
319         pj_pool_t *pool = session->inv_session->dlg->pool;
320         pj_str_t pj_header_name;
321         pj_str_t pj_header_value;
322         struct hdr_list_entry *le;
323         struct hdr_list *list;
324
325         RAII_VAR(struct ast_datastore *, datastore,
326                          ast_sip_session_get_datastore(session, header_datastore.type), ao2_cleanup);
327
328         if (!datastore) {
329                 if (!(datastore = ast_sip_session_alloc_datastore(&header_datastore,
330                                                                                                                   header_datastore.type))
331                         || !(datastore->data = pj_pool_alloc(pool, sizeof(struct hdr_list)))
332                         || ast_sip_session_add_datastore(session, datastore)) {
333                         ast_log(AST_LOG_ERROR, "Unable to create datastore for header functions.\n");
334                         return -1;
335                 }
336                 AST_LIST_HEAD_INIT_NOLOCK((struct hdr_list *) datastore->data);
337         }
338
339         ast_debug(1, "Adding header %s with value %s\n", data->header_name,
340                           data->header_value);
341
342         pj_cstr(&pj_header_name, data->header_name);
343         pj_cstr(&pj_header_value, data->header_value);
344         le = pj_pool_zalloc(pool, sizeof(struct hdr_list_entry));
345         le->hdr = (pjsip_hdr *) pjsip_generic_string_hdr_create(pool, &pj_header_name,
346                                                                                                                         &pj_header_value);
347         list = datastore->data;
348
349         AST_LIST_INSERT_TAIL(list, le, nextptr);
350
351         return 0;
352 }
353
354 /*!
355  * \internal
356  * \brief Implements PJSIP_HEADER 'update' by finding the specified header and updating it.
357  *
358  * Retrieve the header_datastore from the session or create one if it doesn't exist.
359  * Create and initialize the list if needed.
360  * Create the pj_strs for name and value.
361  * Create pjsip_msg and hdr_list_entry.
362  * Add the entry to the list.
363  */
364 static int update_header(void *obj)
365 {
366         struct header_data *data = obj;
367         pjsip_hdr *hdr = NULL;
368         RAII_VAR(struct ast_datastore *, datastore,
369                          ast_sip_session_get_datastore(data->channel->session, header_datastore.type),
370                          ao2_cleanup);
371
372         if (!datastore || !datastore->data) {
373                 ast_log(AST_LOG_ERROR, "No headers had been previously added to this session.\n");
374                 return -1;
375         }
376
377         hdr = find_header((struct hdr_list *) datastore->data, data->header_name,
378                                           data->header_number);
379
380         if (!hdr) {
381                 ast_log(AST_LOG_ERROR, "There was no header named %s.\n", data->header_name);
382                 return -1;
383         }
384
385         pj_strcpy2(&((pjsip_generic_string_hdr *) hdr)->hvalue, data->header_value);
386
387         return 0;
388 }
389
390 /*!
391  * \internal
392  * \brief Implements PJSIP_HEADER 'remove' by finding the specified header and removing it.
393  *
394  * Retrieve the header_datastore from the session.  Fail if it doesn't exist.
395  * If the header_name is exactly '*', the entire list is simply destroyed.
396  * Otherwise search the list for the matching header name which may be a partial name.
397  */
398 static int remove_header(void *obj)
399 {
400         struct header_data *data = obj;
401         size_t len = strlen(data->header_name);
402         struct hdr_list *list;
403         struct hdr_list_entry *le;
404         int removed_count = 0;
405         RAII_VAR(struct ast_datastore *, datastore,
406                          ast_sip_session_get_datastore(data->channel->session, header_datastore.type),
407                          ao2_cleanup);
408
409         if (!datastore || !datastore->data) {
410                 ast_log(AST_LOG_ERROR, "No headers had been previously added to this session.\n");
411                 return -1;
412         }
413
414         list = datastore->data;
415         AST_LIST_TRAVERSE_SAFE_BEGIN(list, le, nextptr) {
416                 if (data->header_name[len - 1] == '*') {
417                         if (pj_strnicmp2(&le->hdr->name, data->header_name, len - 1) == 0) {
418                                 AST_LIST_REMOVE_CURRENT(nextptr);
419                                 removed_count++;
420                         }
421                 } else {
422                         if (pj_stricmp2(&le->hdr->name, data->header_name) == 0) {
423                                 AST_LIST_REMOVE_CURRENT(nextptr);
424                                 removed_count++;
425                         }
426                 }
427         }
428         AST_LIST_TRAVERSE_SAFE_END;
429
430         if (data->buf && data->len) {
431                 snprintf(data->buf, data->len, "%d", removed_count);
432         }
433
434         return 0;
435 }
436
437 /*!
438  * \brief Implements function 'read' callback.
439  *
440  * Valid actions are 'read' and 'remove'.
441  */
442 static int func_read_header(struct ast_channel *chan, const char *function, char *data,
443                                                         char *buf, size_t len)
444 {
445         struct ast_sip_channel_pvt *channel = chan ? ast_channel_tech_pvt(chan) : NULL;
446         struct header_data header_data;
447         int number;
448         AST_DECLARE_APP_ARGS(args,
449                                                  AST_APP_ARG(action);
450                                                  AST_APP_ARG(header_name); AST_APP_ARG(header_number););
451         AST_STANDARD_APP_ARGS(args, data);
452
453         if (!channel || strncmp(ast_channel_name(chan), "PJSIP/", 6)) {
454                 ast_log(LOG_ERROR, "This function requires a PJSIP channel.\n");
455                 return -1;
456         }
457
458         if (ast_strlen_zero(args.action)) {
459                 ast_log(AST_LOG_ERROR, "This function requires an action.\n");
460                 return -1;
461         }
462         if (ast_strlen_zero(args.header_name)) {
463                 ast_log(AST_LOG_ERROR, "This function requires a header name.\n");
464                 return -1;
465         }
466         if (!args.header_number) {
467                 number = 1;
468         } else {
469                 sscanf(args.header_number, "%30d", &number);
470                 if (number < 1) {
471                         number = 1;
472                 }
473         }
474
475         header_data.channel = channel;
476         header_data.header_name = args.header_name;
477         header_data.header_number = number;
478         header_data.header_value = NULL;
479         header_data.buf = buf;
480         header_data.len = len;
481
482         if (!strcasecmp(args.action, "read")) {
483                 return ast_sip_push_task_wait_serializer(channel->session->serializer,
484                         read_header, &header_data);
485         } else if (!strcasecmp(args.action, "remove")) {
486                 return ast_sip_push_task_wait_serializer(channel->session->serializer,
487                         remove_header, &header_data);
488         } else {
489                 ast_log(AST_LOG_ERROR,
490                                 "Unknown action '%s' is not valid, must be 'read' or 'remove'.\n",
491                                 args.action);
492                 return -1;
493         }
494 }
495
496 /*!
497  * \brief Implements function 'write' callback.
498  *
499  * Valid actions are 'add', 'update' and 'remove'.
500  */
501 static int func_write_header(struct ast_channel *chan, const char *cmd, char *data,
502                                                          const char *value)
503 {
504         struct ast_sip_channel_pvt *channel = chan ? ast_channel_tech_pvt(chan) : NULL;
505         struct header_data header_data;
506         int header_number;
507         AST_DECLARE_APP_ARGS(args,
508                                                  AST_APP_ARG(action);
509                                                  AST_APP_ARG(header_name); AST_APP_ARG(header_number););
510         AST_STANDARD_APP_ARGS(args, data);
511
512         if (!channel || strncmp(ast_channel_name(chan), "PJSIP/", 6)) {
513                 ast_log(LOG_ERROR, "This function requires a PJSIP channel.\n");
514                 return -1;
515         }
516
517         if (ast_strlen_zero(args.action)) {
518                 ast_log(AST_LOG_ERROR, "This function requires an action.\n");
519                 return -1;
520         }
521         if (ast_strlen_zero(args.header_name)) {
522                 ast_log(AST_LOG_ERROR, "This function requires a header name.\n");
523                 return -1;
524         }
525         if (!args.header_number) {
526                 header_number = 1;
527         } else {
528                 sscanf(args.header_number, "%30d", &header_number);
529                 if (header_number < 1) {
530                         header_number = 1;
531                 }
532         }
533
534         header_data.channel = channel;
535         header_data.header_name = args.header_name;
536         header_data.header_number = header_number;
537         header_data.header_value = value;
538         header_data.buf = NULL;
539         header_data.len = 0;
540
541         if (!strcasecmp(args.action, "add")) {
542                 return ast_sip_push_task_wait_serializer(channel->session->serializer,
543                         add_header, &header_data);
544         } else if (!strcasecmp(args.action, "update")) {
545                 return ast_sip_push_task_wait_serializer(channel->session->serializer,
546                         update_header, &header_data);
547         } else if (!strcasecmp(args.action, "remove")) {
548                 return ast_sip_push_task_wait_serializer(channel->session->serializer,
549                         remove_header, &header_data);
550         } else {
551                 ast_log(AST_LOG_ERROR,
552                                 "Unknown action '%s' is not valid, must be 'add', 'update', or 'remove'.\n",
553                                 args.action);
554                 return -1;
555         }
556 }
557
558 static struct ast_custom_function pjsip_header_function = {
559         .name = "PJSIP_HEADER",
560         .read = func_read_header,
561         .write = func_write_header,
562 };
563
564 /*!
565  * \internal
566  * \brief Session supplement callback for outgoing INVITE requests
567  *
568  * Retrieve the header_datastore from the session.
569  * Add each header in the list to the outgoing message.
570  *
571  * These pjsip_hdr structures will have been created by add_header.
572  * Because outgoing_request may be called more than once with the same header
573  * list (as in the case of an authentication exchange), each pjsip_hdr structure
574  * MUST be newly cloned for each outgoing message.
575  */
576 static void outgoing_request(struct ast_sip_session *session, pjsip_tx_data * tdata)
577 {
578         pj_pool_t *pool = session->inv_session->dlg->pool;
579         struct hdr_list *list;
580         struct hdr_list_entry *le;
581         RAII_VAR(struct ast_datastore *, datastore,
582                          ast_sip_session_get_datastore(session, header_datastore.type), ao2_cleanup);
583
584         if (!datastore || !datastore->data ||
585                 (session->inv_session->state >= PJSIP_INV_STATE_CONFIRMED)) {
586                 return;
587         }
588
589         list = datastore->data;
590         AST_LIST_TRAVERSE(list, le, nextptr) {
591                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) pjsip_hdr_clone(pool, le->hdr));
592         }
593         ast_sip_session_remove_datastore(session, datastore->uid);
594 }
595
596 static struct ast_sip_session_supplement header_funcs_supplement = {
597         .method = "INVITE",
598         .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL - 1000,
599         .incoming_request = incoming_request,
600         .outgoing_request = outgoing_request,
601 };
602
603 static int load_module(void)
604 {
605         ast_sip_session_register_supplement(&header_funcs_supplement);
606         ast_custom_function_register(&pjsip_header_function);
607
608         return AST_MODULE_LOAD_SUCCESS;
609 }
610
611 static int unload_module(void)
612 {
613         ast_custom_function_unregister(&pjsip_header_function);
614         ast_sip_session_unregister_supplement(&header_funcs_supplement);
615         return 0;
616 }
617
618 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Header Functions",
619         .support_level = AST_MODULE_SUPPORT_CORE,
620         .load = load_module,
621         .unload = unload_module,
622         .load_pri = AST_MODPRI_APP_DEPEND,
623         .requires = "res_pjsip,res_pjsip_session",
624 );