2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \brief AGI - the Asterisk Gateway Interface
23 * \author Mark Spencer <markster@digium.com>
25 * \todo Convert the rest of the AGI commands over to XML documentation
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
39 #include "asterisk/paths.h" /* use many ast_config_AST_*_DIR */
40 #include "asterisk/network.h"
41 #include "asterisk/file.h"
42 #include "asterisk/channel.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/module.h"
45 #include "asterisk/astdb.h"
46 #include "asterisk/callerid.h"
47 #include "asterisk/cli.h"
48 #include "asterisk/image.h"
49 #include "asterisk/say.h"
50 #include "asterisk/app.h"
51 #include "asterisk/dsp.h"
52 #include "asterisk/musiconhold.h"
53 #include "asterisk/utils.h"
54 #include "asterisk/lock.h"
55 #include "asterisk/strings.h"
56 #include "asterisk/manager.h"
57 #include "asterisk/ast_version.h"
58 #include "asterisk/speech.h"
59 #include "asterisk/manager.h"
60 #include "asterisk/features.h"
61 #include "asterisk/term.h"
62 #include "asterisk/xmldoc.h"
63 #include "asterisk/srv.h"
64 #include "asterisk/test.h"
66 #define AST_API_MODULE
67 #include "asterisk/agi.h"
70 <agi name="answer" language="en_US">
76 <para>Answers channel if not already in answer state. Returns <literal>-1</literal> on
77 channel failure, or <literal>0</literal> if successful.</para>
80 <ref type="agi">hangup</ref>
83 <agi name="asyncagi break" language="en_US">
89 <para>Interrupts expected flow of Async AGI commands and returns control to previous source
90 (typically, the PBX dialplan).</para>
93 <ref type="agi">hangup</ref>
96 <agi name="channel status" language="en_US">
98 Returns status of the connected channel.
101 <parameter name="channelname" />
104 <para>Returns the status of the specified <replaceable>channelname</replaceable>.
105 If no channel name is given then returns the status of the current channel.</para>
106 <para>Return values:</para>
109 <para>Channel is down and available.</para>
112 <para>Channel is down, but reserved.</para>
115 <para>Channel is off hook.</para>
118 <para>Digits (or equivalent) have been dialed.</para>
121 <para>Line is ringing.</para>
124 <para>Remote end is ringing.</para>
127 <para>Line is up.</para>
130 <para>Line is busy.</para>
135 <agi name="control stream file" language="en_US">
137 Sends audio file on channel and allows the listener to control the stream.
140 <parameter name="filename" required="true">
141 <para>The file extension must not be included in the filename.</para>
143 <parameter name="escape_digits" required="true" />
144 <parameter name="skipms" />
145 <parameter name="ffchar">
146 <para>Defaults to <literal>*</literal></para>
148 <parameter name="rewchr">
149 <para>Defaults to <literal>#</literal></para>
151 <parameter name="pausechr" />
154 <para>Send the given file, allowing playback to be controlled by the given
155 digits, if any. Use double quotes for the digits if you wish none to be
156 permitted. Returns <literal>0</literal> if playback completes without a digit
157 being pressed, or the ASCII numerical value of the digit if one was pressed,
158 or <literal>-1</literal> on error or if the channel was disconnected.</para>
161 <agi name="database del" language="en_US">
163 Removes database key/value
166 <parameter name="family" required="true" />
167 <parameter name="key" required="true" />
170 <para>Deletes an entry in the Asterisk database for a given
171 <replaceable>family</replaceable> and <replaceable>key</replaceable>.</para>
172 <para>Returns <literal>1</literal> if successful, <literal>0</literal>
176 <agi name="database deltree" language="en_US">
178 Removes database keytree/value
181 <parameter name="family" required="true" />
182 <parameter name="keytree" />
185 <para>Deletes a <replaceable>family</replaceable> or specific <replaceable>keytree</replaceable>
186 within a <replaceable>family</replaceable> in the Asterisk database.</para>
187 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
190 <agi name="database get" language="en_US">
195 <parameter name="family" required="true" />
196 <parameter name="key" required="true" />
199 <para>Retrieves an entry in the Asterisk database for a given <replaceable>family</replaceable>
200 and <replaceable>key</replaceable>.</para>
201 <para>Returns <literal>0</literal> if <replaceable>key</replaceable> is not set.
202 Returns <literal>1</literal> if <replaceable>key</replaceable> is set and returns the variable
203 in parenthesis.</para>
204 <para>Example return code: 200 result=1 (testvariable)</para>
207 <agi name="database put" language="en_US">
209 Adds/updates database value
212 <parameter name="family" required="true" />
213 <parameter name="key" required="true" />
214 <parameter name="value" required="true" />
217 <para>Adds or updates an entry in the Asterisk database for a given
218 <replaceable>family</replaceable>, <replaceable>key</replaceable>, and
219 <replaceable>value</replaceable>.</para>
220 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
223 <agi name="exec" language="en_US">
225 Executes a given Application
228 <parameter name="application" required="true" />
229 <parameter name="options" required="true" />
232 <para>Executes <replaceable>application</replaceable> with given
233 <replaceable>options</replaceable>.</para>
234 <para>Returns whatever the <replaceable>application</replaceable> returns, or
235 <literal>-2</literal> on failure to find <replaceable>application</replaceable>.</para>
238 <agi name="get data" language="en_US">
240 Prompts for DTMF on a channel
243 <parameter name="file" required="true" />
244 <parameter name="timeout" />
245 <parameter name="maxdigits" />
248 <para>Stream the given <replaceable>file</replaceable>, and receive DTMF data.</para>
249 <para>Returns the digits received from the channel at the other end.</para>
252 <agi name="get full variable" language="en_US">
254 Evaluates a channel expression
257 <parameter name="variablename" required="true" />
258 <parameter name="channel name" />
261 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set
262 or channel does not exist. Returns <literal>1</literal> if <replaceable>variablename</replaceable>
263 is set and returns the variable in parenthesis. Understands complex variable names and builtin
264 variables, unlike GET VARIABLE.</para>
265 <para>Example return code: 200 result=1 (testvariable)</para>
268 <agi name="get option" language="en_US">
270 Stream file, prompt for DTMF, with timeout.
273 <parameter name="filename" required="true" />
274 <parameter name="escape_digits" required="true" />
275 <parameter name="timeout" />
278 <para>Behaves similar to STREAM FILE but used with a timeout option.</para>
281 <ref type="agi">stream file</ref>
284 <agi name="get variable" language="en_US">
286 Gets a channel variable.
289 <parameter name="variablename" required="true" />
292 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set.
293 Returns <literal>1</literal> if <replaceable>variablename</replaceable> is set and returns
294 the variable in parentheses.</para>
295 <para>Example return code: 200 result=1 (testvariable)</para>
298 <agi name="hangup" language="en_US">
300 Hangup the current channel.
303 <parameter name="channelname" />
306 <para>Hangs up the specified channel. If no channel name is given, hangs
307 up the current channel</para>
310 <agi name="noop" language="en_US">
316 <para>Does nothing.</para>
319 <agi name="receive char" language="en_US">
321 Receives one character from channels supporting it.
324 <parameter name="timeout" required="true">
325 <para>The maximum time to wait for input in milliseconds, or <literal>0</literal>
326 for infinite. Most channels</para>
330 <para>Receives a character of text on a channel. Most channels do not support
331 the reception of text. Returns the decimal value of the character
332 if one is received, or <literal>0</literal> if the channel does not support
333 text reception. Returns <literal>-1</literal> only on error/hangup.</para>
336 <agi name="receive text" language="en_US">
338 Receives text from channels supporting it.
341 <parameter name="timeout" required="true">
342 <para>The timeout to be the maximum time to wait for input in
343 milliseconds, or <literal>0</literal> for infinite.</para>
347 <para>Receives a string of text on a channel. Most channels
348 do not support the reception of text. Returns <literal>-1</literal> for failure
349 or <literal>1</literal> for success, and the string in parenthesis.</para>
352 <agi name="record file" language="en_US">
354 Records to a given file.
357 <parameter name="filename" required="true" />
358 <parameter name="format" required="true" />
359 <parameter name="escape_digits" required="true" />
360 <parameter name="timeout" required="true" />
361 <parameter name="offset samples" />
362 <parameter name="BEEP" />
363 <parameter name="s=silence" />
366 <para>Record to a file until a given dtmf digit in the sequence is received.
367 Returns <literal>-1</literal> on hangup or error. The format will specify what kind of file
368 will be recorded. The <replaceable>timeout</replaceable> is the maximum record time in
369 milliseconds, or <literal>-1</literal> for no <replaceable>timeout</replaceable>.
370 <replaceable>offset samples</replaceable> is optional, and, if provided, will seek
371 to the offset without exceeding the end of the file. <replaceable>silence</replaceable> is
372 the number of seconds of silence allowed before the function returns despite the
373 lack of dtmf digits or reaching <replaceable>timeout</replaceable>. <replaceable>silence</replaceable>
374 value must be preceded by <literal>s=</literal> and is also optional.</para>
377 <agi name="say alpha" language="en_US">
379 Says a given character string.
382 <parameter name="number" required="true" />
383 <parameter name="escape_digits" required="true" />
386 <para>Say a given character string, returning early if any of the given DTMF digits
387 are received on the channel. Returns <literal>0</literal> if playback completes
388 without a digit being pressed, or the ASCII numerical value of the digit if one
389 was pressed or <literal>-1</literal> on error/hangup.</para>
392 <agi name="say digits" language="en_US">
394 Says a given digit string.
397 <parameter name="number" required="true" />
398 <parameter name="escape_digits" required="true" />
401 <para>Say a given digit string, returning early if any of the given DTMF digits
402 are received on the channel. Returns <literal>0</literal> if playback completes
403 without a digit being pressed, or the ASCII numerical value of the digit if one
404 was pressed or <literal>-1</literal> on error/hangup.</para>
407 <agi name="say number" language="en_US">
412 <parameter name="number" required="true" />
413 <parameter name="escape_digits" required="true" />
414 <parameter name="gender" />
417 <para>Say a given number, returning early if any of the given DTMF digits
418 are received on the channel. Returns <literal>0</literal> if playback
419 completes without a digit being pressed, or the ASCII numerical value of
420 the digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
423 <agi name="say phonetic" language="en_US">
425 Says a given character string with phonetics.
428 <parameter name="string" required="true" />
429 <parameter name="escape_digits" required="true" />
432 <para>Say a given character string with phonetics, returning early if any of the
433 given DTMF digits are received on the channel. Returns <literal>0</literal> if
434 playback completes without a digit pressed, the ASCII numerical value of the digit
435 if one was pressed, or <literal>-1</literal> on error/hangup.</para>
438 <agi name="say date" language="en_US">
443 <parameter name="date" required="true">
444 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
445 Coordinated Universal Time (UTC).</para>
447 <parameter name="escape_digits" required="true" />
450 <para>Say a given date, returning early if any of the given DTMF digits are
451 received on the channel. Returns <literal>0</literal> if playback
452 completes without a digit being pressed, or the ASCII numerical value of the
453 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
456 <agi name="say time" language="en_US">
461 <parameter name="time" required="true">
462 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
463 Coordinated Universal Time (UTC).</para>
465 <parameter name="escape_digits" required="true" />
468 <para>Say a given time, returning early if any of the given DTMF digits are
469 received on the channel. Returns <literal>0</literal> if playback completes
470 without a digit being pressed, or the ASCII numerical value of the digit if
471 one was pressed or <literal>-1</literal> on error/hangup.</para>
474 <agi name="say datetime" language="en_US">
476 Says a given time as specified by the format given.
479 <parameter name="time" required="true">
480 <para>Is number of seconds elapsed since 00:00:00
481 on January 1, 1970, Coordinated Universal Time (UTC)</para>
483 <parameter name="escape_digits" required="true" />
484 <parameter name="format">
485 <para>Is the format the time should be said in. See
486 <filename>voicemail.conf</filename> (defaults to <literal>ABdY
487 'digits/at' IMp</literal>).</para>
489 <parameter name="timezone">
490 <para>Acceptable values can be found in <filename>/usr/share/zoneinfo</filename>
491 Defaults to machine default.</para>
495 <para>Say a given time, returning early if any of the given DTMF digits are
496 received on the channel. Returns <literal>0</literal> if playback
497 completes without a digit being pressed, or the ASCII numerical value of the
498 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
501 <agi name="send image" language="en_US">
503 Sends images to channels supporting it.
506 <parameter name="image" required="true" />
509 <para>Sends the given image on a channel. Most channels do not support the
510 transmission of images. Returns <literal>0</literal> if image is sent, or if
511 the channel does not support image transmission. Returns <literal>-1</literal>
512 only on error/hangup. Image names should not include extensions.</para>
515 <agi name="send text" language="en_US">
517 Sends text to channels supporting it.
520 <parameter name="text to send" required="true">
521 <para>Text consisting of greater than one word should be placed
522 in quotes since the command only accepts a single argument.</para>
526 <para>Sends the given text on a channel. Most channels do not support the
527 transmission of text. Returns <literal>0</literal> if text is sent, or if the
528 channel does not support text transmission. Returns <literal>-1</literal> only
529 on error/hangup.</para>
532 <agi name="set autohangup" language="en_US">
534 Autohangup channel in some time.
537 <parameter name="time" required="true" />
540 <para>Cause the channel to automatically hangup at <replaceable>time</replaceable>
541 seconds in the future. Of course it can be hungup before then as well. Setting to
542 <literal>0</literal> will cause the autohangup feature to be disabled on this channel.</para>
545 <agi name="set callerid" language="en_US">
547 Sets callerid for the current channel.
550 <parameter name="number" required="true" />
553 <para>Changes the callerid of the current channel.</para>
556 <agi name="set context" language="en_US">
558 Sets channel context.
561 <parameter name="desired context" required="true" />
564 <para>Sets the context for continuation upon exiting the application.</para>
567 <agi name="set extension" language="en_US">
569 Changes channel extension.
572 <parameter name="new extension" required="true" />
575 <para>Changes the extension for continuation upon exiting the application.</para>
578 <agi name="set music" language="en_US">
580 Enable/Disable Music on hold generator
583 <parameter required="true">
586 <parameter name="on" literal="true" required="true" />
589 <parameter name="off" literal="true" required="true" />
593 <parameter name="class" required="true" />
596 <para>Enables/Disables the music on hold generator. If <replaceable>class</replaceable>
597 is not specified, then the <literal>default</literal> music on hold class will be
599 <para>Always returns <literal>0</literal>.</para>
602 <agi name="set priority" language="en_US">
604 Set channel dialplan priority.
607 <parameter name="priority" required="true" />
610 <para>Changes the priority for continuation upon exiting the application.
611 The priority must be a valid priority or label.</para>
614 <agi name="set variable" language="en_US">
616 Sets a channel variable.
619 <parameter name="variablename" required="true" />
620 <parameter name="value" required="true" />
623 <para>Sets a variable to the current channel.</para>
626 <agi name="stream file" language="en_US">
628 Sends audio file on channel.
631 <parameter name="filename" required="true">
632 <para>File name to play. The file extension must not be
633 included in the <replaceable>filename</replaceable>.</para>
635 <parameter name="escape_digits" required="true">
636 <para>Use double quotes for the digits if you wish none to be
639 <parameter name="sample offset">
640 <para>If sample offset is provided then the audio will seek to sample
641 offset before play starts.</para>
645 <para>Send the given file, allowing playback to be interrupted by the given
646 digits, if any. Returns <literal>0</literal> if playback completes without a digit
647 being pressed, or the ASCII numerical value of the digit if one was pressed,
648 or <literal>-1</literal> on error or if the channel was disconnected.</para>
651 <ref type="agi">control stream file</ref>
654 <agi name="tdd mode" language="en_US">
656 Toggles TDD mode (for the deaf).
659 <parameter name="boolean" required="true">
667 <para>Enable/Disable TDD transmission/reception on a channel. Returns <literal>1</literal> if
668 successful, or <literal>0</literal> if channel is not TDD-capable.</para>
671 <agi name="verbose" language="en_US">
673 Logs a message to the asterisk verbose log.
676 <parameter name="message" required="true" />
677 <parameter name="level" required="true" />
680 <para>Sends <replaceable>message</replaceable> to the console via verbose
681 message system. <replaceable>level</replaceable> is the verbose level (1-4).
682 Always returns <literal>1</literal></para>
685 <agi name="wait for digit" language="en_US">
687 Waits for a digit to be pressed.
690 <parameter name="timeout" required="true" />
693 <para>Waits up to <replaceable>timeout</replaceable> milliseconds for channel to
694 receive a DTMF digit. Returns <literal>-1</literal> on channel failure, <literal>0</literal>
695 if no digit is received in the timeout, or the numerical value of the ascii of the digit if
696 one is received. Use <literal>-1</literal> for the <replaceable>timeout</replaceable> value if
697 you desire the call to block indefinitely.</para>
700 <agi name="speech create" language="en_US">
702 Creates a speech object.
705 <parameter name="engine" required="true" />
708 <para>Create a speech object to be used by the other Speech AGI commands.</para>
711 <agi name="speech set" language="en_US">
713 Sets a speech engine setting.
716 <parameter name="name" required="true" />
717 <parameter name="value" required="true" />
720 <para>Set an engine-specific setting.</para>
723 <agi name="speech destroy" language="en_US">
725 Destroys a speech object.
730 <para>Destroy the speech object created by <literal>SPEECH CREATE</literal>.</para>
733 <ref type="agi">speech create</ref>
736 <agi name="speech load grammar" language="en_US">
741 <parameter name="grammar name" required="true" />
742 <parameter name="path to grammar" required="true" />
745 <para>Loads the specified grammar as the specified name.</para>
748 <agi name="speech unload grammar" language="en_US">
753 <parameter name="grammar name" required="true" />
756 <para>Unloads the specified grammar.</para>
759 <agi name="speech activate grammar" language="en_US">
764 <parameter name="grammar name" required="true" />
767 <para>Activates the specified grammar on the speech object.</para>
770 <agi name="speech deactivate grammar" language="en_US">
772 Deactivates a grammar.
775 <parameter name="grammar name" required="true" />
778 <para>Deactivates the specified grammar on the speech object.</para>
781 <agi name="speech recognize" language="en_US">
786 <parameter name="prompt" required="true" />
787 <parameter name="timeout" required="true" />
788 <parameter name="offset" />
791 <para>Plays back given <replaceable>prompt</replaceable> while listening for
792 speech and dtmf.</para>
795 <application name="AGI" language="en_US">
797 Executes an AGI compliant application.
800 <parameter name="command" required="true" />
801 <parameter name="args">
802 <argument name="arg1" required="true" />
803 <argument name="arg2" multiple="yes" />
807 <para>Executes an Asterisk Gateway Interface compliant
808 program on a channel. AGI allows Asterisk to launch external programs written
809 in any language to control a telephony channel, play audio, read DTMF digits,
810 etc. by communicating with the AGI protocol on <emphasis>stdin</emphasis> and
811 <emphasis>stdout</emphasis>. As of <literal>1.6.0</literal>, this channel will
812 not stop dialplan execution on hangup inside of this application. Dialplan
813 execution will continue normally, even upon hangup until the AGI application
814 signals a desire to stop (either by exiting or, in the case of a net script, by
815 closing the connection). A locally executed AGI script will receive SIGHUP on
816 hangup from the channel except when using DeadAGI. A fast AGI server will
817 correspondingly receive a HANGUP inline with the command dialog. Both of theses
818 signals may be disabled by setting the <variable>AGISIGHUP</variable> channel
819 variable to <literal>no</literal> before executing the AGI application.</para>
820 <para>Use the CLI command <literal>agi show commands</literal> to list available agi
822 <para>This application sets the following channel variable upon completion:</para>
824 <variable name="AGISTATUS">
825 <para>The status of the attempt to the run the AGI script
826 text string, one of:</para>
827 <value name="SUCCESS" />
828 <value name="FAILURE" />
829 <value name="NOTFOUND" />
830 <value name="HANGUP" />
835 <ref type="application">EAGI</ref>
836 <ref type="application">DeadAGI</ref>
839 <application name="EAGI" language="en_US">
841 Executes an EAGI compliant application.
844 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
845 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
848 <para>Using 'EAGI' provides enhanced AGI, with incoming audio available out of band
849 on file descriptor 3.</para>
850 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
851 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
854 <ref type="application">AGI</ref>
855 <ref type="application">DeadAGI</ref>
858 <application name="DeadAGI" language="en_US">
860 Executes AGI on a hungup channel.
863 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
864 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
867 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
868 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
871 <ref type="application">AGI</ref>
872 <ref type="application">EAGI</ref>
875 <manager name="AGI" language="en_US">
877 Add an AGI command to execute by Async AGI.
880 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
881 <parameter name="Channel" required="true">
882 <para>Channel that is currently in Async AGI.</para>
884 <parameter name="Command" required="true">
885 <para>Application to execute.</para>
887 <parameter name="CommandID">
888 <para>This will be sent back in CommandID header of AsyncAGI exec
889 event notification.</para>
893 <para>Add an AGI command to the execute queue of the channel in Async AGI.</para>
899 #define MAX_CMD_LEN 80
900 #define AGI_NANDFS_RETRY 3
901 #define AGI_BUF_LEN 2048
902 #define SRV_PREFIX "_agi._tcp."
904 static char *app = "AGI";
906 static char *eapp = "EAGI";
908 static char *deadapp = "DeadAGI";
910 static int agidebug = 0;
912 #define TONE_BLOCK_SIZE 200
914 /* Max time to connect to an AGI remote host */
915 #define MAX_AGI_CONNECT 2000
917 #define AGI_PORT 4573
919 /*! Special return code for "asyncagi break" command. */
920 #define ASYNC_AGI_BREAK 3
923 AGI_RESULT_FAILURE = -1,
925 AGI_RESULT_SUCCESS_FAST,
926 AGI_RESULT_SUCCESS_ASYNC,
931 static agi_command *find_command(const char * const cmds[], int exact);
933 AST_THREADSTORAGE(agi_buf);
934 #define AGI_BUF_INITSIZE 256
936 int AST_OPTIONAL_API_NAME(ast_agi_send)(int fd, struct ast_channel *chan, char *fmt, ...)
942 if (!(buf = ast_str_thread_get(&agi_buf, AGI_BUF_INITSIZE)))
946 res = ast_str_set_va(&buf, 0, fmt, ap);
950 ast_log(LOG_ERROR, "Out of memory\n");
956 ast_verbose("<%s>AGI Tx >> %s", chan->name, ast_str_buffer(buf));
958 ast_verbose("AGI Tx >> %s", ast_str_buffer(buf));
962 return ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
965 /* linked list of AGI commands ready to be executed by Async AGI */
969 AST_LIST_ENTRY(agi_cmd) entry;
972 static void free_agi_cmd(struct agi_cmd *cmd)
974 ast_free(cmd->cmd_buffer);
975 ast_free(cmd->cmd_id);
979 /* AGI datastore destructor */
980 static void agi_destroy_commands_cb(void *data)
983 AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
984 AST_LIST_LOCK(chan_cmds);
985 while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
988 AST_LIST_UNLOCK(chan_cmds);
989 AST_LIST_HEAD_DESTROY(chan_cmds);
993 /* channel datastore to keep the queue of AGI commands in the channel */
994 static const struct ast_datastore_info agi_commands_datastore_info = {
996 .destroy = agi_destroy_commands_cb
999 static struct agi_cmd *get_agi_cmd(struct ast_channel *chan)
1001 struct ast_datastore *store;
1002 struct agi_cmd *cmd;
1003 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1005 ast_channel_lock(chan);
1006 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1007 ast_channel_unlock(chan);
1009 ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
1013 agi_commands = store->data;
1014 AST_LIST_LOCK(agi_commands);
1015 cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
1016 AST_LIST_UNLOCK(agi_commands);
1020 /* channel is locked when calling this one either from the CLI or manager thread */
1021 static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
1023 struct ast_datastore *store;
1024 struct agi_cmd *cmd;
1025 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1027 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1029 ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", chan->name);
1032 agi_commands = store->data;
1033 cmd = ast_calloc(1, sizeof(*cmd));
1037 cmd->cmd_buffer = ast_strdup(cmd_buff);
1038 if (!cmd->cmd_buffer) {
1042 cmd->cmd_id = ast_strdup(cmd_id);
1044 ast_free(cmd->cmd_buffer);
1048 AST_LIST_LOCK(agi_commands);
1049 AST_LIST_INSERT_TAIL(agi_commands, cmd, entry);
1050 AST_LIST_UNLOCK(agi_commands);
1054 static int add_to_agi(struct ast_channel *chan)
1056 struct ast_datastore *datastore;
1057 AST_LIST_HEAD(, agi_cmd) *agi_cmds_list;
1059 /* check if already on AGI */
1060 ast_channel_lock(chan);
1061 datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1062 ast_channel_unlock(chan);
1064 /* we already have an AGI datastore, let's just
1069 /* the channel has never been on Async AGI,
1070 let's allocate it's datastore */
1071 datastore = ast_datastore_alloc(&agi_commands_datastore_info, "AGI");
1075 agi_cmds_list = ast_calloc(1, sizeof(*agi_cmds_list));
1076 if (!agi_cmds_list) {
1077 ast_log(LOG_ERROR, "Unable to allocate Async AGI commands list.\n");
1078 ast_datastore_free(datastore);
1081 datastore->data = agi_cmds_list;
1082 AST_LIST_HEAD_INIT(agi_cmds_list);
1083 ast_channel_lock(chan);
1084 ast_channel_datastore_add(chan, datastore);
1085 ast_channel_unlock(chan);
1090 * \brief CLI command to add applications to execute in Async AGI
1095 * \retval CLI_SUCCESS on success
1096 * \retval NULL when init or tab completion is used
1098 static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1100 struct ast_channel *chan;
1103 e->command = "agi exec";
1104 e->usage = "Usage: agi exec <channel name> <app and arguments> [id]\n"
1105 " Add AGI command to the execute queue of the specified channel in Async AGI\n";
1109 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
1114 return CLI_SHOWUSAGE;
1117 if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
1118 ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
1122 ast_channel_lock(chan);
1124 if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
1125 ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", chan->name);
1126 ast_channel_unlock(chan);
1127 chan = ast_channel_unref(chan);
1131 ast_debug(1, "Added AGI command to channel %s queue\n", chan->name);
1133 ast_channel_unlock(chan);
1134 chan = ast_channel_unref(chan);
1140 * \brief Add a new command to execute by the Async AGI application
1144 * It will append the application to the specified channel's queue
1145 * if the channel is not inside Async AGI application it will return an error
1146 * \retval 0 on success or incorrect use
1147 * \retval 1 on failure to add the command ( most likely because the channel
1148 * is not in Async AGI loop )
1150 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
1152 const char *channel = astman_get_header(m, "Channel");
1153 const char *cmdbuff = astman_get_header(m, "Command");
1154 const char *cmdid = astman_get_header(m, "CommandID");
1155 struct ast_channel *chan;
1158 if (ast_strlen_zero(channel) || ast_strlen_zero(cmdbuff)) {
1159 astman_send_error(s, m, "Both, Channel and Command are *required*");
1163 if (!(chan = ast_channel_get_by_name(channel))) {
1164 snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
1165 astman_send_error(s, m, buf);
1169 ast_channel_lock(chan);
1171 if (add_agi_cmd(chan, cmdbuff, cmdid)) {
1172 snprintf(buf, sizeof(buf), "Failed to add AGI command to channel %s queue", chan->name);
1173 astman_send_error(s, m, buf);
1174 ast_channel_unlock(chan);
1175 chan = ast_channel_unref(chan);
1179 ast_channel_unlock(chan);
1180 chan = ast_channel_unref(chan);
1182 astman_send_ack(s, m, "Added AGI command to queue");
1187 static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
1188 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
1192 * \brief Read and handle a channel frame for Async AGI.
1194 * \param chan Channel to read a frame from.
1196 * \retval AGI_RESULT_SUCCESS on success.
1197 * \retval AGI_RESULT_HANGUP on hangup.
1198 * \retval AGI_RESULT_FAILURE on error.
1200 static enum agi_result async_agi_read_frame(struct ast_channel *chan)
1202 struct ast_frame *f;
1206 ast_debug(3, "No frame read on channel %s, going out ...\n", chan->name);
1207 return AGI_RESULT_HANGUP;
1209 if (f->frametype == AST_FRAME_CONTROL) {
1211 * Is there any other frame we should care about besides
1212 * AST_CONTROL_HANGUP?
1214 switch (f->subclass.integer) {
1215 case AST_CONTROL_HANGUP:
1216 ast_debug(3, "Got HANGUP frame on channel %s, going out ...\n", chan->name);
1218 return AGI_RESULT_HANGUP;
1225 return AGI_RESULT_SUCCESS;
1228 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
1230 /* This buffer sizes might cause truncation if the AGI command writes more data
1231 than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
1232 that writes a response larger than 1024 bytes?, I don't think so, most of
1233 them are just result=blah stuff. However probably if GET VARIABLE is called
1234 and the variable has large amount of data, that could be a problem. We could
1235 make this buffers dynamic, but let's leave that as a second step.
1237 AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
1238 number. Some characters of AGI buf will be url encoded to be sent to manager
1239 clients. An URL encoded character will take 3 bytes, but again, to cause
1240 truncation more than about 70% of the AGI buffer should be URL encoded for
1241 that to happen. Not likely at all.
1243 On the other hand. I wonder if read() could eventually return less data than
1244 the amount already available in the pipe? If so, how to deal with that?
1245 So far, my tests on Linux have not had any problems.
1247 #define AGI_BUF_SIZE 1024
1248 #define AMI_BUF_SIZE 2048
1249 enum agi_result cmd_status;
1250 struct agi_cmd *cmd;
1255 char agi_buffer[AGI_BUF_SIZE + 1];
1256 char ami_buffer[AMI_BUF_SIZE];
1257 enum agi_result returnstatus = AGI_RESULT_SUCCESS;
1261 ast_log(LOG_WARNING, "Async AGI does not support Enhanced AGI yet\n");
1262 return AGI_RESULT_FAILURE;
1265 /* add AsyncAGI datastore to the channel */
1266 if (add_to_agi(chan)) {
1267 ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", chan->name);
1268 return AGI_RESULT_FAILURE;
1271 /* this pipe allows us to create a "fake" AGI struct to use
1275 ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
1277 * Intentionally do not remove the datastore added with
1278 * add_to_agi() the from channel. It will be removed when the
1279 * channel is hung up anyway.
1281 return AGI_RESULT_FAILURE;
1284 /* handlers will get the pipe write fd and we read the AGI responses
1285 from the pipe read fd */
1286 async_agi.fd = fds[1];
1287 async_agi.ctrl = fds[1];
1288 async_agi.audio = -1; /* no audio support */
1290 async_agi.speech = NULL;
1292 /* notify possible manager users of a new channel ready to
1294 setup_env(chan, "async", fds[1], 0, 0, NULL);
1295 /* read the environment */
1296 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1298 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
1300 returnstatus = AGI_RESULT_FAILURE;
1301 goto async_agi_abort;
1303 agi_buffer[res] = '\0';
1304 /* encode it and send it thru the manager so whoever is going to take
1305 care of AGI commands on this channel can decide which AGI commands
1306 to execute based on the setup info */
1307 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1308 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1309 "SubEvent: Start\r\n"
1311 "Env: %s\r\n", chan->name, ami_buffer);
1312 hungup = ast_check_hangup(chan);
1315 * Process as many commands as we can. Commands are added via
1316 * the manager or the cli threads.
1318 while (!hungup && (cmd = get_agi_cmd(chan))) {
1319 /* OK, we have a command, let's call the command handler. */
1320 cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
1323 * The command handler must have written to our fake AGI struct
1324 * fd (the pipe), let's read the response.
1326 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1328 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
1331 returnstatus = AGI_RESULT_FAILURE;
1332 goto async_agi_done;
1335 * We have a response, let's send the response thru the manager.
1336 * Include the CommandID if it was specified when the command
1339 agi_buffer[res] = '\0';
1340 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1341 if (ast_strlen_zero(cmd->cmd_id)) {
1342 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1343 "SubEvent: Exec\r\n"
1345 "Result: %s\r\n", chan->name, ami_buffer);
1347 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1348 "SubEvent: Exec\r\n"
1351 "Result: %s\r\n", chan->name, cmd->cmd_id, ami_buffer);
1356 * Check the command status to determine if we should continue
1357 * executing more commands.
1359 hungup = ast_check_hangup(chan);
1360 switch (cmd_status) {
1361 case AGI_RESULT_FAILURE:
1363 /* The failure was not because of a hangup. */
1364 returnstatus = AGI_RESULT_FAILURE;
1365 goto async_agi_done;
1368 case AGI_RESULT_SUCCESS_ASYNC:
1369 /* Only the "asyncagi break" command does this. */
1370 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1371 goto async_agi_done;
1378 /* Wait a bit for a frame to read or to poll for a new command. */
1379 res = ast_waitfor(chan, timeout);
1381 ast_debug(1, "ast_waitfor returned <= 0 on chan %s\n", chan->name);
1382 returnstatus = AGI_RESULT_FAILURE;
1387 * Read the channel control queue until it is dry so we can
1394 cmd_status = async_agi_read_frame(chan);
1395 if (cmd_status != AGI_RESULT_SUCCESS) {
1396 returnstatus = cmd_status;
1397 goto async_agi_done;
1399 hungup = ast_check_hangup(chan);
1402 hungup = ast_check_hangup(chan);
1407 if (async_agi.speech) {
1408 ast_speech_destroy(async_agi.speech);
1410 /* notify manager users this channel cannot be
1411 controlled anymore by Async AGI */
1412 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1414 "Channel: %s\r\n", chan->name);
1417 /* close the pipe */
1422 * Intentionally do not remove the datastore added with
1423 * add_to_agi() the from channel. There might be commands still
1424 * in the queue or in-flight to us and AsyncAGI may get called
1425 * again. The datastore destructor will be called on channel
1426 * destruction anyway.
1429 if (returnstatus == AGI_RESULT_SUCCESS) {
1430 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1432 return returnstatus;
1438 /* launch_netscript: The fastagi handler.
1439 FastAGI defaults to port 4573 */
1440 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
1442 int s, flags, res, port = AGI_PORT;
1443 struct pollfd pfds[1];
1444 char *host, *c, *script;
1445 struct sockaddr_in addr_in;
1447 struct ast_hostent ahp;
1449 /* agiurl is "agi://host.domain[:port][/script/name]" */
1450 host = ast_strdupa(agiurl + 6); /* Remove agi:// */
1451 /* Strip off any script name */
1452 if ((script = strchr(host, '/'))) {
1458 if ((c = strchr(host, ':'))) {
1462 if (!(hp = ast_gethostbyname(host, &ahp))) {
1463 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
1464 return AGI_RESULT_FAILURE;
1466 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1467 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1468 return AGI_RESULT_FAILURE;
1470 if ((flags = fcntl(s, F_GETFL)) < 0) {
1471 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno));
1473 return AGI_RESULT_FAILURE;
1475 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
1476 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno));
1478 return AGI_RESULT_FAILURE;
1480 memset(&addr_in, 0, sizeof(addr_in));
1481 addr_in.sin_family = AF_INET;
1482 addr_in.sin_port = htons(port);
1483 memcpy(&addr_in.sin_addr, hp->h_addr, sizeof(addr_in.sin_addr));
1484 if (connect(s, (struct sockaddr *)&addr_in, sizeof(addr_in)) && (errno != EINPROGRESS)) {
1485 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno));
1487 return AGI_RESULT_FAILURE;
1491 pfds[0].events = POLLOUT;
1492 while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
1493 if (errno != EINTR) {
1495 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
1496 agiurl, MAX_AGI_CONNECT);
1498 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1500 return AGI_RESULT_FAILURE;
1504 if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
1505 if (errno != EINTR) {
1506 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1508 return AGI_RESULT_FAILURE;
1512 /* If we have a script parameter, relay it to the fastagi server */
1513 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
1514 if (!ast_strlen_zero(script))
1515 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
1517 ast_debug(4, "Wow, connected!\n");
1520 return AGI_RESULT_SUCCESS_FAST;
1525 * \brief The HA fastagi handler.
1526 * \param agiurl The request URL as passed to Agi() in the dial plan
1527 * \param argv The parameters after the URL passed to Agi() in the dial plan
1528 * \param fds Input/output file descriptors
1530 * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
1531 * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
1532 * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
1533 * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
1536 * This function parses the URI, resolves the SRV service name, forms new URIs
1537 * with the results of the DNS lookup, and then calls launch_netscript on the
1538 * new URIs until one succeeds.
1540 * \return the result of the AGI operation.
1542 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
1544 char *host, *script;
1545 enum agi_result result;
1546 struct srv_context *context = NULL;
1549 char resolved_uri[1024];
1550 const char *srvhost;
1551 unsigned short srvport;
1553 /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
1554 if (!(host = ast_strdupa(agiurl + 7))) { /* Remove hagi:// */
1555 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
1556 return AGI_RESULT_FAILURE;
1559 /* Strip off any script name */
1560 if ((script = strchr(host, '/'))) {
1566 if (strchr(host, ':')) {
1567 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
1568 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
1571 snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
1573 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
1574 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
1575 result = launch_netscript(resolved_uri, argv, fds);
1576 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
1577 ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
1579 /* The script launched so we must cleanup the context. */
1580 ast_srv_cleanup(&context);
1585 * The DNS SRV lookup failed or we ran out of servers to check.
1586 * ast_srv_lookup() has already cleaned up the context for us.
1589 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
1592 return AGI_RESULT_FAILURE;
1595 static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
1598 int pid, toast[2], fromast[2], audio[2], res;
1601 if (!strncasecmp(script, "agi://", 6)) {
1602 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1604 if (!strncasecmp(script, "hagi://", 7)) {
1605 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1607 if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
1608 return launch_asyncagi(chan, argv, efd);
1611 if (script[0] != '/') {
1612 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
1616 /* Before even trying let's see if the file actually exists */
1617 if (stat(script, &st)) {
1618 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
1619 return AGI_RESULT_NOTFOUND;
1623 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
1624 return AGI_RESULT_FAILURE;
1626 if (pipe(fromast)) {
1627 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
1630 return AGI_RESULT_FAILURE;
1634 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
1639 return AGI_RESULT_FAILURE;
1641 res = fcntl(audio[1], F_GETFL);
1643 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
1645 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
1652 return AGI_RESULT_FAILURE;
1656 if ((pid = ast_safe_fork(1)) < 0) {
1657 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
1658 return AGI_RESULT_FAILURE;
1661 /* Pass paths to AGI via environmental variables */
1662 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
1663 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
1664 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
1665 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
1666 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
1667 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
1668 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
1669 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
1670 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
1671 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
1672 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
1674 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
1675 ast_set_priority(0);
1677 /* Redirect stdin and out, provide enhanced audio channel if desired */
1678 dup2(fromast[0], STDIN_FILENO);
1679 dup2(toast[1], STDOUT_FILENO);
1681 dup2(audio[0], STDERR_FILENO + 1);
1683 close(STDERR_FILENO + 1);
1685 /* Close everything but stdin/out/error */
1686 ast_close_fds_above_n(STDERR_FILENO + 1);
1688 /* Execute script */
1689 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
1690 execv(script, argv);
1691 /* Can't use ast_log since FD's are closed */
1692 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
1693 /* Special case to set status of AGI to failure */
1694 fprintf(stdout, "failure\n");
1698 ast_verb(3, "Launched AGI Script %s\n", script);
1700 fds[1] = fromast[1];
1703 /* close what we're not using in the parent */
1711 return AGI_RESULT_SUCCESS;
1714 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
1718 /* Print initial environment, with agi_request always being the first
1720 ast_agi_send(fd, chan, "agi_request: %s\n", request);
1721 ast_agi_send(fd, chan, "agi_channel: %s\n", chan->name);
1722 ast_agi_send(fd, chan, "agi_language: %s\n", chan->language);
1723 ast_agi_send(fd, chan, "agi_type: %s\n", chan->tech->type);
1724 ast_agi_send(fd, chan, "agi_uniqueid: %s\n", chan->uniqueid);
1725 ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
1728 ast_agi_send(fd, chan, "agi_callerid: %s\n",
1729 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "unknown"));
1730 ast_agi_send(fd, chan, "agi_calleridname: %s\n",
1731 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "unknown"));
1732 ast_agi_send(fd, chan, "agi_callingpres: %d\n",
1733 ast_party_id_presentation(&chan->caller.id));
1734 ast_agi_send(fd, chan, "agi_callingani2: %d\n", chan->caller.ani2);
1735 ast_agi_send(fd, chan, "agi_callington: %d\n", chan->caller.id.number.plan);
1736 ast_agi_send(fd, chan, "agi_callingtns: %d\n", chan->dialed.transit_network_select);
1737 ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(chan->dialed.number.str, "unknown"));
1738 ast_agi_send(fd, chan, "agi_rdnis: %s\n",
1739 S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "unknown"));
1741 /* Context information */
1742 ast_agi_send(fd, chan, "agi_context: %s\n", chan->context);
1743 ast_agi_send(fd, chan, "agi_extension: %s\n", chan->exten);
1744 ast_agi_send(fd, chan, "agi_priority: %d\n", chan->priority);
1745 ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
1747 /* User information */
1748 ast_agi_send(fd, chan, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
1749 ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
1751 /* Send any parameters to the fastagi server that have been passed via the agi application */
1752 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
1753 for(count = 1; count < argc; count++)
1754 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
1756 /* End with empty return */
1757 ast_agi_send(fd, chan, "\n");
1760 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1764 /* Answer the channel */
1765 if (chan->_state != AST_STATE_UP)
1766 res = ast_answer(chan);
1768 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1769 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1772 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1774 ast_agi_send(agi->fd, chan, "200 result=0\n");
1775 return ASYNC_AGI_BREAK;
1778 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1783 return RESULT_SHOWUSAGE;
1784 if (sscanf(argv[3], "%30d", &to) != 1)
1785 return RESULT_SHOWUSAGE;
1786 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
1787 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1788 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1791 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1796 return RESULT_SHOWUSAGE;
1798 /* At the moment, the parser (perhaps broken) returns with
1799 the last argument PLUS the newline at the end of the input
1800 buffer. This probably needs to be fixed, but I wont do that
1801 because other stuff may break as a result. The right way
1802 would probably be to strip off the trailing newline before
1803 parsing, then here, add a newline at the end of the string
1804 before sending it to ast_sendtext --DUDE */
1805 res = ast_sendtext(chan, argv[2]);
1806 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1807 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1810 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1815 return RESULT_SHOWUSAGE;
1817 res = ast_recvchar(chan,atoi(argv[2]));
1819 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
1820 return RESULT_SUCCESS;
1823 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1824 return RESULT_SUCCESS;
1826 ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
1827 return RESULT_FAILURE;
1830 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1835 return RESULT_SHOWUSAGE;
1837 buf = ast_recvtext(chan, atoi(argv[2]));
1839 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
1842 ast_agi_send(agi->fd, chan, "200 result=-1\n");
1844 return RESULT_SUCCESS;
1847 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1852 return RESULT_SHOWUSAGE;
1854 if (!strncasecmp(argv[2],"on",2)) {
1859 if (!strncasecmp(argv[2],"mate",4)) {
1862 if (!strncasecmp(argv[2],"tdd",3)) {
1865 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
1867 /* Set channel option failed */
1868 ast_agi_send(agi->fd, chan, "200 result=0\n");
1870 ast_agi_send(agi->fd, chan, "200 result=1\n");
1872 return RESULT_SUCCESS;
1875 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1880 return RESULT_SHOWUSAGE;
1883 res = ast_send_image(chan, argv[2]);
1884 if (!ast_check_hangup(chan)) {
1887 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1888 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1891 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1893 int res = 0, skipms = 3000;
1894 const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL; /* Default values */
1896 if (argc < 5 || argc > 9) {
1897 return RESULT_SHOWUSAGE;
1900 if (!ast_strlen_zero(argv[4])) {
1904 if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
1905 return RESULT_SHOWUSAGE;
1908 if (argc > 6 && !ast_strlen_zero(argv[6])) {
1912 if (argc > 7 && !ast_strlen_zero(argv[7])) {
1916 if (argc > 8 && !ast_strlen_zero(argv[8])) {
1920 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
1922 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1924 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1927 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1930 struct ast_filestream *fs, *vfs;
1931 long sample_offset = 0, max_length;
1932 const char *edigits = "";
1934 if (argc < 4 || argc > 5)
1935 return RESULT_SHOWUSAGE;
1940 if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1))
1941 return RESULT_SHOWUSAGE;
1943 if (!(fs = ast_openstream(chan, argv[2], chan->language))) {
1944 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
1945 return RESULT_SUCCESS;
1948 if ((vfs = ast_openvstream(chan, argv[2], chan->language)))
1949 ast_debug(1, "Ooh, found a video stream, too\n");
1951 ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
1953 ast_seekstream(fs, 0, SEEK_END);
1954 max_length = ast_tellstream(fs);
1955 ast_seekstream(fs, sample_offset, SEEK_SET);
1956 res = ast_applystream(chan, fs);
1958 ast_applystream(chan, vfs);
1961 ast_playstream(vfs);
1963 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
1964 /* this is to check for if ast_waitstream closed the stream, we probably are at
1965 * the end of the stream, return that amount, else check for the amount */
1966 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
1967 ast_stopstream(chan);
1969 /* Stop this command, don't print a result line, as there is a new command */
1970 return RESULT_SUCCESS;
1972 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
1973 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1976 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
1977 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1980 struct ast_filestream *fs, *vfs;
1981 long sample_offset = 0, max_length;
1983 const char *edigits = "";
1985 if ( argc < 4 || argc > 5 )
1986 return RESULT_SHOWUSAGE;
1992 timeout = atoi(argv[4]);
1993 else if (chan->pbx->dtimeoutms) {
1994 /* by default dtimeout is set to 5sec */
1995 timeout = chan->pbx->dtimeoutms; /* in msec */
1998 if (!(fs = ast_openstream(chan, argv[2], chan->language))) {
1999 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2000 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2001 return RESULT_SUCCESS;
2004 if ((vfs = ast_openvstream(chan, argv[2], chan->language)))
2005 ast_debug(1, "Ooh, found a video stream, too\n");
2007 ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2009 ast_seekstream(fs, 0, SEEK_END);
2010 max_length = ast_tellstream(fs);
2011 ast_seekstream(fs, sample_offset, SEEK_SET);
2012 res = ast_applystream(chan, fs);
2014 ast_applystream(chan, vfs);
2017 ast_playstream(vfs);
2019 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2020 /* this is to check for if ast_waitstream closed the stream, we probably are at
2021 * the end of the stream, return that amount, else check for the amount */
2022 sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
2023 ast_stopstream(chan);
2025 /* Stop this command, don't print a result line, as there is a new command */
2026 return RESULT_SUCCESS;
2029 /* If the user didnt press a key, wait for digitTimeout*/
2031 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2032 /* Make sure the new result is in the escape digits of the GET OPTION */
2033 if ( !strchr(edigits,res) )
2037 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2038 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2044 /*! \brief Say number in various language syntaxes */
2045 /* While waiting, we're sending a NULL. */
2046 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2050 if (argc < 4 || argc > 5)
2051 return RESULT_SHOWUSAGE;
2052 if (sscanf(argv[2], "%30d", &num) != 1)
2053 return RESULT_SHOWUSAGE;
2054 res = ast_say_number_full(chan, num, argv[3], chan->language, argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2056 return RESULT_SUCCESS;
2057 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2058 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2061 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2066 return RESULT_SHOWUSAGE;
2067 if (sscanf(argv[2], "%30d", &num) != 1)
2068 return RESULT_SHOWUSAGE;
2070 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
2071 if (res == 1) /* New command */
2072 return RESULT_SUCCESS;
2073 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2074 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2077 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2082 return RESULT_SHOWUSAGE;
2084 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
2085 if (res == 1) /* New command */
2086 return RESULT_SUCCESS;
2087 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2088 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2091 static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2096 return RESULT_SHOWUSAGE;
2097 if (sscanf(argv[2], "%30d", &num) != 1)
2098 return RESULT_SHOWUSAGE;
2099 res = ast_say_date(chan, num, argv[3], chan->language);
2101 return RESULT_SUCCESS;
2102 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2103 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2106 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2111 return RESULT_SHOWUSAGE;
2112 if (sscanf(argv[2], "%30d", &num) != 1)
2113 return RESULT_SHOWUSAGE;
2114 res = ast_say_time(chan, num, argv[3], chan->language);
2116 return RESULT_SUCCESS;
2117 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2118 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2121 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2125 const char *format, *zone = NULL;
2128 return RESULT_SHOWUSAGE;
2133 /* XXX this doesn't belong here, but in the 'say' module */
2134 if (!strcasecmp(chan->language, "de")) {
2135 format = "A dBY HMS";
2137 format = "ABdY 'digits/at' IMp";
2141 if (argc > 5 && !ast_strlen_zero(argv[5]))
2144 if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2145 return RESULT_SHOWUSAGE;
2147 res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone);
2149 return RESULT_SUCCESS;
2151 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2152 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2155 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2160 return RESULT_SHOWUSAGE;
2162 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
2163 if (res == 1) /* New command */
2164 return RESULT_SUCCESS;
2165 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2166 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2169 static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2171 int res, max, timeout;
2175 return RESULT_SHOWUSAGE;
2177 timeout = atoi(argv[3]);
2181 max = atoi(argv[4]);
2184 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2185 if (res == 2) /* New command */
2186 return RESULT_SUCCESS;
2188 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2190 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2192 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2193 return RESULT_SUCCESS;
2196 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2200 return RESULT_SHOWUSAGE;
2201 ast_copy_string(chan->context, argv[2], sizeof(chan->context));
2202 ast_agi_send(agi->fd, chan, "200 result=0\n");
2203 return RESULT_SUCCESS;
2206 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2209 return RESULT_SHOWUSAGE;
2210 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
2211 ast_agi_send(agi->fd, chan, "200 result=0\n");
2212 return RESULT_SUCCESS;
2215 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2220 return RESULT_SHOWUSAGE;
2222 if (sscanf(argv[2], "%30d", &pri) != 1) {
2223 pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2],
2224 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
2226 return RESULT_SHOWUSAGE;
2229 ast_explicit_goto(chan, NULL, NULL, pri);
2230 ast_agi_send(agi->fd, chan, "200 result=0\n");
2231 return RESULT_SUCCESS;
2234 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2236 struct ast_filestream *fs;
2237 struct ast_frame *f;
2238 struct timeval start;
2239 long sample_offset = 0;
2243 struct ast_dsp *sildet=NULL; /* silence detector dsp */
2244 int totalsilence = 0;
2246 int silence = 0; /* amount of silence to allow */
2247 int gotsilence = 0; /* did we timeout for silence? */
2248 char *silencestr = NULL;
2249 struct ast_format rfmt;
2250 ast_format_clear(&rfmt);
2252 /* XXX EAGI FIXME XXX */
2255 return RESULT_SHOWUSAGE;
2256 if (sscanf(argv[5], "%30d", &ms) != 1)
2257 return RESULT_SHOWUSAGE;
2260 silencestr = strchr(argv[6],'s');
2261 if ((argc > 7) && (!silencestr))
2262 silencestr = strchr(argv[7],'s');
2263 if ((argc > 8) && (!silencestr))
2264 silencestr = strchr(argv[8],'s');
2267 if (strlen(silencestr) > 2) {
2268 if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2272 silence = atoi(silencestr);
2280 ast_format_copy(&rfmt, &chan->readformat);
2281 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2283 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2284 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2285 return RESULT_FAILURE;
2287 sildet = ast_dsp_new();
2289 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2290 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2291 return RESULT_FAILURE;
2293 ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
2296 /* backward compatibility, if no offset given, arg[6] would have been
2297 * caught below and taken to be a beep, else if it is a digit then it is a
2299 if ((argc >6) && (sscanf(argv[6], "%30ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
2300 res = ast_streamfile(chan, "beep", chan->language);
2302 if ((argc > 7) && (!strchr(argv[7], '=')))
2303 res = ast_streamfile(chan, "beep", chan->language);
2306 res = ast_waitstream(chan, argv[4]);
2308 ast_agi_send(agi->fd, chan, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
2310 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE);
2313 ast_agi_send(agi->fd, chan, "200 result=%d (writefile)\n", res);
2315 ast_dsp_free(sildet);
2316 return RESULT_FAILURE;
2319 /* Request a video update */
2320 ast_indicate(chan, AST_CONTROL_VIDUPDATE);
2323 ast_applystream(chan,fs);
2324 /* really should have checks */
2325 ast_seekstream(fs, sample_offset, SEEK_SET);
2326 ast_truncstream(fs);
2328 start = ast_tvnow();
2329 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
2330 res = ast_waitfor(chan, ms - ast_tvdiff_ms(ast_tvnow(), start));
2332 ast_closestream(fs);
2333 ast_agi_send(agi->fd, chan, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
2335 ast_dsp_free(sildet);
2336 return RESULT_FAILURE;
2340 ast_agi_send(agi->fd, chan, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
2341 ast_closestream(fs);
2343 ast_dsp_free(sildet);
2344 return RESULT_FAILURE;
2346 switch(f->frametype) {
2347 case AST_FRAME_DTMF:
2348 if (strchr(argv[4], f->subclass.integer)) {
2349 /* This is an interrupting chracter, so rewind to chop off any small
2350 amount of DTMF that may have been recorded
2352 ast_stream_rewind(fs, 200);
2353 ast_truncstream(fs);
2354 sample_offset = ast_tellstream(fs);
2355 ast_agi_send(agi->fd, chan, "200 result=%d (dtmf) endpos=%ld\n", f->subclass.integer, sample_offset);
2356 ast_closestream(fs);
2359 ast_dsp_free(sildet);
2360 return RESULT_SUCCESS;
2363 case AST_FRAME_VOICE:
2364 ast_writestream(fs, f);
2365 /* this is a safe place to check progress since we know that fs
2366 * is valid after a write, and it will then have our current
2368 sample_offset = ast_tellstream(fs);
2371 ast_dsp_silence(sildet, f, &dspsilence);
2373 totalsilence = dspsilence;
2377 if (totalsilence > silence) {
2378 /* Ended happily with silence */
2384 case AST_FRAME_VIDEO:
2385 ast_writestream(fs, f);
2387 /* Ignore all other frames */
2396 ast_stream_rewind(fs, silence-1000);
2397 ast_truncstream(fs);
2398 sample_offset = ast_tellstream(fs);
2400 ast_agi_send(agi->fd, chan, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
2401 ast_closestream(fs);
2405 res = ast_set_read_format(chan, &rfmt);
2407 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
2408 ast_dsp_free(sildet);
2411 return RESULT_SUCCESS;
2414 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2417 struct timeval whentohangup = { 0, 0 };
2420 return RESULT_SHOWUSAGE;
2421 if (sscanf(argv[2], "%30lf", &timeout) != 1)
2422 return RESULT_SHOWUSAGE;
2426 whentohangup.tv_sec = timeout;
2427 whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
2429 ast_channel_setwhentohangup_tv(chan, whentohangup);
2430 ast_agi_send(agi->fd, chan, "200 result=0\n");
2431 return RESULT_SUCCESS;
2434 static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2436 struct ast_channel *c;
2439 /* no argument: hangup the current channel */
2440 ast_set_hangupsource(chan, "dialplan/agi", 0);
2441 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
2442 ast_agi_send(agi->fd, chan, "200 result=1\n");
2443 return RESULT_SUCCESS;
2444 } else if (argc == 2) {
2445 /* one argument: look for info on the specified channel */
2446 if ((c = ast_channel_get_by_name(argv[1]))) {
2447 /* we have a matching channel */
2448 ast_set_hangupsource(c, "dialplan/agi", 0);
2449 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
2450 c = ast_channel_unref(c);
2451 ast_agi_send(agi->fd, chan, "200 result=1\n");
2452 return RESULT_SUCCESS;
2454 /* if we get this far no channel name matched the argument given */
2455 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2456 return RESULT_SUCCESS;
2458 return RESULT_SHOWUSAGE;
2462 static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2464 int res, workaround;
2465 struct ast_app *app_to_exec;
2468 return RESULT_SHOWUSAGE;
2470 ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
2472 if ((app_to_exec = pbx_findapp(argv[1]))) {
2473 if(!strcasecmp(argv[1], PARK_APP_NAME)) {
2474 ast_masq_park_call(chan, NULL, 0, NULL);
2476 if (!(workaround = ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS))) {
2477 ast_set_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
2479 if (ast_compat_res_agi && argc >= 3 && !ast_strlen_zero(argv[2])) {
2480 char *compat = alloca(strlen(argv[2]) * 2 + 1), *cptr;
2482 for (cptr = compat, vptr = argv[2]; *vptr; vptr++) {
2486 } else if (*vptr == '|') {
2493 res = pbx_exec(chan, app_to_exec, compat);
2495 res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
2498 ast_clear_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
2501 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
2504 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2506 /* Even though this is wrong, users are depending upon this result. */
2510 static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2513 char *l = NULL, *n = NULL;
2516 ast_copy_string(tmp, argv[2], sizeof(tmp));
2517 ast_callerid_parse(tmp, &n, &l);
2519 ast_shrink_phone_number(l);
2524 ast_set_callerid(chan, l, n, NULL);
2527 ast_agi_send(agi->fd, chan, "200 result=1\n");
2528 return RESULT_SUCCESS;
2531 static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2533 struct ast_channel *c;
2535 /* no argument: supply info on the current channel */
2536 ast_agi_send(agi->fd, chan, "200 result=%d\n", chan->_state);
2537 return RESULT_SUCCESS;
2538 } else if (argc == 3) {
2539 /* one argument: look for info on the specified channel */
2540 if ((c = ast_channel_get_by_name(argv[2]))) {
2541 ast_agi_send(agi->fd, chan, "200 result=%d\n", c->_state);
2542 c = ast_channel_unref(c);
2543 return RESULT_SUCCESS;
2545 /* if we get this far no channel name matched the argument given */
2546 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2547 return RESULT_SUCCESS;
2549 return RESULT_SHOWUSAGE;
2553 static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2556 pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
2558 ast_agi_send(agi->fd, chan, "200 result=1\n");
2559 return RESULT_SUCCESS;
2562 static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2565 char tempstr[1024] = "";
2568 return RESULT_SHOWUSAGE;
2570 /* check if we want to execute an ast_custom_function */
2571 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
2572 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
2574 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
2578 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ret);
2580 ast_agi_send(agi->fd, chan, "200 result=0\n");
2582 return RESULT_SUCCESS;
2585 static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2587 struct ast_channel *chan2 = NULL;
2589 if (argc != 4 && argc != 5) {
2590 return RESULT_SHOWUSAGE;
2594 chan2 = ast_channel_get_by_name(argv[4]);
2596 chan2 = ast_channel_ref(chan);
2600 struct ast_str *str = ast_str_create(16);
2602 ast_agi_send(agi->fd, chan, "200 result=0\n");
2603 return RESULT_SUCCESS;
2605 ast_str_substitute_variables(&str, 0, chan2, argv[3]);
2606 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str));
2609 ast_agi_send(agi->fd, chan, "200 result=0\n");
2613 chan2 = ast_channel_unref(chan2);
2616 return RESULT_SUCCESS;
2619 static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2624 return RESULT_SHOWUSAGE;
2627 sscanf(argv[2], "%30d", &level);
2629 ast_verb(level, "%s: %s\n", chan->data, argv[1]);
2631 ast_agi_send(agi->fd, chan, "200 result=1\n");
2633 return RESULT_SUCCESS;
2636 static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2639 struct ast_str *buf;
2642 return RESULT_SHOWUSAGE;
2644 if (!(buf = ast_str_create(16))) {
2645 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2646 return RESULT_SUCCESS;
2650 res = ast_db_get(argv[2], argv[3], ast_str_buffer(buf), ast_str_size(buf));
2651 ast_str_update(buf);
2652 if (ast_str_strlen(buf) < ast_str_size(buf) - 1) {
2655 if (ast_str_make_space(&buf, ast_str_size(buf) * 2)) {
2661 ast_agi_send(agi->fd, chan, "200 result=0\n");
2663 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(buf));
2666 return RESULT_SUCCESS;
2669 static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2674 return RESULT_SHOWUSAGE;
2675 res = ast_db_put(argv[2], argv[3], argv[4]);
2676 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2677 return RESULT_SUCCESS;
2680 static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2685 return RESULT_SHOWUSAGE;
2686 res = ast_db_del(argv[2], argv[3]);
2687 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2688 return RESULT_SUCCESS;
2691 static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2695 if ((argc < 3) || (argc > 4))
2696 return RESULT_SHOWUSAGE;
2698 res = ast_db_deltree(argv[2], argv[3]);
2700 res = ast_db_deltree(argv[2], NULL);
2702 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2703 return RESULT_SUCCESS;
2706 static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2710 e->command = "agi set debug [on|off]";
2712 "Usage: agi set debug [on|off]\n"
2713 " Enables/disables dumping of AGI transactions for\n"
2714 " debugging purposes.\n";
2721 if (a->argc != e->args)
2722 return CLI_SHOWUSAGE;
2724 if (strncasecmp(a->argv[3], "off", 3) == 0) {
2726 } else if (strncasecmp(a->argv[3], "on", 2) == 0) {
2729 return CLI_SHOWUSAGE;
2731 ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis");
2735 static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, const char * const argv[])
2737 ast_agi_send(agi->fd, chan, "200 result=0\n");
2738 return RESULT_SUCCESS;
2741 static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2744 return RESULT_SHOWUSAGE;
2746 if (!strncasecmp(argv[2], "on", 2))
2747 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
2748 else if (!strncasecmp(argv[2], "off", 3))
2750 ast_agi_send(agi->fd, chan, "200 result=0\n");
2751 return RESULT_SUCCESS;
2754 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2756 struct ast_format_cap *cap;
2757 struct ast_format tmpfmt;
2759 /* If a structure already exists, return an error */
2761 ast_agi_send(agi->fd, chan, "200 result=0\n");
2762 return RESULT_SUCCESS;
2765 if (!(cap = ast_format_cap_alloc_nolock())) {
2766 return RESULT_FAILURE;
2768 ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
2769 if ((agi->speech = ast_speech_new(argv[2], cap))) {
2770 ast_agi_send(agi->fd, chan, "200 result=1\n");
2772 ast_agi_send(agi->fd, chan, "200 result=0\n");
2774 cap = ast_format_cap_destroy(cap);
2776 return RESULT_SUCCESS;
2779 static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2781 /* Check for minimum arguments */
2783 return RESULT_SHOWUSAGE;
2785 /* Check to make sure speech structure exists */
2787 ast_agi_send(agi->fd, chan, "200 result=0\n");
2788 return RESULT_SUCCESS;
2791 ast_speech_change(agi->speech, argv[2], argv[3]);
2792 ast_agi_send(agi->fd, chan, "200 result=1\n");
2794 return RESULT_SUCCESS;
2797 static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2800 ast_speech_destroy(agi->speech);
2802 ast_agi_send(agi->fd, chan, "200 result=1\n");
2804 ast_agi_send(agi->fd, chan, "200 result=0\n");
2807 return RESULT_SUCCESS;
2810 static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2813 return RESULT_SHOWUSAGE;
2816 ast_agi_send(agi->fd, chan, "200 result=0\n");
2817 return RESULT_SUCCESS;
2820 if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
2821 ast_agi_send(agi->fd, chan, "200 result=0\n");
2823 ast_agi_send(agi->fd, chan, "200 result=1\n");
2825 return RESULT_SUCCESS;
2828 static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2831 return RESULT_SHOWUSAGE;
2834 ast_agi_send(agi->fd, chan, "200 result=0\n");
2835 return RESULT_SUCCESS;
2838 if (ast_speech_grammar_unload(agi->speech, argv[3]))
2839 ast_agi_send(agi->fd, chan, "200 result=0\n");
2841 ast_agi_send(agi->fd, chan, "200 result=1\n");
2843 return RESULT_SUCCESS;
2846 static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2849 return RESULT_SHOWUSAGE;
2852 ast_agi_send(agi->fd, chan, "200 result=0\n");
2853 return RESULT_SUCCESS;
2856 if (ast_speech_grammar_activate(agi->speech, argv[3]))
2857 ast_agi_send(agi->fd, chan, "200 result=0\n");
2859 ast_agi_send(agi->fd, chan, "200 result=1\n");
2861 return RESULT_SUCCESS;
2864 static int handle_speechdeactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2867 return RESULT_SHOWUSAGE;
2870 ast_agi_send(agi->fd, chan, "200 result=0\n");
2871 return RESULT_SUCCESS;
2874 if (ast_speech_grammar_deactivate(agi->speech, argv[3]))
2875 ast_agi_send(agi->fd, chan, "200 result=0\n");
2877 ast_agi_send(agi->fd, chan, "200 result=1\n");
2879 return RESULT_SUCCESS;
2882 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang, int offset)
2884 struct ast_filestream *fs = NULL;
2886 if (!(fs = ast_openstream(chan, filename, preflang)))
2890 ast_seekstream(fs, offset, SEEK_SET);
2892 if (ast_applystream(chan, fs))
2895 if (ast_playstream(fs))
2901 static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2903 struct ast_speech *speech = agi->speech;
2905 char dtmf = 0, tmp[4096] = "", *buf = tmp;
2906 int timeout = 0, offset = 0, res = 0, i = 0;
2907 struct ast_format old_read_format;
2908 long current_offset = 0;
2909 const char *reason = NULL;
2910 struct ast_frame *fr = NULL;
2911 struct ast_speech_result *result = NULL;
2912 size_t left = sizeof(tmp);
2913 time_t start = 0, current;
2916 return RESULT_SHOWUSAGE;
2919 ast_agi_send(agi->fd, chan, "200 result=0\n");
2920 return RESULT_SUCCESS;
2924 timeout = atoi(argv[3]);
2926 /* If offset is specified then convert from text to integer */
2928 offset = atoi(argv[4]);
2930 /* We want frames coming in signed linear */
2931 ast_format_copy(&old_read_format, &chan->readformat);
2932 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
2933 ast_agi_send(agi->fd, chan, "200 result=0\n");
2934 return RESULT_SUCCESS;
2937 /* Setup speech structure */
2938 if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
2939 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
2940 ast_speech_start(speech);
2943 /* Start playing prompt */
2944 speech_streamfile(chan, prompt, chan->language, offset);
2946 /* Go into loop reading in frames, passing to speech thingy, checking for hangup, all that jazz */
2947 while (ast_strlen_zero(reason)) {
2948 /* Run scheduled items */
2949 ast_sched_runq(chan->sched);
2951 /* See maximum time of waiting */
2952 if ((res = ast_sched_wait(chan->sched)) < 0)
2955 /* Wait for frame */
2956 if (ast_waitfor(chan, res) > 0) {
2957 if (!(fr = ast_read(chan))) {
2963 /* Perform timeout check */
2964 if ((timeout > 0) && (start > 0)) {
2966 if ((current - start) >= timeout) {
2974 /* Check the speech structure for any changes */
2975 ast_mutex_lock(&speech->lock);
2977 /* See if we need to quiet the audio stream playback */
2978 if (ast_test_flag(speech, AST_SPEECH_QUIET) && chan->stream) {
2979 current_offset = ast_tellstream(chan->stream);
2980 ast_stopstream(chan);
2981 ast_clear_flag(speech, AST_SPEECH_QUIET);
2984 /* Check each state */
2985 switch (speech->state) {
2986 case AST_SPEECH_STATE_READY:
2987 /* If the stream is done, start timeout calculation */
2988 if ((timeout > 0) && start == 0 && ((!chan->stream) || (chan->streamid == -1 && chan->timingfunc == NULL))) {
2989 ast_stopstream(chan);
2992 /* Write audio frame data into speech engine if possible */
2993 if (fr && fr->frametype == AST_FRAME_VOICE)
2994 ast_speech_write(speech, fr->data.ptr, fr->datalen);
2996 case AST_SPEECH_STATE_WAIT:
2997 /* Cue waiting sound if not already playing */
2998 if ((!chan->stream) || (chan->streamid == -1 && chan->timingfunc == NULL)) {
2999 ast_stopstream(chan);
3000 /* If a processing sound exists, or is not none - play it */
3001 if (!ast_strlen_zero(speech->processing_sound) && strcasecmp(speech->processing_sound, "none"))
3002 speech_streamfile(chan, speech->processing_sound, chan->language, 0);
3005 case AST_SPEECH_STATE_DONE:
3006 /* Get the results */
3007 speech->results = ast_speech_results_get(speech);
3008 /* Change state to not ready */
3009 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
3015 ast_mutex_unlock(&speech->lock);
3017 /* Check frame for DTMF or hangup */
3019 if (fr->frametype == AST_FRAME_DTMF) {
3021 dtmf = fr->subclass.integer;
3022 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_HANGUP) {
3029 if (!strcasecmp(reason, "speech")) {
3030 /* Build string containing speech results */
3031 for (result = speech->results; result; result = AST_LIST_NEXT(result, list)) {
3032 /* Build result string */
3033 ast_build_string(&buf, &left, "%sscore%d=%d text%d=\"%s\" grammar%d=%s", (i > 0 ? " " : ""), i, result->score, i, result->text, i, result->grammar);
3034 /* Increment result count */
3038 ast_agi_send(agi->fd, chan, "200 result=1 (speech) endpos=%ld results=%d %s\n", current_offset, i, tmp);
3039 } else if (!strcasecmp(reason, "dtmf")) {
3040 ast_agi_send(agi->fd, chan, "200 result=1 (digit) digit=%c endpos=%ld\n", dtmf, current_offset);
3041 } else if (!strcasecmp(reason, "hangup") || !strcasecmp(reason, "timeout")) {
3042 ast_agi_send(agi->fd, chan, "200 result=1 (%s) endpos=%ld\n", reason, current_offset);
3044 ast_agi_send(agi->fd, chan, "200 result=0 endpos=%ld\n", current_offset);
3047 return RESULT_SUCCESS;
3051 * \brief AGI commands list
3053 static struct agi_command commands[] = {
3054 { { "answer", NULL }, handle_answer, NULL, NULL, 0 },
3055 { { "asyncagi", "break", NULL }, handle_asyncagi_break, NULL, NULL, 1 },
3056 { { "channel", "status", NULL }, handle_channelstatus, NULL, NULL, 0 },
3057 { { "database", "del", NULL }, handle_dbdel, NULL, NULL, 1 },
3058 { { "database", "deltree", NULL }, handle_dbdeltree, NULL, NULL, 1 },
3059 { { "database", "get", NULL }, handle_dbget, NULL, NULL, 1 },
3060 { { "database", "put", NULL }, handle_dbput, NULL, NULL, 1 },
3061 { { "exec", NULL }, handle_exec, NULL, NULL, 1 },
3062 { { "get", "data", NULL }, handle_getdata, NULL, NULL, 0 },
3063 { { "get", "full", "variable", NULL }, handle_getvariablefull, NULL, NULL, 1 },
3064 { { "get", "option", NULL }, handle_getoption, NULL, NULL, 0 },
3065 { { "get", "variable", NULL }, handle_getvariable, NULL, NULL, 1 },
3066 { { "hangup", NULL }, handle_hangup, NULL, NULL, 0 },
3067 { { "noop", NULL }, handle_noop, NULL, NULL, 1 },
3068 { { "receive", "char", NULL }, handle_recvchar, NULL, NULL, 0 },
3069 { { "receive", "text", NULL }, handle_recvtext, NULL,