Asterisk - The Open Source Telephony Project GIT-master-a358458
app_sendtext.c
Go to the documentation of this file.
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 * \author Naveen Albert <asterisk@phreaknet.org>
25 *
26 * \note Requires support of sending text messages from channel driver
27 *
28 * \ingroup applications
29 */
30
31/*** MODULEINFO
32 <support_level>core</support_level>
33 ***/
34
35#include "asterisk.h"
36
37#include "asterisk/file.h"
38#include "asterisk/channel.h"
39#include "asterisk/pbx.h"
40#include "asterisk/module.h"
41#include "asterisk/app.h"
42#include "asterisk/message.h"
43
44/*** DOCUMENTATION
45 <application name="SendText" language="en_US">
46 <synopsis>
47 Send a Text Message on a channel.
48 </synopsis>
49 <syntax>
50 <parameter name="text" required="false" />
51 </syntax>
52 <description>
53 <para>Sends <replaceable>text</replaceable> to the current channel.</para>
54 <note><para><literal>current channel</literal> could be the caller or callee depending
55 on the context in which this application is called.</para></note>
56 <para>
57 </para>
58 <para>The following variables can be set:</para>
59 <variablelist>
60 <variable name="SENDTEXT_FROM_DISPLAYNAME">
61 <para>If set and this channel supports enhanced messaging, this value will be
62 used as the <literal>From</literal> display name.</para>
63 </variable>
64 <variable name="SENDTEXT_TO_DISPLAYNAME">
65 <para>If set and this channel supports enhanced messaging, this value will be
66 used as the <literal>To</literal> display name.</para>
67 </variable>
68 <variable name="SENDTEXT_CONTENT_TYPE">
69 <para>If set and this channel supports enhanced messaging, this value will be
70 used as the message <literal>Content-Type</literal>. If not specified, the
71 default of <literal>text/plain</literal> will be used.</para>
72 <para><emphasis>Warning:</emphasis> Messages of types other than
73 <literal>text/&#42;</literal> cannot be sent via channel drivers that do not
74 support Enhanced Messaging. An attempt to do so will be ignored and will result
75 in the <literal>SENDTEXTSTATUS</literal> variable being set to
76 <literal>UNSUPPORTED</literal>.</para>
77 </variable>
78 <variable name="SENDTEXT_BODY">
79 <para>If set this value will be used as the message body and any text supplied
80 as a function parameter will be ignored.
81 </para>
82 </variable>
83 </variablelist>
84 <para>
85 </para>
86 <para>Result of transmission will be stored in the following variables:</para>
87 <variablelist>
88 <variable name="SENDTEXTTYPE">
89 <value name="NONE">
90 No message sent.
91 </value>
92 <value name="BASIC">
93 Message body sent without attributes because the channel driver
94 doesn't support enhanced messaging.
95 </value>
96 <value name="ENHANCED">
97 The message was sent using enhanced messaging.
98 </value>
99 </variable>
100 <variable name="SENDTEXTSTATUS">
101 <value name="SUCCESS">
102 Transmission succeeded.
103 </value>
104 <value name="FAILURE">
105 Transmission failed.
106 </value>
107 <value name="UNSUPPORTED">
108 Text transmission not supported by channel.
109 </value>
110 </variable>
111 </variablelist>
112 <para>
113 </para>
114 <note><para>The text encoding and transmission method is completely at the
115 discretion of the channel driver. chan_pjsip will use in-dialog SIP MESSAGE
116 messages always.</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">ReceiveText</ref>
142 </see-also>
143 </application>
144 <application name="ReceiveText" language="en_US">
145 <since>
146 <version>16.24.0</version>
147 <version>18.10.0</version>
148 <version>19.2.0</version>
149 </since>
150 <synopsis>
151 Receive a Text Message on a channel.
152 </synopsis>
153 <syntax>
154 <parameter name="timeout" required="false">
155 <para>Time in seconds to wait for text. Default is 0 (forever).</para>
156 </parameter>
157 </syntax>
158 <description>
159 <para>Waits for <replaceable>timeout</replaceable> seconds on the current channel
160 to receive text.</para>
161 <para>Result of transmission will be stored in the following variables:</para>
162 <variablelist>
163 <variable name="RECEIVETEXTMESSAGE">
164 <para>The received text message.</para>
165 </variable>
166 <variable name="RECEIVETEXTSTATUS">
167 <value name="SUCCESS">
168 Transmission succeeded.
169 </value>
170 <value name="FAILURE">
171 Transmission failed or timed out.
172 </value>
173 </variable>
174 </variablelist>
175 <example title="Receive message on channel">
176 same => n,ReceiveText()
177 same => n,NoOp(${RECEIVETEXTMESSAGE})
178 </example>
179 </description>
180 <see-also>
181 <ref type="application">SendText</ref>
182 </see-also>
183 </application>
184 ***/
185
186static const char * const app = "SendText";
187static const char * const app2 = "ReceiveText";
188
189static int sendtext_exec(struct ast_channel *chan, const char *data)
190{
191 char *status;
192 char *msg_type;
193 struct ast_str *str;
194 const char *from;
195 const char *to;
196 const char *content_type;
197 const char *body;
198 int rc = 0;
199
200 ast_channel_lock(chan);
201 from = pbx_builtin_getvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME");
202 to = pbx_builtin_getvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME");
203 content_type = pbx_builtin_getvar_helper(chan, "SENDTEXT_CONTENT_TYPE");
204 body = S_OR(pbx_builtin_getvar_helper(chan, "SENDTEXT_BODY"), data);
205 body = S_OR(body, "");
206
207 if (!(str = ast_str_alloca(strlen(body) + 1))) {
208 rc = -1;
209 goto cleanup;
210 }
211 ast_str_get_encoded_str(&str, -1, body);
212 body = ast_str_buffer(str);
213
214 msg_type = "NONE";
215 status = "UNSUPPORTED";
216 if (ast_channel_tech(chan)->send_text_data) {
217 struct ast_msg_data *msg;
218 struct ast_msg_data_attribute attrs[] =
219 {
220 {
222 .value = (char *)S_OR(from, ""),
223 },
224 {
225 .type = AST_MSG_DATA_ATTR_TO,
226 .value = (char *)S_OR(to, ""),
227 },
228 {
230 .value = (char *)S_OR(content_type, ""),
231 },
232 {
234 .value = (char *)S_OR(body, ""),
235 },
236 };
237
238 msg_type = "ENHANCED";
240 if (msg) {
241 if (ast_sendtext_data(chan, msg) == 0) {
242 status = "SUCCESS";
243 } else {
244 status = "FAILURE";
245 }
246
247 ast_free(msg);
248 } else {
249 rc = -1;
250 goto cleanup;
251 }
252
253 } else if (ast_channel_tech(chan)->send_text) {
254 if (!ast_strlen_zero(content_type) && !ast_begins_with(content_type, "text/")) {
255 rc = -1;
256 goto cleanup;
257 }
258
259 msg_type = "BASIC";
260 if (ast_sendtext(chan, body) == 0) {
261 status = "SUCCESS";
262 } else {
263 status = "FAILURE";
264 }
265 }
266
267 pbx_builtin_setvar_helper(chan, "SENDTEXTTYPE", msg_type);
268 pbx_builtin_setvar_helper(chan, "SENDTEXTSTATUS", status);
269
270cleanup:
271 pbx_builtin_setvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME", NULL);
272 pbx_builtin_setvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME", NULL);
273 pbx_builtin_setvar_helper(chan, "SENDTEXT_CONTENT_TYPE", NULL);
274 pbx_builtin_setvar_helper(chan, "SENDTEXT_BODY", NULL);
275 ast_channel_unlock(chan);
276
277 return rc;
278}
279
280static int recvtext_exec(struct ast_channel *chan, const char *data)
281{
282 double timeout = 0, timeout_ms = 0;
283 char *parse, *buf;
284
286 AST_APP_ARG(timeout);
287 );
288
289 parse = ast_strdupa(data);
290
292
293 if (!ast_strlen_zero(args.timeout)) {
294 if (sscanf(args.timeout, "%30lg", &timeout) != 1) {
295 ast_log(LOG_WARNING, "Invalid timeout provided: %s. No timeout set.\n", args.timeout);
296 return -1;
297 }
298 timeout_ms = timeout * 1000.0;
299 }
300
301 buf = ast_recvtext(chan, timeout_ms);
302 pbx_builtin_setvar_helper(chan, "RECEIVETEXTSTATUS", buf ? "SUCCESS" : "FAILURE");
303 if (buf) {
304 pbx_builtin_setvar_helper(chan, "RECEIVETEXTMESSAGE", buf);
305 ast_free(buf);
306 }
307
308 return 0;
309}
310
311static int unload_module(void)
312{
313 int res;
314
317
318 return res;
319}
320
321static int load_module(void)
322{
323 int res;
324
327
328 return res;
329}
330
331AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send and Receive Text Applications");
jack_status_t status
Definition: app_jack.c:146
const char * str
Definition: app_jack.c:147
static int sendtext_exec(struct ast_channel *chan, const char *data)
Definition: app_sendtext.c:189
static const char *const app
Definition: app_sendtext.c:186
static int recvtext_exec(struct ast_channel *chan, const char *data)
Definition: app_sendtext.c:280
static const char *const app2
Definition: app_sendtext.c:187
static int load_module(void)
Definition: app_sendtext.c:321
static int unload_module(void)
Definition: app_sendtext.c:311
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
static void send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte, const char *text)
General Asterisk PBX channel definitions.
char * ast_recvtext(struct ast_channel *chan, int timeout)
Receives a text string from a channel Read a string of text from a channel.
Definition: channel.c:4717
int ast_sendtext_data(struct ast_channel *chan, struct ast_msg_data *msg)
Sends text to a channel in an ast_msg_data structure wrapper with ast_sendtext as fallback.
Definition: channel.c:4751
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_sendtext(struct ast_channel *chan, const char *text)
Sends text to a channel.
Definition: channel.c:4809
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Generic File Format Support. Should be included by clients of the file handling routines....
struct ast_msg_data * ast_msg_data_alloc(enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
Allocates an ast_msg_data structure.
@ AST_MSG_DATA_ATTR_BODY
Definition: message.h:458
@ AST_MSG_DATA_ATTR_TO
Definition: message.h:455
@ AST_MSG_DATA_ATTR_FROM
Definition: message.h:456
@ AST_MSG_DATA_ATTR_CONTENT_TYPE
Definition: message.h:457
@ AST_MSG_DATA_SOURCE_TYPE_IN_DIALOG
Definition: message.h:449
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
int ast_str_get_encoded_str(struct ast_str **str, int maxlen, const char *stream)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3165
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_WARNING
Out-of-call text message support.
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
#define NULL
Definition: resample.c:96
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_alloca(init_len)
Definition: strings.h:848
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
Main Channel structure associated with a channel.
enum ast_msg_data_attribute_type type
Definition: message.h:463
Structure used to transport a message through the frame core.
Support for dynamic strings.
Definition: strings.h:623
const char * args
#define ARRAY_LEN(a)
Definition: utils.h:666