ARI: Add ability to raise arbitrary User Events
[asterisk/asterisk.git] / main / message.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.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 /*! \file
20  *
21  * \brief Out-of-call text message support
22  *
23  * \author Russell Bryant <russell@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/_private.h"
35
36 #include "asterisk/module.h"
37 #include "asterisk/datastore.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/manager.h"
40 #include "asterisk/strings.h"
41 #include "asterisk/astobj2.h"
42 #include "asterisk/app.h"
43 #include "asterisk/taskprocessor.h"
44 #include "asterisk/message.h"
45
46 /*** DOCUMENTATION
47         <function name="MESSAGE" language="en_US">
48                 <synopsis>
49                         Create a message or read fields from a message.
50                 </synopsis>
51                 <syntax argsep="/">
52                         <parameter name="argument" required="true">
53                         <para>Field of the message to get or set.</para>
54                         <enumlist>
55                                 <enum name="to">
56                                         <para>Read-only.  The destination of the message.  When processing an
57                                         incoming message, this will be set to the destination listed as
58                                         the recipient of the message that was received by Asterisk.</para>
59                                 </enum>
60                                 <enum name="from">
61                                         <para>Read-only.  The source of the message.  When processing an
62                                         incoming message, this will be set to the source of the message.</para>
63                                 </enum>
64                                 <enum name="custom_data">
65                                         <para>Write-only.  Mark or unmark all message headers for an outgoing
66                                         message.  The following values can be set:</para>
67                                         <enumlist>
68                                                 <enum name="mark_all_outbound">
69                                                         <para>Mark all headers for an outgoing message.</para>
70                                                 </enum>
71                                                 <enum name="clear_all_outbound">
72                                                         <para>Unmark all headers for an outgoing message.</para>
73                                                 </enum>
74                                         </enumlist>
75                                 </enum>
76                                 <enum name="body">
77                                         <para>Read/Write.  The message body.  When processing an incoming
78                                         message, this includes the body of the message that Asterisk
79                                         received.  When MessageSend() is executed, the contents of this
80                                         field are used as the body of the outgoing message.  The body
81                                         will always be UTF-8.</para>
82                                 </enum>
83                         </enumlist>
84                         </parameter>
85                 </syntax>
86                 <description>
87                         <para>This function will read from or write a value to a text message.
88                         It is used both to read the data out of an incoming message, as well as
89                         modify or create a message that will be sent outbound.</para>
90                 </description>
91                 <see-also>
92                         <ref type="application">MessageSend</ref>
93                 </see-also>
94         </function>
95         <function name="MESSAGE_DATA" language="en_US">
96                 <synopsis>
97                         Read or write custom data attached to a message.
98                 </synopsis>
99                 <syntax argsep="/">
100                         <parameter name="argument" required="true">
101                         <para>Field of the message to get or set.</para>
102                         </parameter>
103                 </syntax>
104                 <description>
105                         <para>This function will read from or write a value to a text message.
106                         It is used both to read the data out of an incoming message, as well as
107                         modify a message that will be sent outbound.</para>
108                         <note>
109                                 <para>If you want to set an outbound message to carry data in the
110                                 current message, do
111                                 Set(MESSAGE_DATA(<replaceable>key</replaceable>)=${MESSAGE_DATA(<replaceable>key</replaceable>)}).</para>
112                         </note>
113                 </description>
114                 <see-also>
115                         <ref type="application">MessageSend</ref>
116                 </see-also>
117         </function>
118         <application name="MessageSend" language="en_US">
119                 <synopsis>
120                         Send a text message.
121                 </synopsis>
122                 <syntax>
123                         <parameter name="to" required="true">
124                                 <para>A To URI for the message.</para>
125                                 <xi:include xpointer="xpointer(/docs/info[@name='PJSIPMessageToInfo'])" />
126                                 <xi:include xpointer="xpointer(/docs/info[@name='SIPMessageToInfo'])" />
127                                 <xi:include xpointer="xpointer(/docs/info[@name='XMPPMessageToInfo'])" />
128                         </parameter>
129                         <parameter name="from" required="false">
130                                 <para>A From URI for the message if needed for the
131                                 message technology being used to send this message.</para>
132                                 <xi:include xpointer="xpointer(/docs/info[@name='PJSIPMessageFromInfo'])" />
133                                 <xi:include xpointer="xpointer(/docs/info[@name='SIPMessageFromInfo'])" />
134                                 <xi:include xpointer="xpointer(/docs/info[@name='XMPPMessageFromInfo'])" />
135                         </parameter>
136                 </syntax>
137                 <description>
138                         <para>Send a text message.  The body of the message that will be
139                         sent is what is currently set to <literal>MESSAGE(body)</literal>.
140                           The technology chosen for sending the message is determined
141                         based on a prefix to the <literal>to</literal> parameter.</para>
142                         <para>This application sets the following channel variables:</para>
143                         <variablelist>
144                                 <variable name="MESSAGE_SEND_STATUS">
145                                         <para>This is the message delivery status returned by this application.</para>
146                                         <value name="INVALID_PROTOCOL">
147                                                 No handler for the technology part of the URI was found.
148                                         </value>
149                                         <value name="INVALID_URI">
150                                                 The protocol handler reported that the URI was not valid.
151                                         </value>
152                                         <value name="SUCCESS">
153                                                 Successfully passed on to the protocol handler, but delivery has not necessarily been guaranteed.
154                                         </value>
155                                         <value name="FAILURE">
156                                                 The protocol handler reported that it was unabled to deliver the message for some reason.
157                                         </value>
158                                 </variable>
159                         </variablelist>
160                 </description>
161         </application>
162         <manager name="MessageSend" language="en_US">
163                 <synopsis>
164                         Send an out of call message to an endpoint.
165                 </synopsis>
166                 <syntax>
167                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
168                         <parameter name="To" required="true">
169                                 <para>The URI the message is to be sent to.</para>
170                                 <xi:include xpointer="xpointer(/docs/info[@name='PJSIPMessageToInfo'])" />
171                                 <xi:include xpointer="xpointer(/docs/info[@name='SIPMessageToInfo'])" />
172                                 <xi:include xpointer="xpointer(/docs/info[@name='XMPPMessageToInfo'])" />
173                         </parameter>
174                         <parameter name="From">
175                                 <para>A From URI for the message if needed for the
176                                 message technology being used to send this message.</para>
177                                 <xi:include xpointer="xpointer(/docs/info[@name='PJSIPMessageFromInfo'])" />
178                                 <xi:include xpointer="xpointer(/docs/info[@name='SIPMessageFromInfo'])" />
179                                 <xi:include xpointer="xpointer(/docs/info[@name='XMPPMessageFromInfo'])" />
180                         </parameter>
181                         <parameter name="Body">
182                                 <para>The message body text.  This must not contain any newlines as that
183                                 conflicts with the AMI protocol.</para>
184                         </parameter>
185                         <parameter name="Base64Body">
186                                 <para>Text bodies requiring the use of newlines have to be base64 encoded
187                                 in this field.  Base64Body will be decoded before being sent out.
188                                 Base64Body takes precedence over Body.</para>
189                         </parameter>
190                         <parameter name="Variable">
191                                 <para>Message variable to set, multiple Variable: headers are
192                                 allowed.  The header value is a comma separated list of
193                                 name=value pairs.</para>
194                         </parameter>
195                 </syntax>
196         </manager>
197  ***/
198
199 struct msg_data {
200         AST_DECLARE_STRING_FIELDS(
201                 AST_STRING_FIELD(name);
202                 AST_STRING_FIELD(value);
203         );
204         unsigned int send:1; /* Whether to send out on outbound messages */
205 };
206
207 AST_LIST_HEAD_NOLOCK(outhead, msg_data);
208
209 /*!
210  * \brief A message.
211  *
212  * \todo Consider whether stringfields would be an appropriate optimization here.
213  */
214 struct ast_msg {
215         struct ast_str *to;
216         struct ast_str *from;
217         struct ast_str *body;
218         struct ast_str *context;
219         struct ast_str *exten;
220         struct ao2_container *vars;
221 };
222
223 struct ast_msg_tech_holder {
224         const struct ast_msg_tech *tech;
225         /*!
226          * \brief A rwlock for this object
227          *
228          * a read/write lock must be used to protect the wrapper instead
229          * of the ao2 lock. A rdlock must be held to read tech_holder->tech.
230          */
231         ast_rwlock_t tech_lock;
232 };
233
234 static struct ao2_container *msg_techs;
235
236 static struct ast_taskprocessor *msg_q_tp;
237
238 static const char app_msg_send[] = "MessageSend";
239
240 static void msg_ds_destroy(void *data);
241
242 static const struct ast_datastore_info msg_datastore = {
243         .type = "message",
244         .destroy = msg_ds_destroy,
245 };
246
247 static int msg_func_read(struct ast_channel *chan, const char *function,
248                 char *data, char *buf, size_t len);
249 static int msg_func_write(struct ast_channel *chan, const char *function,
250                 char *data, const char *value);
251
252 static struct ast_custom_function msg_function = {
253         .name = "MESSAGE",
254         .read = msg_func_read,
255         .write = msg_func_write,
256 };
257
258 static int msg_data_func_read(struct ast_channel *chan, const char *function,
259                 char *data, char *buf, size_t len);
260 static int msg_data_func_write(struct ast_channel *chan, const char *function,
261                 char *data, const char *value);
262
263 static struct ast_custom_function msg_data_function = {
264         .name = "MESSAGE_DATA",
265         .read = msg_data_func_read,
266         .write = msg_data_func_write,
267 };
268
269 static struct ast_frame *chan_msg_read(struct ast_channel *chan);
270 static int chan_msg_write(struct ast_channel *chan, struct ast_frame *fr);
271 static int chan_msg_indicate(struct ast_channel *chan, int condition,
272                 const void *data, size_t datalen);
273 static int chan_msg_send_digit_begin(struct ast_channel *chan, char digit);
274 static int chan_msg_send_digit_end(struct ast_channel *chan, char digit,
275                 unsigned int duration);
276
277 /*!
278  * \internal
279  * \brief A bare minimum channel technology
280  *
281  * This will not be registered as we never want anything to try
282  * to create Message channels other than internally in this file.
283  */
284 static const struct ast_channel_tech msg_chan_tech_hack = {
285         .type             = "Message",
286         .description      = "Internal Text Message Processing",
287         .read             = chan_msg_read,
288         .write            = chan_msg_write,
289         .indicate         = chan_msg_indicate,
290         .send_digit_begin = chan_msg_send_digit_begin,
291         .send_digit_end   = chan_msg_send_digit_end,
292 };
293
294 /*!
295  * \internal
296  * \brief ast_channel_tech read callback
297  *
298  * This should never be called.  However, we say that about chan_iax2's
299  * read callback, too, and it seems to randomly get called for some
300  * reason.  If it does, a simple NULL frame will suffice.
301  */
302 static struct ast_frame *chan_msg_read(struct ast_channel *chan)
303 {
304         return &ast_null_frame;
305 }
306
307 /*!
308  * \internal
309  * \brief ast_channel_tech write callback
310  *
311  * Throw all frames away.  We don't care about any of them.
312  */
313 static int chan_msg_write(struct ast_channel *chan, struct ast_frame *fr)
314 {
315         return 0;
316 }
317
318 /*!
319  * \internal
320  * \brief ast_channel_tech indicate callback
321  *
322  * The indicate callback is here just so it can return success.
323  * We don't want any callers of ast_indicate() to think something
324  * has failed.  We also don't want ast_indicate() itself to try
325  * to generate inband tones since we didn't tell it that we took
326  * care of it ourselves.
327  */
328 static int chan_msg_indicate(struct ast_channel *chan, int condition,
329                 const void *data, size_t datalen)
330 {
331         return 0;
332 }
333
334 /*!
335  * \internal
336  * \brief ast_channel_tech send_digit_begin callback
337  *
338  * This is here so that just in case a digit comes at a message channel
339  * that the Asterisk core doesn't waste any time trying to generate
340  * inband DTMF in audio.  It's a waste of resources.
341  */
342 static int chan_msg_send_digit_begin(struct ast_channel *chan, char digit)
343 {
344         return 0;
345 }
346
347 /*!
348  * \internal
349  * \brief ast_channel_tech send_digit_end callback
350  *
351  * This is here so that just in case a digit comes at a message channel
352  * that the Asterisk core doesn't waste any time trying to generate
353  * inband DTMF in audio.  It's a waste of resources.
354  */
355 static int chan_msg_send_digit_end(struct ast_channel *chan, char digit,
356                 unsigned int duration)
357 {
358         return 0;
359 }
360
361 static void msg_ds_destroy(void *data)
362 {
363         struct ast_msg *msg = data;
364
365         ao2_ref(msg, -1);
366 }
367
368 static int msg_data_hash_fn(const void *obj, const int flags)
369 {
370         const struct msg_data *data = obj;
371         return ast_str_case_hash(data->name);
372 }
373
374 static int msg_data_cmp_fn(void *obj, void *arg, int flags)
375 {
376         const struct msg_data *one = obj, *two = arg;
377         return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP : 0;
378 }
379
380 static void msg_data_destructor(void *obj)
381 {
382         struct msg_data *data = obj;
383         ast_string_field_free_memory(data);
384 }
385
386 static void msg_destructor(void *obj)
387 {
388         struct ast_msg *msg = obj;
389
390         ast_free(msg->to);
391         msg->to = NULL;
392
393         ast_free(msg->from);
394         msg->from = NULL;
395
396         ast_free(msg->body);
397         msg->body = NULL;
398
399         ast_free(msg->context);
400         msg->context = NULL;
401
402         ast_free(msg->exten);
403         msg->exten = NULL;
404
405         ao2_ref(msg->vars, -1);
406 }
407
408 struct ast_msg *ast_msg_alloc(void)
409 {
410         struct ast_msg *msg;
411
412         if (!(msg = ao2_alloc(sizeof(*msg), msg_destructor))) {
413                 return NULL;
414         }
415
416         if (!(msg->to = ast_str_create(32))) {
417                 ao2_ref(msg, -1);
418                 return NULL;
419         }
420
421         if (!(msg->from = ast_str_create(32))) {
422                 ao2_ref(msg, -1);
423                 return NULL;
424         }
425
426         if (!(msg->body = ast_str_create(128))) {
427                 ao2_ref(msg, -1);
428                 return NULL;
429         }
430
431         if (!(msg->context = ast_str_create(16))) {
432                 ao2_ref(msg, -1);
433                 return NULL;
434         }
435
436         if (!(msg->exten = ast_str_create(16))) {
437                 ao2_ref(msg, -1);
438                 return NULL;
439         }
440
441         if (!(msg->vars = ao2_container_alloc(1, msg_data_hash_fn, msg_data_cmp_fn))) {
442                 ao2_ref(msg, -1);
443                 return NULL;
444         }
445
446         ast_str_set(&msg->context, 0, "default");
447
448         return msg;
449 }
450
451 struct ast_msg *ast_msg_ref(struct ast_msg *msg)
452 {
453         ao2_ref(msg, 1);
454         return msg;
455 }
456
457 struct ast_msg *ast_msg_destroy(struct ast_msg *msg)
458 {
459         ao2_ref(msg, -1);
460
461         return NULL;
462 }
463
464 int ast_msg_set_to(struct ast_msg *msg, const char *fmt, ...)
465 {
466         va_list ap;
467         int res;
468
469         va_start(ap, fmt);
470         res = ast_str_set_va(&msg->to, 0, fmt, ap);
471         va_end(ap);
472
473         return res < 0 ? -1 : 0;
474 }
475
476 int ast_msg_set_from(struct ast_msg *msg, const char *fmt, ...)
477 {
478         va_list ap;
479         int res;
480
481         va_start(ap, fmt);
482         res = ast_str_set_va(&msg->from, 0, fmt, ap);
483         va_end(ap);
484
485         return res < 0 ? -1 : 0;
486 }
487
488 int ast_msg_set_body(struct ast_msg *msg, const char *fmt, ...)
489 {
490         va_list ap;
491         int res;
492
493         va_start(ap, fmt);
494         res = ast_str_set_va(&msg->body, 0, fmt, ap);
495         va_end(ap);
496
497         return res < 0 ? -1 : 0;
498 }
499
500 int ast_msg_set_context(struct ast_msg *msg, const char *fmt, ...)
501 {
502         va_list ap;
503         int res;
504
505         va_start(ap, fmt);
506         res = ast_str_set_va(&msg->context, 0, fmt, ap);
507         va_end(ap);
508
509         return res < 0 ? -1 : 0;
510 }
511
512 int ast_msg_set_exten(struct ast_msg *msg, const char *fmt, ...)
513 {
514         va_list ap;
515         int res;
516
517         va_start(ap, fmt);
518         res = ast_str_set_va(&msg->exten, 0, fmt, ap);
519         va_end(ap);
520
521         return res < 0 ? -1 : 0;
522 }
523
524 const char *ast_msg_get_body(const struct ast_msg *msg)
525 {
526         return ast_str_buffer(msg->body);
527 }
528
529 static struct msg_data *msg_data_alloc(void)
530 {
531         struct msg_data *data;
532
533         if (!(data = ao2_alloc(sizeof(*data), msg_data_destructor))) {
534                 return NULL;
535         }
536
537         if (ast_string_field_init(data, 32)) {
538                 ao2_ref(data, -1);
539                 return NULL;
540         }
541
542         return data;
543 }
544
545 static struct msg_data *msg_data_find(struct ao2_container *vars, const char *name)
546 {
547         struct msg_data tmp = {
548                 .name = name,
549         };
550         return ao2_find(vars, &tmp, OBJ_POINTER);
551 }
552
553 static int msg_set_var_full(struct ast_msg *msg, const char *name, const char *value, unsigned int outbound)
554 {
555         struct msg_data *data;
556
557         if (!(data = msg_data_find(msg->vars, name))) {
558                 if (ast_strlen_zero(value)) {
559                         return 0;
560                 }
561                 if (!(data = msg_data_alloc())) {
562                         return -1;
563                 };
564
565                 ast_string_field_set(data, name, name);
566                 ast_string_field_set(data, value, value);
567                 data->send = outbound;
568                 ao2_link(msg->vars, data);
569         } else {
570                 if (ast_strlen_zero(value)) {
571                         ao2_unlink(msg->vars, data);
572                 } else {
573                         ast_string_field_set(data, value, value);
574                         data->send = outbound;
575                 }
576         }
577
578         ao2_ref(data, -1);
579
580         return 0;
581 }
582
583 int ast_msg_set_var_outbound(struct ast_msg *msg, const char *name, const char *value)
584 {
585         return msg_set_var_full(msg, name, value, 1);
586 }
587
588 int ast_msg_set_var(struct ast_msg *msg, const char *name, const char *value)
589 {
590         return msg_set_var_full(msg, name, value, 0);
591 }
592
593 const char *ast_msg_get_var(struct ast_msg *msg, const char *name)
594 {
595         struct msg_data *data;
596         const char *val = NULL;
597
598         if (!(data = msg_data_find(msg->vars, name))) {
599                 return NULL;
600         }
601
602         /* Yep, this definitely looks like val would be a dangling pointer
603          * after the ref count is decremented.  As long as the message structure
604          * is used in a thread safe manner, this will not be the case though.
605          * The ast_msg holds a reference to this object in the msg->vars container. */
606         val = data->value;
607         ao2_ref(data, -1);
608
609         return val;
610 }
611
612 struct ast_msg_var_iterator {
613         struct ao2_iterator iter;
614         struct msg_data *current_used;
615 };
616
617 struct ast_msg_var_iterator *ast_msg_var_iterator_init(const struct ast_msg *msg)
618 {
619         struct ast_msg_var_iterator *iter;
620
621         iter = ast_calloc(1, sizeof(*iter));
622         if (!iter) {
623                 return NULL;
624         }
625
626         iter->iter = ao2_iterator_init(msg->vars, 0);
627
628         return iter;
629 }
630
631 int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
632 {
633         struct msg_data *data;
634
635         if (!iter) {
636                 return 0;
637         }
638
639         /* Skip any that aren't marked for sending out */
640         while ((data = ao2_iterator_next(&iter->iter)) && !data->send) {
641                 ao2_ref(data, -1);
642         }
643
644         if (!data) {
645                 return 0;
646         }
647
648         if (data->send) {
649                 *name = data->name;
650                 *value = data->value;
651         }
652
653         /* Leave the refcount to be cleaned up by the caller with
654          * ast_msg_var_unref_current after they finish with the pointers to the data */
655         iter->current_used = data;
656
657         return 1;
658 }
659
660 void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
661 {
662         ao2_cleanup(iter->current_used);
663         iter->current_used = NULL;
664 }
665
666 void ast_msg_var_iterator_destroy(struct ast_msg_var_iterator *iter)
667 {
668         if (iter) {
669                 ao2_iterator_destroy(&iter->iter);
670                 ast_msg_var_unref_current(iter);
671                 ast_free(iter);
672         }
673 }
674
675 static struct ast_channel *create_msg_q_chan(void)
676 {
677         struct ast_channel *chan;
678         struct ast_datastore *ds;
679
680         chan = ast_channel_alloc(1, AST_STATE_UP,
681                         NULL, NULL, NULL,
682                         NULL, NULL, NULL, NULL, 0,
683                         "%s", "Message/ast_msg_queue");
684
685         if (!chan) {
686                 return NULL;
687         }
688
689         ast_channel_tech_set(chan, &msg_chan_tech_hack);
690         ast_channel_unlock(chan);
691         ast_channel_unlink(chan);
692
693         if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
694                 ast_hangup(chan);
695                 return NULL;
696         }
697
698         ast_channel_lock(chan);
699         ast_channel_datastore_add(chan, ds);
700         ast_channel_unlock(chan);
701
702         return chan;
703 }
704
705 /*!
706  * \internal
707  * \brief Run the dialplan for message processing
708  *
709  * \pre The message has already been set up on the msg datastore
710  *      on this channel.
711  */
712 static void msg_route(struct ast_channel *chan, struct ast_msg *msg)
713 {
714         struct ast_pbx_args pbx_args;
715
716         ast_explicit_goto(chan, ast_str_buffer(msg->context), AS_OR(msg->exten, "s"), 1);
717
718         memset(&pbx_args, 0, sizeof(pbx_args));
719         pbx_args.no_hangup_chan = 1,
720         ast_pbx_run_args(chan, &pbx_args);
721 }
722
723 /*!
724  * \internal
725  * \brief Clean up ast_channel after each message
726  *
727  * Reset various bits of state after routing each message so the same ast_channel
728  * can just be reused.
729  */
730 static void chan_cleanup(struct ast_channel *chan)
731 {
732         struct ast_datastore *msg_ds, *ds;
733         struct varshead *headp;
734         struct ast_var_t *vardata;
735
736         ast_channel_lock(chan);
737
738         /*
739          * Remove the msg datastore.  Free its data but keep around the datastore
740          * object and just reuse it.
741          */
742         if ((msg_ds = ast_channel_datastore_find(chan, &msg_datastore, NULL)) && msg_ds->data) {
743                 ast_channel_datastore_remove(chan, msg_ds);
744                 ao2_ref(msg_ds->data, -1);
745                 msg_ds->data = NULL;
746         }
747
748         /*
749          * Destroy all other datastores.
750          */
751         while ((ds = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry))) {
752                 ast_datastore_free(ds);
753         }
754
755         /*
756          * Destroy all channel variables.
757          */
758         headp = ast_channel_varshead(chan);
759         while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
760                 ast_var_delete(vardata);
761         }
762
763         /*
764          * Restore msg datastore.
765          */
766         if (msg_ds) {
767                 ast_channel_datastore_add(chan, msg_ds);
768         }
769         /*
770          * Clear softhangup flags.
771          */
772         ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ALL);
773
774         ast_channel_unlock(chan);
775 }
776
777 static void destroy_msg_q_chan(void *data)
778 {
779         struct ast_channel **chan = data;
780
781         if (!*chan) {
782                 return;
783         }
784
785         ast_channel_release(*chan);
786 }
787
788 AST_THREADSTORAGE_CUSTOM(msg_q_chan, NULL, destroy_msg_q_chan);
789
790 /*!
791  * \internal
792  * \brief Message queue task processor callback
793  *
794  * \retval 0 success
795  * \retval -1 failure
796  *
797  * \note Even though this returns a value, the taskprocessor code ignores the value.
798  */
799 static int msg_q_cb(void *data)
800 {
801         struct ast_msg *msg = data;
802         struct ast_channel **chan_p, *chan;
803         struct ast_datastore *ds;
804
805         if (!(chan_p = ast_threadstorage_get(&msg_q_chan, sizeof(struct ast_channel *)))) {
806                 return -1;
807         }
808         if (!*chan_p) {
809                 if (!(*chan_p = create_msg_q_chan())) {
810                         return -1;
811                 }
812         }
813         chan = *chan_p;
814
815         ast_channel_lock(chan);
816         if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
817                 ast_channel_unlock(chan);
818                 return -1;
819         }
820         ao2_ref(msg, +1);
821         ds->data = msg;
822         ast_channel_unlock(chan);
823
824         msg_route(chan, msg);
825         chan_cleanup(chan);
826
827         ao2_ref(msg, -1);
828
829         return 0;
830 }
831
832 int ast_msg_queue(struct ast_msg *msg)
833 {
834         int res;
835
836         res = ast_taskprocessor_push(msg_q_tp, msg_q_cb, msg);
837         if (res == -1) {
838                 ao2_ref(msg, -1);
839         }
840
841         return res;
842 }
843
844 /*!
845  * \internal
846  * \brief Find or create a message datastore on a channel
847  *
848  * \pre chan is locked
849  *
850  * \param chan the relevant channel
851  *
852  * \return the channel's message datastore, or NULL on error
853  */
854 static struct ast_datastore *msg_datastore_find_or_create(struct ast_channel *chan)
855 {
856         struct ast_datastore *ds;
857
858         if ((ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
859                 return ds;
860         }
861
862         if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
863                 return NULL;
864         }
865
866         if (!(ds->data = ast_msg_alloc())) {
867                 ast_datastore_free(ds);
868                 return NULL;
869         }
870
871         ast_channel_datastore_add(chan, ds);
872
873         return ds;
874 }
875
876 static int msg_func_read(struct ast_channel *chan, const char *function,
877                 char *data, char *buf, size_t len)
878 {
879         struct ast_datastore *ds;
880         struct ast_msg *msg;
881
882         if (!chan) {
883                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
884                 return -1;
885         }
886
887         ast_channel_lock(chan);
888
889         if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
890                 ast_channel_unlock(chan);
891                 ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
892                 return -1;
893         }
894
895         msg = ds->data;
896         ao2_ref(msg, +1);
897         ast_channel_unlock(chan);
898
899         ao2_lock(msg);
900
901         if (!strcasecmp(data, "to")) {
902                 ast_copy_string(buf, ast_str_buffer(msg->to), len);
903         } else if (!strcasecmp(data, "from")) {
904                 ast_copy_string(buf, ast_str_buffer(msg->from), len);
905         } else if (!strcasecmp(data, "body")) {
906                 ast_copy_string(buf, ast_msg_get_body(msg), len);
907         } else {
908                 ast_log(LOG_WARNING, "Invalid argument to MESSAGE(): '%s'\n", data);
909         }
910
911         ao2_unlock(msg);
912         ao2_ref(msg, -1);
913
914         return 0;
915 }
916
917 static int msg_func_write(struct ast_channel *chan, const char *function,
918                 char *data, const char *value)
919 {
920         struct ast_datastore *ds;
921         struct ast_msg *msg;
922
923         if (!chan) {
924                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
925                 return -1;
926         }
927
928         ast_channel_lock(chan);
929
930         if (!(ds = msg_datastore_find_or_create(chan))) {
931                 ast_channel_unlock(chan);
932                 return -1;
933         }
934
935         msg = ds->data;
936         ao2_ref(msg, +1);
937         ast_channel_unlock(chan);
938
939         ao2_lock(msg);
940
941         if (!strcasecmp(data, "to")) {
942                 ast_msg_set_to(msg, "%s", value);
943         } else if (!strcasecmp(data, "from")) {
944                 ast_msg_set_from(msg, "%s", value);
945         } else if (!strcasecmp(data, "body")) {
946                 ast_msg_set_body(msg, "%s", value);
947         } else if (!strcasecmp(data, "custom_data")) {
948                 int outbound = -1;
949                 if (!strcasecmp(value, "mark_all_outbound")) {
950                         outbound = 1;
951                 } else if (!strcasecmp(value, "clear_all_outbound")) {
952                         outbound = 0;
953                 } else {
954                         ast_log(LOG_WARNING, "'%s' is not a valid value for custom_data\n", value);
955                 }
956
957                 if (outbound != -1) {
958                         struct msg_data *hdr_data;
959                         struct ao2_iterator iter = ao2_iterator_init(msg->vars, 0);
960
961                         while ((hdr_data = ao2_iterator_next(&iter))) {
962                                 hdr_data->send = outbound;
963                                 ao2_ref(hdr_data, -1);
964                         }
965                         ao2_iterator_destroy(&iter);
966                 }
967         } else {
968                 ast_log(LOG_WARNING, "'%s' is not a valid write argument.\n", data);
969         }
970
971         ao2_unlock(msg);
972         ao2_ref(msg, -1);
973
974         return 0;
975 }
976
977 static int msg_data_func_read(struct ast_channel *chan, const char *function,
978                 char *data, char *buf, size_t len)
979 {
980         struct ast_datastore *ds;
981         struct ast_msg *msg;
982         const char *val;
983
984         if (!chan) {
985                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
986                 return -1;
987         }
988
989         ast_channel_lock(chan);
990
991         if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
992                 ast_channel_unlock(chan);
993                 ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
994                 return -1;
995         }
996
997         msg = ds->data;
998         ao2_ref(msg, +1);
999         ast_channel_unlock(chan);
1000
1001         ao2_lock(msg);
1002
1003         if ((val = ast_msg_get_var(msg, data))) {
1004                 ast_copy_string(buf, val, len);
1005         }
1006
1007         ao2_unlock(msg);
1008         ao2_ref(msg, -1);
1009
1010         return 0;
1011 }
1012
1013 static int msg_data_func_write(struct ast_channel *chan, const char *function,
1014                 char *data, const char *value)
1015 {
1016         struct ast_datastore *ds;
1017         struct ast_msg *msg;
1018
1019         if (!chan) {
1020                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1021                 return -1;
1022         }
1023
1024         ast_channel_lock(chan);
1025
1026         if (!(ds = msg_datastore_find_or_create(chan))) {
1027                 ast_channel_unlock(chan);
1028                 return -1;
1029         }
1030
1031         msg = ds->data;
1032         ao2_ref(msg, +1);
1033         ast_channel_unlock(chan);
1034
1035         ao2_lock(msg);
1036
1037         ast_msg_set_var_outbound(msg, data, value);
1038
1039         ao2_unlock(msg);
1040         ao2_ref(msg, -1);
1041
1042         return 0;
1043 }
1044 static int msg_tech_hash(const void *obj, const int flags)
1045 {
1046         struct ast_msg_tech_holder *tech_holder = (struct ast_msg_tech_holder *) obj;
1047         int res = 0;
1048
1049         ast_rwlock_rdlock(&tech_holder->tech_lock);
1050         if (tech_holder->tech) {
1051                 res = ast_str_case_hash(tech_holder->tech->name);
1052         }
1053         ast_rwlock_unlock(&tech_holder->tech_lock);
1054
1055         return res;
1056 }
1057
1058 static int msg_tech_cmp(void *obj, void *arg, int flags)
1059 {
1060         struct ast_msg_tech_holder *tech_holder = obj;
1061         const struct ast_msg_tech_holder *tech_holder2 = arg;
1062         int res = 1;
1063
1064         ast_rwlock_rdlock(&tech_holder->tech_lock);
1065         /*
1066          * tech_holder2 is a temporary fake tech_holder.
1067          */
1068         if (tech_holder->tech) {
1069                 res = strcasecmp(tech_holder->tech->name, tech_holder2->tech->name) ? 0 : CMP_MATCH | CMP_STOP;
1070         }
1071         ast_rwlock_unlock(&tech_holder->tech_lock);
1072
1073         return res;
1074 }
1075
1076 static struct ast_msg_tech_holder *msg_find_by_tech(const struct ast_msg_tech *msg_tech, int ao2_flags)
1077 {
1078         struct ast_msg_tech_holder *tech_holder;
1079         struct ast_msg_tech_holder tmp_tech_holder = {
1080                 .tech = msg_tech,
1081         };
1082
1083         ast_rwlock_init(&tmp_tech_holder.tech_lock);
1084         tech_holder = ao2_find(msg_techs, &tmp_tech_holder, ao2_flags);
1085         ast_rwlock_destroy(&tmp_tech_holder.tech_lock);
1086         return tech_holder;
1087 }
1088
1089 static struct ast_msg_tech_holder *msg_find_by_tech_name(const char *tech_name, int ao2_flags)
1090 {
1091         struct ast_msg_tech tmp_msg_tech = {
1092                 .name = tech_name,
1093         };
1094         return msg_find_by_tech(&tmp_msg_tech, ao2_flags);
1095 }
1096
1097 /*!
1098  * \internal
1099  * \brief MessageSend() application
1100  */
1101 static int msg_send_exec(struct ast_channel *chan, const char *data)
1102 {
1103         struct ast_datastore *ds;
1104         struct ast_msg *msg;
1105         char *tech_name;
1106         struct ast_msg_tech_holder *tech_holder = NULL;
1107         char *parse;
1108         int res = -1;
1109         AST_DECLARE_APP_ARGS(args,
1110                 AST_APP_ARG(to);
1111                 AST_APP_ARG(from);
1112         );
1113
1114         if (ast_strlen_zero(data)) {
1115                 ast_log(LOG_WARNING, "An argument is required to MessageSend()\n");
1116                 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1117                 return 0;
1118         }
1119
1120         parse = ast_strdupa(data);
1121         AST_STANDARD_APP_ARGS(args, parse);
1122
1123         if (ast_strlen_zero(args.to)) {
1124                 ast_log(LOG_WARNING, "A 'to' URI is required for MessageSend()\n");
1125                 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1126                 return 0;
1127         }
1128
1129         ast_channel_lock(chan);
1130
1131         if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1132                 ast_channel_unlock(chan);
1133                 ast_log(LOG_WARNING, "No message data found on channel to send.\n");
1134                 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "FAILURE");
1135                 return 0;
1136         }
1137
1138         msg = ds->data;
1139         ao2_ref(msg, +1);
1140         ast_channel_unlock(chan);
1141
1142         tech_name = ast_strdupa(args.to);
1143         tech_name = strsep(&tech_name, ":");
1144
1145         tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
1146
1147         if (!tech_holder) {
1148                 ast_log(LOG_WARNING, "No message technology '%s' found.\n", tech_name);
1149                 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_PROTOCOL");
1150                 goto exit_cleanup;
1151         }
1152
1153         /*
1154          * The message lock is held here to safely allow the technology
1155          * implementation to access the message fields without worrying
1156          * that they could change.
1157          */
1158         ao2_lock(msg);
1159         ast_rwlock_rdlock(&tech_holder->tech_lock);
1160         if (tech_holder->tech) {
1161                 res = tech_holder->tech->msg_send(msg, S_OR(args.to, ""),
1162                                                         S_OR(args.from, ""));
1163         }
1164         ast_rwlock_unlock(&tech_holder->tech_lock);
1165         ao2_unlock(msg);
1166
1167         pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", res ? "FAILURE" : "SUCCESS");
1168
1169 exit_cleanup:
1170         if (tech_holder) {
1171                 ao2_ref(tech_holder, -1);
1172                 tech_holder = NULL;
1173         }
1174
1175         ao2_ref(msg, -1);
1176
1177         return 0;
1178 }
1179
1180 static int action_messagesend(struct mansession *s, const struct message *m)
1181 {
1182         const char *to = ast_strdupa(astman_get_header(m, "To"));
1183         const char *from = astman_get_header(m, "From");
1184         const char *body = astman_get_header(m, "Body");
1185         const char *base64body = astman_get_header(m, "Base64Body");
1186         char base64decoded[1301] = { 0, };
1187         char *tech_name = NULL;
1188         struct ast_variable *vars = NULL;
1189         struct ast_variable *data = NULL;
1190         struct ast_msg_tech_holder *tech_holder = NULL;
1191         struct ast_msg *msg;
1192         int res = -1;
1193
1194         if (ast_strlen_zero(to)) {
1195                 astman_send_error(s, m, "No 'To' address specified.");
1196                 return -1;
1197         }
1198
1199         if (!ast_strlen_zero(base64body)) {
1200                 ast_base64decode((unsigned char *) base64decoded, base64body, sizeof(base64decoded) - 1);
1201                 body = base64decoded;
1202         }
1203
1204         tech_name = ast_strdupa(to);
1205         tech_name = strsep(&tech_name, ":");
1206
1207         tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
1208
1209         if (!tech_holder) {
1210                 astman_send_error(s, m, "Message technology not found.");
1211                 return -1;
1212         }
1213
1214         if (!(msg = ast_msg_alloc())) {
1215                 ao2_ref(tech_holder, -1);
1216                 astman_send_error(s, m, "Internal failure\n");
1217                 return -1;
1218         }
1219
1220         data = astman_get_variables(m);
1221         for (vars = data; vars; vars = vars->next) {
1222                 ast_msg_set_var_outbound(msg, vars->name, vars->value);
1223         }
1224
1225         ast_msg_set_body(msg, "%s", body);
1226
1227         ast_rwlock_rdlock(&tech_holder->tech_lock);
1228         if (tech_holder->tech) {
1229                 res = tech_holder->tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1230         }
1231         ast_rwlock_unlock(&tech_holder->tech_lock);
1232
1233         ast_variables_destroy(vars);
1234         ao2_ref(tech_holder, -1);
1235         ao2_ref(msg, -1);
1236
1237         if (res) {
1238                 astman_send_error(s, m, "Message failed to send.");
1239         } else {
1240                 astman_send_ack(s, m, "Message successfully sent");
1241         }
1242         return res;
1243 }
1244
1245 int ast_msg_send(struct ast_msg *msg, const char *to, const char *from)
1246 {
1247         char *tech_name = NULL;
1248         struct ast_msg_tech_holder *tech_holder = NULL;
1249         int res = -1;
1250
1251         if (ast_strlen_zero(to)) {
1252                 ao2_ref(msg, -1);
1253                 return -1;
1254         }
1255
1256         tech_name = ast_strdupa(to);
1257         tech_name = strsep(&tech_name, ":");
1258
1259         tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
1260
1261         if (!tech_holder) {
1262                 ao2_ref(msg, -1);
1263                 return -1;
1264         }
1265
1266         ast_rwlock_rdlock(&tech_holder->tech_lock);
1267         if (tech_holder->tech) {
1268                 res = tech_holder->tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1269         }
1270         ast_rwlock_unlock(&tech_holder->tech_lock);
1271
1272         ao2_ref(tech_holder, -1);
1273         ao2_ref(msg, -1);
1274
1275         return res;
1276 }
1277
1278 int ast_msg_tech_register(const struct ast_msg_tech *tech)
1279 {
1280         struct ast_msg_tech_holder *tech_holder;
1281
1282         if ((tech_holder = msg_find_by_tech(tech, OBJ_POINTER))) {
1283                 ao2_ref(tech_holder, -1);
1284                 ast_log(LOG_ERROR, "Message technology already registered for '%s'\n",
1285                                 tech->name);
1286                 return -1;
1287         }
1288
1289         if (!(tech_holder = ao2_alloc(sizeof(*tech_holder), NULL))) {
1290                 return -1;
1291         }
1292
1293         ast_rwlock_init(&tech_holder->tech_lock);
1294         tech_holder->tech = tech;
1295
1296         ao2_link(msg_techs, tech_holder);
1297
1298         ao2_ref(tech_holder, -1);
1299         tech_holder = NULL;
1300
1301         ast_verb(3, "Message technology handler '%s' registered.\n", tech->name);
1302
1303         return 0;
1304 }
1305
1306 int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
1307 {
1308         struct ast_msg_tech_holder *tech_holder;
1309
1310         tech_holder = msg_find_by_tech(tech, OBJ_POINTER | OBJ_UNLINK);
1311
1312         if (!tech_holder) {
1313                 ast_log(LOG_ERROR, "No '%s' message technology found.\n", tech->name);
1314                 return -1;
1315         }
1316
1317         ast_rwlock_wrlock(&tech_holder->tech_lock);
1318         tech_holder->tech = NULL;
1319         ast_rwlock_unlock(&tech_holder->tech_lock);
1320
1321         ao2_ref(tech_holder, -1);
1322         tech_holder = NULL;
1323
1324         ast_verb(3, "Message technology handler '%s' unregistered.\n", tech->name);
1325
1326         return 0;
1327 }
1328
1329 void ast_msg_shutdown(void)
1330 {
1331         if (msg_q_tp) {
1332                 msg_q_tp = ast_taskprocessor_unreference(msg_q_tp);
1333         }
1334 }
1335
1336 /*!
1337  * \internal
1338  * \brief Clean up other resources on Asterisk shutdown
1339  *
1340  * \note This does not include the msg_q_tp object, which must be disposed
1341  * of prior to Asterisk checking for channel destruction in its shutdown
1342  * sequence.  The atexit handlers are executed after this occurs.
1343  */
1344 static void message_shutdown(void)
1345 {
1346         ast_custom_function_unregister(&msg_function);
1347         ast_custom_function_unregister(&msg_data_function);
1348         ast_unregister_application(app_msg_send);
1349         ast_manager_unregister("MessageSend");
1350
1351         if (msg_techs) {
1352                 ao2_ref(msg_techs, -1);
1353                 msg_techs = NULL;
1354         }
1355 }
1356
1357 /*
1358  * \internal
1359  * \brief Initialize stuff during Asterisk startup.
1360  *
1361  * Cleanup isn't a big deal in this function.  If we return non-zero,
1362  * Asterisk is going to exit.
1363  *
1364  * \retval 0 success
1365  * \retval non-zero failure
1366  */
1367 int ast_msg_init(void)
1368 {
1369         int res;
1370
1371         msg_q_tp = ast_taskprocessor_get("ast_msg_queue", TPS_REF_DEFAULT);
1372         if (!msg_q_tp) {
1373                 return -1;
1374         }
1375
1376         msg_techs = ao2_container_alloc(17, msg_tech_hash, msg_tech_cmp);
1377         if (!msg_techs) {
1378                 return -1;
1379         }
1380
1381         res = __ast_custom_function_register(&msg_function, NULL);
1382         res |= __ast_custom_function_register(&msg_data_function, NULL);
1383         res |= ast_register_application2(app_msg_send, msg_send_exec, NULL, NULL, NULL);
1384         res |= ast_manager_register_xml_core("MessageSend", EVENT_FLAG_MESSAGE, action_messagesend);
1385
1386         ast_register_atexit(message_shutdown);
1387
1388         return res;
1389 }