Asterisk - The Open Source Telephony Project GIT-master-8924258
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 <since>
47 <version>1.0.0</version>
48 </since>
49 <synopsis>
50 Send a Text Message on a channel.
51 </synopsis>
52 <syntax>
53 <parameter name="text" required="false" />
54 </syntax>
55 <description>
56 <para>Sends <replaceable>text</replaceable> to the current channel.</para>
57 <note><para><literal>current channel</literal> could be the caller or callee depending
58 on the context in which this application is called.</para></note>
59 <para>
60 </para>
61 <para>The following variables can be set:</para>
62 <variablelist>
63 <variable name="SENDTEXT_FROM_DISPLAYNAME">
64 <para>If set and this channel supports enhanced messaging, this value will be
65 used as the <literal>From</literal> display name.</para>
66 </variable>
67 <variable name="SENDTEXT_TO_DISPLAYNAME">
68 <para>If set and this channel supports enhanced messaging, this value will be
69 used as the <literal>To</literal> display name.</para>
70 </variable>
71 <variable name="SENDTEXT_CONTENT_TYPE">
72 <para>If set and this channel supports enhanced messaging, this value will be
73 used as the message <literal>Content-Type</literal>. If not specified, the
74 default of <literal>text/plain</literal> will be used.</para>
75 <para><emphasis>Warning:</emphasis> Messages of types other than
76 <literal>text/&#42;</literal> cannot be sent via channel drivers that do not
77 support Enhanced Messaging. An attempt to do so will be ignored and will result
78 in the <literal>SENDTEXTSTATUS</literal> variable being set to
79 <literal>UNSUPPORTED</literal>.</para>
80 </variable>
81 <variable name="SENDTEXT_BODY">
82 <para>If set this value will be used as the message body and any text supplied
83 as a function parameter will be ignored.
84 </para>
85 </variable>
86 </variablelist>
87 <para>
88 </para>
89 <para>Result of transmission will be stored in the following variables:</para>
90 <variablelist>
91 <variable name="SENDTEXTTYPE">
92 <value name="NONE">
93 No message sent.
94 </value>
95 <value name="BASIC">
96 Message body sent without attributes because the channel driver
97 doesn't support enhanced messaging.
98 </value>
99 <value name="ENHANCED">
100 The message was sent using enhanced messaging.
101 </value>
102 </variable>
103 <variable name="SENDTEXTSTATUS">
104 <value name="SUCCESS">
105 Transmission succeeded.
106 </value>
107 <value name="FAILURE">
108 Transmission failed.
109 </value>
110 <value name="UNSUPPORTED">
111 Text transmission not supported by channel.
112 </value>
113 </variable>
114 </variablelist>
115 <para>
116 </para>
117 <note><para>The text encoding and transmission method is completely at the
118 discretion of the channel driver. chan_pjsip will use in-dialog SIP MESSAGE
119 messages always.</para></note>
120 <para>
121 </para>
122 <para>Examples:
123 </para>
124 <example title="Send a simple message">
125 same => n,SendText(Your Text Here)
126 </example>
127 <para>If the channel driver supports enhanced messaging (currently only chan_pjsip),
128 you can set additional variables:</para>
129 <example title="Alter the From display name">
130 same => n,Set(SENDTEXT_FROM_DISPLAYNAME=Really From Bob)
131 same => n,SendText(Your Text Here)
132 </example>
133 <example title="Send a JSON String">
134 same => n,Set(SENDTEXT_CONTENT_TYPE=text/json)
135 same => n,SendText({"foo":a, "bar":23})
136 </example>
137 <example title="Send a JSON String (alternate)">
138 same => n,Set(SENDTEXT_CONTENT_TYPE=text/json)
139 same => n,Set(SENDTEXT_BODY={"foo":a, "bar":23})
140 same => n,SendText()
141 </example>
142 </description>
143 <see-also>
144 <ref type="application">ReceiveText</ref>
145 </see-also>
146 </application>
147 <application name="ReceiveText" language="en_US">
148 <since>
149 <version>16.24.0</version>
150 <version>18.10.0</version>
151 <version>19.2.0</version>
152 </since>
153 <synopsis>
154 Receive a Text Message on a channel.
155 </synopsis>
156 <syntax>
157 <parameter name="timeout" required="false">
158 <para>Time in seconds to wait for text. Default is 0 (forever).</para>
159 </parameter>
160 </syntax>
161 <description>
162 <para>Waits for <replaceable>timeout</replaceable> seconds on the current channel
163 to receive text.</para>
164 <para>Result of transmission will be stored in the following variables:</para>
165 <variablelist>
166 <variable name="RECEIVETEXTMESSAGE">
167 <para>The received text message.</para>
168 </variable>
169 <variable name="RECEIVETEXTSTATUS">
170 <value name="SUCCESS">
171 Transmission succeeded.
172 </value>
173 <value name="FAILURE">
174 Transmission failed or timed out.
175 </value>
176 </variable>
177 </variablelist>
178 <example title="Receive message on channel">
179 same => n,ReceiveText()
180 same => n,NoOp(${RECEIVETEXTMESSAGE})
181 </example>
182 </description>
183 <see-also>
184 <ref type="application">SendText</ref>
185 </see-also>
186 </application>
187 ***/
188
189static const char * const app = "SendText";
190static const char * const app2 = "ReceiveText";
191
192static int sendtext_exec(struct ast_channel *chan, const char *data)
193{
194 char *status;
195 char *msg_type;
196 struct ast_str *str;
197 const char *from;
198 const char *to;
199 const char *content_type;
200 const char *body;
201 int rc = 0;
202
203 ast_channel_lock(chan);
204 from = pbx_builtin_getvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME");
205 to = pbx_builtin_getvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME");
206 content_type = pbx_builtin_getvar_helper(chan, "SENDTEXT_CONTENT_TYPE");
207 body = S_OR(pbx_builtin_getvar_helper(chan, "SENDTEXT_BODY"), data);
208 body = S_OR(body, "");
209
210 if (!(str = ast_str_alloca(strlen(body) + 1))) {
211 rc = -1;
212 goto cleanup;
213 }
214 ast_str_get_encoded_str(&str, -1, body);
215 body = ast_str_buffer(str);
216
217 msg_type = "NONE";
218 status = "UNSUPPORTED";
219 if (ast_channel_tech(chan)->send_text_data) {
220 struct ast_msg_data *msg;
221 struct ast_msg_data_attribute attrs[] =
222 {
223 {
225 .value = (char *)S_OR(from, ""),
226 },
227 {
228 .type = AST_MSG_DATA_ATTR_TO,
229 .value = (char *)S_OR(to, ""),
230 },
231 {
233 .value = (char *)S_OR(content_type, ""),
234 },
235 {
237 .value = (char *)S_OR(body, ""),
238 },
239 };
240
241 msg_type = "ENHANCED";
243 if (msg) {
244 if (ast_sendtext_data(chan, msg) == 0) {
245 status = "SUCCESS";
246 } else {
247 status = "FAILURE";
248 }
249
250 ast_free(msg);
251 } else {
252 rc = -1;
253 goto cleanup;
254 }
255
256 } else if (ast_channel_tech(chan)->send_text) {
257 if (!ast_strlen_zero(content_type) && !ast_begins_with(content_type, "text/")) {
258 rc = -1;
259 goto cleanup;
260 }
261
262 msg_type = "BASIC";
263 if (ast_sendtext(chan, body) == 0) {
264 status = "SUCCESS";
265 } else {
266 status = "FAILURE";
267 }
268 }
269
270 pbx_builtin_setvar_helper(chan, "SENDTEXTTYPE", msg_type);
271 pbx_builtin_setvar_helper(chan, "SENDTEXTSTATUS", status);
272
273cleanup:
274 pbx_builtin_setvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME", NULL);
275 pbx_builtin_setvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME", NULL);
276 pbx_builtin_setvar_helper(chan, "SENDTEXT_CONTENT_TYPE", NULL);
277 pbx_builtin_setvar_helper(chan, "SENDTEXT_BODY", NULL);
278 ast_channel_unlock(chan);
279
280 return rc;
281}
282
283static int recvtext_exec(struct ast_channel *chan, const char *data)
284{
285 double timeout = 0, timeout_ms = 0;
286 char *parse, *buf;
287
289 AST_APP_ARG(timeout);
290 );
291
292 parse = ast_strdupa(data);
293
295
296 if (!ast_strlen_zero(args.timeout)) {
297 if (sscanf(args.timeout, "%30lg", &timeout) != 1) {
298 ast_log(LOG_WARNING, "Invalid timeout provided: %s. No timeout set.\n", args.timeout);
299 return -1;
300 }
301 timeout_ms = timeout * 1000.0;
302 }
303
304 buf = ast_recvtext(chan, timeout_ms);
305 pbx_builtin_setvar_helper(chan, "RECEIVETEXTSTATUS", buf ? "SUCCESS" : "FAILURE");
306 if (buf) {
307 pbx_builtin_setvar_helper(chan, "RECEIVETEXTMESSAGE", buf);
308 ast_free(buf);
309 }
310
311 return 0;
312}
313
314static int unload_module(void)
315{
316 int res;
317
320
321 return res;
322}
323
324static int load_module(void)
325{
326 int res;
327
330
331 return res;
332}
333
334AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send and Receive Text Applications");
jack_status_t status
Definition: app_jack.c:149
const char * str
Definition: app_jack.c:150
static int sendtext_exec(struct ast_channel *chan, const char *data)
Definition: app_sendtext.c:192
static const char *const app
Definition: app_sendtext.c:189
static int recvtext_exec(struct ast_channel *chan, const char *data)
Definition: app_sendtext.c:283
static const char *const app2
Definition: app_sendtext.c:190
static int load_module(void)
Definition: app_sendtext.c:324
static int unload_module(void)
Definition: app_sendtext.c:314
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:4734
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:4768
#define ast_channel_lock(chan)
Definition: channel.h:2970
int ast_sendtext(struct ast_channel *chan, const char *text)
Sends text to a channel.
Definition: channel.c:4826
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2971
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:3175
#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:581
#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:640
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