Merge "astobj2: Create function to copy weak proxied objects from container."
[asterisk/asterisk.git] / apps / app_sendtext.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@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 App to transmit a text message
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \note Requires support of sending text messages from channel driver
26  *
27  * \ingroup applications
28  */
29
30 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 #include "asterisk/file.h"
37 #include "asterisk/channel.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/module.h"
40 #include "asterisk/app.h"
41 #include "asterisk/message.h"
42
43 /*** DOCUMENTATION
44         <application name="SendText" language="en_US">
45                 <synopsis>
46                         Send a Text Message on a channel.
47                 </synopsis>
48                 <syntax>
49                         <parameter name="text" required="false" />
50                 </syntax>
51                 <description>
52                         <para>Sends <replaceable>text</replaceable> to the current channel.</para>
53                         <note><para><literal>current channel</literal> could be the caller or callee depending
54                         on the context in which this application is called.</para></note>
55                         <para>
56                         </para>
57                         <para>The following variables can be set:</para>
58                         <variablelist>
59                                 <variable name="SENDTEXT_FROM_DISPLAYNAME">
60                                         <para>If set and this channel supports enhanced messaging, this value will be
61                                         used as the <literal>From</literal> display name.</para>
62                                 </variable>
63                                 <variable name="SENDTEXT_TO_DISPLAYNAME">
64                                         <para>If set and this channel supports enhanced messaging, this value will be
65                                         used as the <literal>To</literal> display name.</para>
66                                 </variable>
67                                 <variable name="SENDTEXT_CONTENT_TYPE">
68                                         <para>If set and this channel supports enhanced messaging, this value will be
69                                         used as the message <literal>Content-Type</literal>.  If not specified, the
70                                         default of <literal>text/plain</literal> will be used.</para>
71                                         <para><emphasis>Warning:</emphasis> Messages of types other than
72                                         <literal>text/&#42;</literal> cannot be sent via channel drivers that do not
73                                         support Enhanced Messaging. An attempt to do so will be ignored and will result
74                                         in the <literal>SENDTEXTSTATUS</literal> variable being set to
75                                         <literal>UNSUPPORTED</literal>.</para>
76                                 </variable>
77                                 <variable name="SENDTEXT_BODY">
78                                         <para>If set this value will be used as the message body and any text supplied
79                                         as a function parameter will be ignored.
80                                         </para>
81                                 </variable>
82                         </variablelist>
83                         <para>
84                         </para>
85                         <para>Result of transmission will be stored in the following variables:</para>
86                         <variablelist>
87                                 <variable name="SENDTEXTTYPE">
88                                         <value name="NONE">
89                                                 No message sent.
90                                         </value>
91                                         <value name="BASIC">
92                                                 Message body sent without attributes because the channel driver
93                                                 doesn't support enhanced messaging.
94                                         </value>
95                                         <value name="ENHANCED">
96                                                 The message was sent using enhanced messaging.
97                                         </value>
98                                 </variable>
99                                 <variable name="SENDTEXTSTATUS">
100                                         <value name="SUCCESS">
101                                                 Transmission succeeded.
102                                         </value>
103                                         <value name="FAILURE">
104                                                 Transmission failed.
105                                         </value>
106                                         <value name="UNSUPPORTED">
107                                                 Text transmission not supported by channel.
108                                         </value>
109                                 </variable>
110                         </variablelist>
111                         <para>
112                         </para>
113                         <note><para>The text encoding and transmission method is completely at the
114                         discretion of the channel driver.  chan_pjsip will use in-dialog SIP MESSAGE
115                         messages always.  chan_sip will use T.140 via RTP if a text media type was
116                         negotiated and in-dialog SIP MESSAGE messages otherwise.</para></note>
117                         <para>
118                         </para>
119                         <para>Examples:
120                         </para>
121                         <example title="Send a simple message">
122                          same => n,SendText(Your Text Here)
123                         </example>
124                         <para>If the channel driver supports enhanced messaging (currently only chan_pjsip),
125                         you can set additional variables:</para>
126                         <example title="Alter the From display name">
127                          same => n,Set(SENDTEXT_FROM_DISPLAYNAME=Really From Bob)
128                          same => n,SendText(Your Text Here)
129                         </example>
130                         <example title="Send a JSON String">
131                          same => n,Set(SENDTEXT_CONTENT_TYPE=text/json)
132                          same => n,SendText({"foo":a, "bar":23})
133                         </example>
134                         <example title="Send a JSON String (alternate)">
135                          same => n,Set(SENDTEXT_CONTENT_TYPE=text/json)
136                          same => n,Set(SENDTEXT_BODY={"foo":a, "bar":23})
137                          same => n,SendText()
138                         </example>
139                 </description>
140                 <see-also>
141                         <ref type="application">SendImage</ref>
142                         <ref type="application">SendURL</ref>
143                 </see-also>
144         </application>
145  ***/
146
147 static const char * const app = "SendText";
148
149 static int sendtext_exec(struct ast_channel *chan, const char *data)
150 {
151         char *status;
152         char *msg_type;
153         struct ast_str *str;
154         const char *from;
155         const char *to;
156         const char *content_type;
157         const char *body;
158         int rc = 0;
159
160         ast_channel_lock(chan);
161         from = pbx_builtin_getvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME");
162         to = pbx_builtin_getvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME");
163         content_type = pbx_builtin_getvar_helper(chan, "SENDTEXT_CONTENT_TYPE");
164         body = S_OR(pbx_builtin_getvar_helper(chan, "SENDTEXT_BODY"), data);
165         body = S_OR(body, "");
166
167         if (!(str = ast_str_alloca(strlen(body) + 1))) {
168                 rc = -1;
169                 goto cleanup;
170         }
171         ast_str_get_encoded_str(&str, -1, body);
172         body = ast_str_buffer(str);
173
174         msg_type = "NONE";
175         status = "UNSUPPORTED";
176         if (ast_channel_tech(chan)->send_text_data) {
177                 struct ast_msg_data *msg;
178                 struct ast_msg_data_attribute attrs[] =
179                 {
180                         {
181                                 .type = AST_MSG_DATA_ATTR_FROM,
182                                 .value = (char *)S_OR(from, ""),
183                         },
184                         {
185                                 .type = AST_MSG_DATA_ATTR_TO,
186                                 .value = (char *)S_OR(to, ""),
187                         },
188                         {
189                                 .type = AST_MSG_DATA_ATTR_CONTENT_TYPE,
190                                 .value = (char *)S_OR(content_type, ""),
191                         },
192                         {
193                                 .type = AST_MSG_DATA_ATTR_BODY,
194                                 .value = (char *)S_OR(body, ""),
195                         },
196                 };
197
198                 msg_type = "ENHANCED";
199                 msg = ast_msg_data_alloc(AST_MSG_DATA_SOURCE_TYPE_IN_DIALOG, attrs, ARRAY_LEN(attrs));
200                 if (msg) {
201                         if (ast_sendtext_data(chan, msg) == 0) {
202                                 status = "SUCCESS";
203                         } else {
204                                 status = "FAILURE";
205                         }
206
207                         ast_free(msg);
208                 } else {
209                         rc = -1;
210                         goto cleanup;
211                 }
212
213         } else if (ast_channel_tech(chan)->send_text) {
214                 if (!ast_strlen_zero(content_type) && !ast_begins_with(content_type, "text/")) {
215                         rc = -1;
216                         goto cleanup;
217                 }
218
219                 msg_type = "BASIC";
220                 if (ast_sendtext(chan, body) == 0) {
221                         status = "SUCCESS";
222                 } else {
223                         status = "FAILURE";
224                 }
225         }
226
227         pbx_builtin_setvar_helper(chan, "SENDTEXTTYPE", msg_type);
228         pbx_builtin_setvar_helper(chan, "SENDTEXTSTATUS", status);
229
230 cleanup:
231         pbx_builtin_setvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME", NULL);
232         pbx_builtin_setvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME", NULL);
233         pbx_builtin_setvar_helper(chan, "SENDTEXT_CONTENT_TYPE", NULL);
234         pbx_builtin_setvar_helper(chan, "SENDTEXT_BODY", NULL);
235         ast_channel_unlock(chan);
236
237         return rc;
238 }
239
240 static int unload_module(void)
241 {
242         return ast_unregister_application(app);
243 }
244
245 static int load_module(void)
246 {
247         return ast_register_application_xml(app, sendtext_exec);
248 }
249
250 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send Text Applications");