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
29 <support_level>core</support_level>
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
43 #include "asterisk/paths.h" /* use many ast_config_AST_*_DIR */
44 #include "asterisk/network.h"
45 #include "asterisk/file.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/pbx.h"
48 #include "asterisk/module.h"
49 #include "asterisk/astdb.h"
50 #include "asterisk/callerid.h"
51 #include "asterisk/cli.h"
52 #include "asterisk/image.h"
53 #include "asterisk/say.h"
54 #include "asterisk/app.h"
55 #include "asterisk/dsp.h"
56 #include "asterisk/musiconhold.h"
57 #include "asterisk/utils.h"
58 #include "asterisk/lock.h"
59 #include "asterisk/strings.h"
60 #include "asterisk/manager.h"
61 #include "asterisk/ast_version.h"
62 #include "asterisk/speech.h"
63 #include "asterisk/manager.h"
64 #include "asterisk/term.h"
65 #include "asterisk/xmldoc.h"
66 #include "asterisk/srv.h"
67 #include "asterisk/test.h"
68 #include "asterisk/netsock2.h"
70 #define AST_API_MODULE
71 #include "asterisk/agi.h"
74 <agi name="answer" language="en_US">
80 <para>Answers channel if not already in answer state. Returns <literal>-1</literal> on
81 channel failure, or <literal>0</literal> if successful.</para>
84 <ref type="agi">hangup</ref>
87 <agi name="asyncagi break" language="en_US">
93 <para>Interrupts expected flow of Async AGI commands and returns control to previous source
94 (typically, the PBX dialplan).</para>
97 <ref type="agi">hangup</ref>
100 <agi name="channel status" language="en_US">
102 Returns status of the connected channel.
105 <parameter name="channelname" />
108 <para>Returns the status of the specified <replaceable>channelname</replaceable>.
109 If no channel name is given then returns the status of the current channel.</para>
110 <para>Return values:</para>
113 <para>Channel is down and available.</para>
116 <para>Channel is down, but reserved.</para>
119 <para>Channel is off hook.</para>
122 <para>Digits (or equivalent) have been dialed.</para>
125 <para>Line is ringing.</para>
128 <para>Remote end is ringing.</para>
131 <para>Line is up.</para>
134 <para>Line is busy.</para>
139 <agi name="control stream file" language="en_US">
141 Sends audio file on channel and allows the listener to control the stream.
144 <parameter name="filename" required="true">
145 <para>The file extension must not be included in the filename.</para>
147 <parameter name="escape_digits" required="true" />
148 <parameter name="skipms" />
149 <parameter name="ffchar">
150 <para>Defaults to <literal>*</literal></para>
152 <parameter name="rewchr">
153 <para>Defaults to <literal>#</literal></para>
155 <parameter name="pausechr" />
158 <para>Send the given file, allowing playback to be controlled by the given
159 digits, if any. Use double quotes for the digits if you wish none to be
160 permitted. Returns <literal>0</literal> if playback completes without a digit
161 being pressed, or the ASCII numerical value of the digit if one was pressed,
162 or <literal>-1</literal> on error or if the channel was disconnected.</para>
165 <agi name="database del" language="en_US">
167 Removes database key/value
170 <parameter name="family" required="true" />
171 <parameter name="key" required="true" />
174 <para>Deletes an entry in the Asterisk database for a given
175 <replaceable>family</replaceable> and <replaceable>key</replaceable>.</para>
176 <para>Returns <literal>1</literal> if successful, <literal>0</literal>
180 <agi name="database deltree" language="en_US">
182 Removes database keytree/value
185 <parameter name="family" required="true" />
186 <parameter name="keytree" />
189 <para>Deletes a <replaceable>family</replaceable> or specific <replaceable>keytree</replaceable>
190 within a <replaceable>family</replaceable> in the Asterisk database.</para>
191 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
194 <agi name="database get" language="en_US">
199 <parameter name="family" required="true" />
200 <parameter name="key" required="true" />
203 <para>Retrieves an entry in the Asterisk database for a given <replaceable>family</replaceable>
204 and <replaceable>key</replaceable>.</para>
205 <para>Returns <literal>0</literal> if <replaceable>key</replaceable> is not set.
206 Returns <literal>1</literal> if <replaceable>key</replaceable> is set and returns the variable
207 in parenthesis.</para>
208 <para>Example return code: 200 result=1 (testvariable)</para>
211 <agi name="database put" language="en_US">
213 Adds/updates database value
216 <parameter name="family" required="true" />
217 <parameter name="key" required="true" />
218 <parameter name="value" required="true" />
221 <para>Adds or updates an entry in the Asterisk database for a given
222 <replaceable>family</replaceable>, <replaceable>key</replaceable>, and
223 <replaceable>value</replaceable>.</para>
224 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
227 <agi name="exec" language="en_US">
229 Executes a given Application
232 <parameter name="application" required="true" />
233 <parameter name="options" required="true" />
236 <para>Executes <replaceable>application</replaceable> with given
237 <replaceable>options</replaceable>.</para>
238 <para>Returns whatever the <replaceable>application</replaceable> returns, or
239 <literal>-2</literal> on failure to find <replaceable>application</replaceable>.</para>
242 <agi name="get data" language="en_US">
244 Prompts for DTMF on a channel
247 <parameter name="file" required="true" />
248 <parameter name="timeout" />
249 <parameter name="maxdigits" />
252 <para>Stream the given <replaceable>file</replaceable>, and receive DTMF data.</para>
253 <para>Returns the digits received from the channel at the other end.</para>
256 <agi name="get full variable" language="en_US">
258 Evaluates a channel expression
261 <parameter name="variablename" required="true" />
262 <parameter name="channel name" />
265 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set
266 or channel does not exist. Returns <literal>1</literal> if <replaceable>variablename</replaceable>
267 is set and returns the variable in parenthesis. Understands complex variable names and builtin
268 variables, unlike GET VARIABLE.</para>
269 <para>Example return code: 200 result=1 (testvariable)</para>
272 <agi name="get option" language="en_US">
274 Stream file, prompt for DTMF, with timeout.
277 <parameter name="filename" required="true" />
278 <parameter name="escape_digits" required="true" />
279 <parameter name="timeout" />
282 <para>Behaves similar to STREAM FILE but used with a timeout option.</para>
285 <ref type="agi">stream file</ref>
288 <agi name="get variable" language="en_US">
290 Gets a channel variable.
293 <parameter name="variablename" required="true" />
296 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set.
297 Returns <literal>1</literal> if <replaceable>variablename</replaceable> is set and returns
298 the variable in parentheses.</para>
299 <para>Example return code: 200 result=1 (testvariable)</para>
302 <agi name="hangup" language="en_US">
307 <parameter name="channelname" />
310 <para>Hangs up the specified channel. If no channel name is given, hangs
311 up the current channel</para>
314 <agi name="noop" language="en_US">
320 <para>Does nothing.</para>
323 <agi name="receive char" language="en_US">
325 Receives one character from channels supporting it.
328 <parameter name="timeout" required="true">
329 <para>The maximum time to wait for input in milliseconds, or <literal>0</literal>
330 for infinite. Most channels</para>
334 <para>Receives a character of text on a channel. Most channels do not support
335 the reception of text. Returns the decimal value of the character
336 if one is received, or <literal>0</literal> if the channel does not support
337 text reception. Returns <literal>-1</literal> only on error/hangup.</para>
340 <agi name="receive text" language="en_US">
342 Receives text from channels supporting it.
345 <parameter name="timeout" required="true">
346 <para>The timeout to be the maximum time to wait for input in
347 milliseconds, or <literal>0</literal> for infinite.</para>
351 <para>Receives a string of text on a channel. Most channels
352 do not support the reception of text. Returns <literal>-1</literal> for failure
353 or <literal>1</literal> for success, and the string in parenthesis.</para>
356 <agi name="record file" language="en_US">
358 Records to a given file.
361 <parameter name="filename" required="true" />
362 <parameter name="format" required="true" />
363 <parameter name="escape_digits" required="true" />
364 <parameter name="timeout" required="true" />
365 <parameter name="offset samples" />
366 <parameter name="BEEP" />
367 <parameter name="s=silence" />
370 <para>Record to a file until a given dtmf digit in the sequence is received.
371 Returns <literal>-1</literal> on hangup or error. The format will specify what kind of file
372 will be recorded. The <replaceable>timeout</replaceable> is the maximum record time in
373 milliseconds, or <literal>-1</literal> for no <replaceable>timeout</replaceable>.
374 <replaceable>offset samples</replaceable> is optional, and, if provided, will seek
375 to the offset without exceeding the end of the file. <replaceable>silence</replaceable> is
376 the number of seconds of silence allowed before the function returns despite the
377 lack of dtmf digits or reaching <replaceable>timeout</replaceable>. <replaceable>silence</replaceable>
378 value must be preceded by <literal>s=</literal> and is also optional.</para>
381 <agi name="say alpha" language="en_US">
383 Says a given character string.
386 <parameter name="number" required="true" />
387 <parameter name="escape_digits" required="true" />
390 <para>Say a given character string, returning early if any of the given DTMF digits
391 are received on the channel. Returns <literal>0</literal> if playback completes
392 without a digit being pressed, or the ASCII numerical value of the digit if one
393 was pressed or <literal>-1</literal> on error/hangup.</para>
396 <agi name="say digits" language="en_US">
398 Says a given digit string.
401 <parameter name="number" required="true" />
402 <parameter name="escape_digits" required="true" />
405 <para>Say a given digit string, returning early if any of the given DTMF digits
406 are received on the channel. Returns <literal>0</literal> if playback completes
407 without a digit being pressed, or the ASCII numerical value of the digit if one
408 was pressed or <literal>-1</literal> on error/hangup.</para>
411 <agi name="say number" language="en_US">
416 <parameter name="number" required="true" />
417 <parameter name="escape_digits" required="true" />
418 <parameter name="gender" />
421 <para>Say a given number, returning early if any of the given DTMF digits
422 are received on the channel. Returns <literal>0</literal> if playback
423 completes without a digit being pressed, or the ASCII numerical value of
424 the digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
427 <agi name="say phonetic" language="en_US">
429 Says a given character string with phonetics.
432 <parameter name="string" required="true" />
433 <parameter name="escape_digits" required="true" />
436 <para>Say a given character string with phonetics, returning early if any of the
437 given DTMF digits are received on the channel. Returns <literal>0</literal> if
438 playback completes without a digit pressed, the ASCII numerical value of the digit
439 if one was pressed, or <literal>-1</literal> on error/hangup.</para>
442 <agi name="say date" language="en_US">
447 <parameter name="date" required="true">
448 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
449 Coordinated Universal Time (UTC).</para>
451 <parameter name="escape_digits" required="true" />
454 <para>Say a given date, returning early if any of the given DTMF digits are
455 received on the channel. Returns <literal>0</literal> if playback
456 completes without a digit being pressed, or the ASCII numerical value of the
457 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
460 <agi name="say time" language="en_US">
465 <parameter name="time" required="true">
466 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
467 Coordinated Universal Time (UTC).</para>
469 <parameter name="escape_digits" required="true" />
472 <para>Say a given time, returning early if any of the given DTMF digits are
473 received on the channel. Returns <literal>0</literal> if playback completes
474 without a digit being pressed, or the ASCII numerical value of the digit if
475 one was pressed or <literal>-1</literal> on error/hangup.</para>
478 <agi name="say datetime" language="en_US">
480 Says a given time as specified by the format given.
483 <parameter name="time" required="true">
484 <para>Is number of seconds elapsed since 00:00:00
485 on January 1, 1970, Coordinated Universal Time (UTC)</para>
487 <parameter name="escape_digits" required="true" />
488 <parameter name="format">
489 <para>Is the format the time should be said in. See
490 <filename>voicemail.conf</filename> (defaults to <literal>ABdY
491 'digits/at' IMp</literal>).</para>
493 <parameter name="timezone">
494 <para>Acceptable values can be found in <filename>/usr/share/zoneinfo</filename>
495 Defaults to machine default.</para>
499 <para>Say a given time, returning early if any of the given DTMF digits are
500 received on the channel. Returns <literal>0</literal> if playback
501 completes without a digit being pressed, or the ASCII numerical value of the
502 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
505 <agi name="send image" language="en_US">
507 Sends images to channels supporting it.
510 <parameter name="image" required="true" />
513 <para>Sends the given image on a channel. Most channels do not support the
514 transmission of images. Returns <literal>0</literal> if image is sent, or if
515 the channel does not support image transmission. Returns <literal>-1</literal>
516 only on error/hangup. Image names should not include extensions.</para>
519 <agi name="send text" language="en_US">
521 Sends text to channels supporting it.
524 <parameter name="text to send" required="true">
525 <para>Text consisting of greater than one word should be placed
526 in quotes since the command only accepts a single argument.</para>
530 <para>Sends the given text on a channel. Most channels do not support the
531 transmission of text. Returns <literal>0</literal> if text is sent, or if the
532 channel does not support text transmission. Returns <literal>-1</literal> only
533 on error/hangup.</para>
536 <agi name="set autohangup" language="en_US">
538 Autohangup channel in some time.
541 <parameter name="time" required="true" />
544 <para>Cause the channel to automatically hangup at <replaceable>time</replaceable>
545 seconds in the future. Of course it can be hungup before then as well. Setting to
546 <literal>0</literal> will cause the autohangup feature to be disabled on this channel.</para>
549 <agi name="set callerid" language="en_US">
551 Sets callerid for the current channel.
554 <parameter name="number" required="true" />
557 <para>Changes the callerid of the current channel.</para>
560 <agi name="set context" language="en_US">
562 Sets channel context.
565 <parameter name="desired context" required="true" />
568 <para>Sets the context for continuation upon exiting the application.</para>
571 <agi name="set extension" language="en_US">
573 Changes channel extension.
576 <parameter name="new extension" required="true" />
579 <para>Changes the extension for continuation upon exiting the application.</para>
582 <agi name="set music" language="en_US">
584 Enable/Disable Music on hold generator
587 <parameter required="true">
590 <parameter name="on" literal="true" required="true" />
593 <parameter name="off" literal="true" required="true" />
597 <parameter name="class" required="true" />
600 <para>Enables/Disables the music on hold generator. If <replaceable>class</replaceable>
601 is not specified, then the <literal>default</literal> music on hold class will be
603 <para>Always returns <literal>0</literal>.</para>
606 <agi name="set priority" language="en_US">
608 Set channel dialplan priority.
611 <parameter name="priority" required="true" />
614 <para>Changes the priority for continuation upon exiting the application.
615 The priority must be a valid priority or label.</para>
618 <agi name="set variable" language="en_US">
620 Sets a channel variable.
623 <parameter name="variablename" required="true" />
624 <parameter name="value" required="true" />
627 <para>Sets a variable to the current channel.</para>
630 <agi name="stream file" language="en_US">
632 Sends audio file on channel.
635 <parameter name="filename" required="true">
636 <para>File name to play. The file extension must not be
637 included in the <replaceable>filename</replaceable>.</para>
639 <parameter name="escape_digits" required="true">
640 <para>Use double quotes for the digits if you wish none to be
643 <parameter name="sample offset">
644 <para>If sample offset is provided then the audio will seek to sample
645 offset before play starts.</para>
649 <para>Send the given file, allowing playback to be interrupted by the given
650 digits, if any. Returns <literal>0</literal> if playback completes without a digit
651 being pressed, or the ASCII numerical value of the digit if one was pressed,
652 or <literal>-1</literal> on error or if the channel was disconnected.</para>
655 <ref type="agi">control stream file</ref>
658 <agi name="tdd mode" language="en_US">
660 Toggles TDD mode (for the deaf).
663 <parameter name="boolean" required="true">
671 <para>Enable/Disable TDD transmission/reception on a channel. Returns <literal>1</literal> if
672 successful, or <literal>0</literal> if channel is not TDD-capable.</para>
675 <agi name="verbose" language="en_US">
677 Logs a message to the asterisk verbose log.
680 <parameter name="message" required="true" />
681 <parameter name="level" required="true" />
684 <para>Sends <replaceable>message</replaceable> to the console via verbose
685 message system. <replaceable>level</replaceable> is the verbose level (1-4).
686 Always returns <literal>1</literal></para>
689 <agi name="wait for digit" language="en_US">
691 Waits for a digit to be pressed.
694 <parameter name="timeout" required="true" />
697 <para>Waits up to <replaceable>timeout</replaceable> milliseconds for channel to
698 receive a DTMF digit. Returns <literal>-1</literal> on channel failure, <literal>0</literal>
699 if no digit is received in the timeout, or the numerical value of the ascii of the digit if
700 one is received. Use <literal>-1</literal> for the <replaceable>timeout</replaceable> value if
701 you desire the call to block indefinitely.</para>
704 <agi name="speech create" language="en_US">
706 Creates a speech object.
709 <parameter name="engine" required="true" />
712 <para>Create a speech object to be used by the other Speech AGI commands.</para>
715 <agi name="speech set" language="en_US">
717 Sets a speech engine setting.
720 <parameter name="name" required="true" />
721 <parameter name="value" required="true" />
724 <para>Set an engine-specific setting.</para>
727 <agi name="speech destroy" language="en_US">
729 Destroys a speech object.
734 <para>Destroy the speech object created by <literal>SPEECH CREATE</literal>.</para>
737 <ref type="agi">speech create</ref>
740 <agi name="speech load grammar" language="en_US">
745 <parameter name="grammar name" required="true" />
746 <parameter name="path to grammar" required="true" />
749 <para>Loads the specified grammar as the specified name.</para>
752 <agi name="speech unload grammar" language="en_US">
757 <parameter name="grammar name" required="true" />
760 <para>Unloads the specified grammar.</para>
763 <agi name="speech activate grammar" language="en_US">
768 <parameter name="grammar name" required="true" />
771 <para>Activates the specified grammar on the speech object.</para>
774 <agi name="speech deactivate grammar" language="en_US">
776 Deactivates a grammar.
779 <parameter name="grammar name" required="true" />
782 <para>Deactivates the specified grammar on the speech object.</para>
785 <agi name="speech recognize" language="en_US">
790 <parameter name="prompt" required="true" />
791 <parameter name="timeout" required="true" />
792 <parameter name="offset" />
795 <para>Plays back given <replaceable>prompt</replaceable> while listening for
796 speech and dtmf.</para>
799 <application name="AGI" language="en_US">
801 Executes an AGI compliant application.
804 <parameter name="command" required="true" />
805 <parameter name="args">
806 <argument name="arg1" required="true" />
807 <argument name="arg2" multiple="yes" />
811 <para>Executes an Asterisk Gateway Interface compliant
812 program on a channel. AGI allows Asterisk to launch external programs written
813 in any language to control a telephony channel, play audio, read DTMF digits,
814 etc. by communicating with the AGI protocol on <emphasis>stdin</emphasis> and
815 <emphasis>stdout</emphasis>. As of <literal>1.6.0</literal>, this channel will
816 not stop dialplan execution on hangup inside of this application. Dialplan
817 execution will continue normally, even upon hangup until the AGI application
818 signals a desire to stop (either by exiting or, in the case of a net script, by
819 closing the connection). A locally executed AGI script will receive SIGHUP on
820 hangup from the channel except when using DeadAGI. A fast AGI server will
821 correspondingly receive a HANGUP inline with the command dialog. Both of theses
822 signals may be disabled by setting the <variable>AGISIGHUP</variable> channel
823 variable to <literal>no</literal> before executing the AGI application.
824 Alternatively, if you would like the AGI application to exit immediately
825 after a channel hangup is detected, set the <variable>AGIEXITONHANGUP</variable>
826 variable to <literal>yes</literal>.</para>
827 <para>Use the CLI command <literal>agi show commands</literal> to list available agi
829 <para>This application sets the following channel variable upon completion:</para>
831 <variable name="AGISTATUS">
832 <para>The status of the attempt to the run the AGI script
833 text string, one of:</para>
834 <value name="SUCCESS" />
835 <value name="FAILURE" />
836 <value name="NOTFOUND" />
837 <value name="HANGUP" />
842 <ref type="application">EAGI</ref>
843 <ref type="application">DeadAGI</ref>
846 <application name="EAGI" language="en_US">
848 Executes an EAGI compliant application.
851 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
852 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
855 <para>Using 'EAGI' provides enhanced AGI, with incoming audio available out of band
856 on file descriptor 3.</para>
857 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
858 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
861 <ref type="application">AGI</ref>
862 <ref type="application">DeadAGI</ref>
865 <application name="DeadAGI" language="en_US">
867 Executes AGI on a hungup channel.
870 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
871 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
874 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
875 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
878 <ref type="application">AGI</ref>
879 <ref type="application">EAGI</ref>
882 <manager name="AGI" language="en_US">
884 Add an AGI command to execute by Async AGI.
887 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
888 <parameter name="Channel" required="true">
889 <para>Channel that is currently in Async AGI.</para>
891 <parameter name="Command" required="true">
892 <para>Application to execute.</para>
894 <parameter name="CommandID">
895 <para>This will be sent back in CommandID header of AsyncAGI exec
896 event notification.</para>
900 <para>Add an AGI command to the execute queue of the channel in Async AGI.</para>
906 #define MAX_CMD_LEN 80
907 #define AGI_NANDFS_RETRY 3
908 #define AGI_BUF_LEN 2048
909 #define SRV_PREFIX "_agi._tcp."
911 static char *app = "AGI";
913 static char *eapp = "EAGI";
915 static char *deadapp = "DeadAGI";
917 static int agidebug = 0;
919 #define TONE_BLOCK_SIZE 200
921 /* Max time to connect to an AGI remote host */
922 #define MAX_AGI_CONNECT 2000
924 #define AGI_PORT 4573
926 /*! Special return code for "asyncagi break" command. */
927 #define ASYNC_AGI_BREAK 3
930 AGI_RESULT_FAILURE = -1,
932 AGI_RESULT_SUCCESS_FAST,
933 AGI_RESULT_SUCCESS_ASYNC,
938 static agi_command *find_command(const char * const cmds[], int exact);
940 AST_THREADSTORAGE(agi_buf);
941 #define AGI_BUF_INITSIZE 256
943 int AST_OPTIONAL_API_NAME(ast_agi_send)(int fd, struct ast_channel *chan, char *fmt, ...)
949 if (!(buf = ast_str_thread_get(&agi_buf, AGI_BUF_INITSIZE)))
953 res = ast_str_set_va(&buf, 0, fmt, ap);
957 ast_log(LOG_ERROR, "Out of memory\n");
963 ast_verbose("<%s>AGI Tx >> %s", ast_channel_name(chan), ast_str_buffer(buf));
965 ast_verbose("AGI Tx >> %s", ast_str_buffer(buf));
969 return ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
972 /* linked list of AGI commands ready to be executed by Async AGI */
976 AST_LIST_ENTRY(agi_cmd) entry;
979 static void free_agi_cmd(struct agi_cmd *cmd)
981 ast_free(cmd->cmd_buffer);
982 ast_free(cmd->cmd_id);
986 /* AGI datastore destructor */
987 static void agi_destroy_commands_cb(void *data)
990 AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
991 AST_LIST_LOCK(chan_cmds);
992 while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
995 AST_LIST_UNLOCK(chan_cmds);
996 AST_LIST_HEAD_DESTROY(chan_cmds);
1000 /* channel datastore to keep the queue of AGI commands in the channel */
1001 static const struct ast_datastore_info agi_commands_datastore_info = {
1003 .destroy = agi_destroy_commands_cb
1006 static struct agi_cmd *get_agi_cmd(struct ast_channel *chan)
1008 struct ast_datastore *store;
1009 struct agi_cmd *cmd;
1010 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1012 ast_channel_lock(chan);
1013 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1014 ast_channel_unlock(chan);
1016 ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
1017 ast_channel_name(chan));
1020 agi_commands = store->data;
1021 AST_LIST_LOCK(agi_commands);
1022 cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
1023 AST_LIST_UNLOCK(agi_commands);
1027 /* channel is locked when calling this one either from the CLI or manager thread */
1028 static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
1030 struct ast_datastore *store;
1031 struct agi_cmd *cmd;
1032 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1034 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1036 ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", ast_channel_name(chan));
1039 agi_commands = store->data;
1040 cmd = ast_calloc(1, sizeof(*cmd));
1044 cmd->cmd_buffer = ast_strdup(cmd_buff);
1045 if (!cmd->cmd_buffer) {
1049 cmd->cmd_id = ast_strdup(cmd_id);
1051 ast_free(cmd->cmd_buffer);
1055 AST_LIST_LOCK(agi_commands);
1056 AST_LIST_INSERT_TAIL(agi_commands, cmd, entry);
1057 AST_LIST_UNLOCK(agi_commands);
1061 static int add_to_agi(struct ast_channel *chan)
1063 struct ast_datastore *datastore;
1064 AST_LIST_HEAD(, agi_cmd) *agi_cmds_list;
1066 /* check if already on AGI */
1067 ast_channel_lock(chan);
1068 datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1069 ast_channel_unlock(chan);
1071 /* we already have an AGI datastore, let's just
1076 /* the channel has never been on Async AGI,
1077 let's allocate it's datastore */
1078 datastore = ast_datastore_alloc(&agi_commands_datastore_info, "AGI");
1082 agi_cmds_list = ast_calloc(1, sizeof(*agi_cmds_list));
1083 if (!agi_cmds_list) {
1084 ast_log(LOG_ERROR, "Unable to allocate Async AGI commands list.\n");
1085 ast_datastore_free(datastore);
1088 datastore->data = agi_cmds_list;
1089 AST_LIST_HEAD_INIT(agi_cmds_list);
1090 ast_channel_lock(chan);
1091 ast_channel_datastore_add(chan, datastore);
1092 ast_channel_unlock(chan);
1097 * \brief CLI command to add applications to execute in Async AGI
1102 * \retval CLI_SUCCESS on success
1103 * \retval NULL when init or tab completion is used
1105 static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1107 struct ast_channel *chan;
1110 e->command = "agi exec";
1111 e->usage = "Usage: agi exec <channel name> <app and arguments> [id]\n"
1112 " Add AGI command to the execute queue of the specified channel in Async AGI\n";
1116 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
1121 return CLI_SHOWUSAGE;
1124 if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
1125 ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
1129 ast_channel_lock(chan);
1131 if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
1132 ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", ast_channel_name(chan));
1133 ast_channel_unlock(chan);
1134 chan = ast_channel_unref(chan);
1138 ast_debug(1, "Added AGI command to channel %s queue\n", ast_channel_name(chan));
1140 ast_channel_unlock(chan);
1141 chan = ast_channel_unref(chan);
1147 * \brief Add a new command to execute by the Async AGI application
1151 * It will append the application to the specified channel's queue
1152 * if the channel is not inside Async AGI application it will return an error
1153 * \retval 0 on success or incorrect use
1154 * \retval 1 on failure to add the command ( most likely because the channel
1155 * is not in Async AGI loop )
1157 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
1159 const char *channel = astman_get_header(m, "Channel");
1160 const char *cmdbuff = astman_get_header(m, "Command");
1161 const char *cmdid = astman_get_header(m, "CommandID");
1162 struct ast_channel *chan;
1165 if (ast_strlen_zero(channel) || ast_strlen_zero(cmdbuff)) {
1166 astman_send_error(s, m, "Both, Channel and Command are *required*");
1170 if (!(chan = ast_channel_get_by_name(channel))) {
1171 snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
1172 astman_send_error(s, m, buf);
1176 ast_channel_lock(chan);
1178 if (add_agi_cmd(chan, cmdbuff, cmdid)) {
1179 snprintf(buf, sizeof(buf), "Failed to add AGI command to channel %s queue", ast_channel_name(chan));
1180 astman_send_error(s, m, buf);
1181 ast_channel_unlock(chan);
1182 chan = ast_channel_unref(chan);
1186 ast_channel_unlock(chan);
1187 chan = ast_channel_unref(chan);
1189 astman_send_ack(s, m, "Added AGI command to queue");
1194 static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
1195 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
1199 * \brief Read and handle a channel frame for Async AGI.
1201 * \param chan Channel to read a frame from.
1203 * \retval AGI_RESULT_SUCCESS on success.
1204 * \retval AGI_RESULT_HANGUP on hangup.
1205 * \retval AGI_RESULT_FAILURE on error.
1207 static enum agi_result async_agi_read_frame(struct ast_channel *chan)
1209 struct ast_frame *f;
1213 ast_debug(3, "No frame read on channel %s, going out ...\n", ast_channel_name(chan));
1214 return AGI_RESULT_HANGUP;
1216 if (f->frametype == AST_FRAME_CONTROL) {
1218 * Is there any other frame we should care about besides
1219 * AST_CONTROL_HANGUP?
1221 switch (f->subclass.integer) {
1222 case AST_CONTROL_HANGUP:
1223 ast_debug(3, "Got HANGUP frame on channel %s, going out ...\n", ast_channel_name(chan));
1225 return AGI_RESULT_HANGUP;
1232 return AGI_RESULT_SUCCESS;
1235 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
1237 /* This buffer sizes might cause truncation if the AGI command writes more data
1238 than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
1239 that writes a response larger than 1024 bytes?, I don't think so, most of
1240 them are just result=blah stuff. However probably if GET VARIABLE is called
1241 and the variable has large amount of data, that could be a problem. We could
1242 make this buffers dynamic, but let's leave that as a second step.
1244 AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
1245 number. Some characters of AGI buf will be url encoded to be sent to manager
1246 clients. An URL encoded character will take 3 bytes, but again, to cause
1247 truncation more than about 70% of the AGI buffer should be URL encoded for
1248 that to happen. Not likely at all.
1250 On the other hand. I wonder if read() could eventually return less data than
1251 the amount already available in the pipe? If so, how to deal with that?
1252 So far, my tests on Linux have not had any problems.
1254 #define AGI_BUF_SIZE 1024
1255 #define AMI_BUF_SIZE 2048
1256 enum agi_result cmd_status;
1257 struct agi_cmd *cmd;
1262 char agi_buffer[AGI_BUF_SIZE + 1];
1263 char ami_buffer[AMI_BUF_SIZE];
1264 enum agi_result returnstatus = AGI_RESULT_SUCCESS;
1268 ast_log(LOG_WARNING, "Async AGI does not support Enhanced AGI yet\n");
1269 return AGI_RESULT_FAILURE;
1272 /* add AsyncAGI datastore to the channel */
1273 if (add_to_agi(chan)) {
1274 ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", ast_channel_name(chan));
1275 return AGI_RESULT_FAILURE;
1278 /* this pipe allows us to create a "fake" AGI struct to use
1282 ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
1284 * Intentionally do not remove the datastore added with
1285 * add_to_agi() the from channel. It will be removed when the
1286 * channel is hung up anyway.
1288 return AGI_RESULT_FAILURE;
1291 /* handlers will get the pipe write fd and we read the AGI responses
1292 from the pipe read fd */
1293 async_agi.fd = fds[1];
1294 async_agi.ctrl = fds[1];
1295 async_agi.audio = -1; /* no audio support */
1297 async_agi.speech = NULL;
1299 /* notify possible manager users of a new channel ready to
1301 setup_env(chan, "async", fds[1], 0, 0, NULL);
1302 /* read the environment */
1303 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1305 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s: %s\n",
1306 ast_channel_name(chan), res < 0 ? strerror(errno) : "EOF");
1307 returnstatus = AGI_RESULT_FAILURE;
1308 goto async_agi_abort;
1310 agi_buffer[res] = '\0';
1311 /* encode it and send it thru the manager so whoever is going to take
1312 care of AGI commands on this channel can decide which AGI commands
1313 to execute based on the setup info */
1314 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1315 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1316 "SubEvent: Start\r\n"
1318 "Env: %s\r\n", ast_channel_name(chan), ami_buffer);
1319 hungup = ast_check_hangup(chan);
1322 * Process as many commands as we can. Commands are added via
1323 * the manager or the cli threads.
1325 while (!hungup && (cmd = get_agi_cmd(chan))) {
1326 /* OK, we have a command, let's call the command handler. */
1327 cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
1330 * The command handler must have written to our fake AGI struct
1331 * fd (the pipe), let's read the response.
1333 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1335 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s: %s\n",
1336 ast_channel_name(chan), res < 0 ? strerror(errno) : "EOF");
1338 returnstatus = AGI_RESULT_FAILURE;
1339 goto async_agi_done;
1342 * We have a response, let's send the response thru the manager.
1343 * Include the CommandID if it was specified when the command
1346 agi_buffer[res] = '\0';
1347 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1348 if (ast_strlen_zero(cmd->cmd_id)) {
1349 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1350 "SubEvent: Exec\r\n"
1352 "Result: %s\r\n", ast_channel_name(chan), ami_buffer);
1354 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1355 "SubEvent: Exec\r\n"
1358 "Result: %s\r\n", ast_channel_name(chan), cmd->cmd_id, ami_buffer);
1363 * Check the command status to determine if we should continue
1364 * executing more commands.
1366 hungup = ast_check_hangup(chan);
1367 switch (cmd_status) {
1368 case AGI_RESULT_FAILURE:
1370 /* The failure was not because of a hangup. */
1371 returnstatus = AGI_RESULT_FAILURE;
1372 goto async_agi_done;
1375 case AGI_RESULT_SUCCESS_ASYNC:
1376 /* Only the "asyncagi break" command does this. */
1377 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1378 goto async_agi_done;
1385 /* Wait a bit for a frame to read or to poll for a new command. */
1386 res = ast_waitfor(chan, timeout);
1388 ast_debug(1, "ast_waitfor returned <= 0 on chan %s\n", ast_channel_name(chan));
1389 returnstatus = AGI_RESULT_FAILURE;
1394 * Read the channel control queue until it is dry so we can
1401 cmd_status = async_agi_read_frame(chan);
1402 if (cmd_status != AGI_RESULT_SUCCESS) {
1403 returnstatus = cmd_status;
1404 goto async_agi_done;
1406 hungup = ast_check_hangup(chan);
1409 hungup = ast_check_hangup(chan);
1414 if (async_agi.speech) {
1415 ast_speech_destroy(async_agi.speech);
1417 /* notify manager users this channel cannot be
1418 controlled anymore by Async AGI */
1419 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1421 "Channel: %s\r\n", ast_channel_name(chan));
1424 /* close the pipe */
1429 * Intentionally do not remove the datastore added with
1430 * add_to_agi() the from channel. There might be commands still
1431 * in the queue or in-flight to us and AsyncAGI may get called
1432 * again. The datastore destructor will be called on channel
1433 * destruction anyway.
1436 if (returnstatus == AGI_RESULT_SUCCESS) {
1437 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1439 return returnstatus;
1445 /* launch_netscript: The fastagi handler.
1446 FastAGI defaults to port 4573 */
1447 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
1449 int s = 0, flags, res;
1450 struct pollfd pfds[1];
1451 char *host, *script;
1452 int num_addrs = 0, i = 0;
1453 struct ast_sockaddr *addrs;
1455 /* agiurl is "agi://host.domain[:port][/script/name]" */
1456 host = ast_strdupa(agiurl + 6); /* Remove agi:// */
1458 /* Strip off any script name */
1459 if ((script = strchr(host, '/'))) {
1465 if (!(num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC))) {
1466 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
1467 return AGI_RESULT_FAILURE;
1470 for (i = 0; i < num_addrs; i++) {
1471 if (!ast_sockaddr_port(&addrs[i])) {
1472 ast_sockaddr_set_port(&addrs[i], AGI_PORT);
1475 if ((s = socket(addrs[i].ss.ss_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
1476 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1480 if ((flags = fcntl(s, F_GETFL)) < 0) {
1481 ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
1486 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
1487 ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
1492 if (ast_connect(s, &addrs[i]) && (errno != EINPROGRESS)) {
1493 ast_log(LOG_WARNING, "Connection to %s failed with unexpected error: %s\n",
1494 ast_sockaddr_stringify(&addrs[i]),
1505 if (i == num_addrs) {
1506 ast_log(LOG_WARNING, "Couldn't connect to any host. FastAGI failed.\n");
1507 return AGI_RESULT_FAILURE;
1511 pfds[0].events = POLLOUT;
1512 while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
1513 if (errno != EINTR) {
1515 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
1516 agiurl, MAX_AGI_CONNECT);
1518 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1520 return AGI_RESULT_FAILURE;
1524 if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
1525 if (errno != EINTR) {
1526 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1528 return AGI_RESULT_FAILURE;
1532 /* If we have a script parameter, relay it to the fastagi server */
1533 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
1534 if (!ast_strlen_zero(script))
1535 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
1537 ast_debug(4, "Wow, connected!\n");
1540 return AGI_RESULT_SUCCESS_FAST;
1545 * \brief The HA fastagi handler.
1546 * \param agiurl The request URL as passed to Agi() in the dial plan
1547 * \param argv The parameters after the URL passed to Agi() in the dial plan
1548 * \param fds Input/output file descriptors
1550 * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
1551 * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
1552 * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
1553 * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
1556 * This function parses the URI, resolves the SRV service name, forms new URIs
1557 * with the results of the DNS lookup, and then calls launch_netscript on the
1558 * new URIs until one succeeds.
1560 * \return the result of the AGI operation.
1562 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
1564 char *host, *script;
1565 enum agi_result result;
1566 struct srv_context *context = NULL;
1569 char resolved_uri[1024];
1570 const char *srvhost;
1571 unsigned short srvport;
1573 /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
1574 if (!(host = ast_strdupa(agiurl + 7))) { /* Remove hagi:// */
1575 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
1576 return AGI_RESULT_FAILURE;
1579 /* Strip off any script name */
1580 if ((script = strchr(host, '/'))) {
1586 if (strchr(host, ':')) {
1587 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
1588 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
1591 snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
1593 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
1594 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
1595 result = launch_netscript(resolved_uri, argv, fds);
1596 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
1597 ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
1599 /* The script launched so we must cleanup the context. */
1600 ast_srv_cleanup(&context);
1605 * The DNS SRV lookup failed or we ran out of servers to check.
1606 * ast_srv_lookup() has already cleaned up the context for us.
1609 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
1612 return AGI_RESULT_FAILURE;
1615 static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
1618 int pid, toast[2], fromast[2], audio[2], res;
1621 if (!strncasecmp(script, "agi://", 6)) {
1622 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1624 if (!strncasecmp(script, "hagi://", 7)) {
1625 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1627 if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
1628 return launch_asyncagi(chan, argv, efd);
1631 if (script[0] != '/') {
1632 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
1636 /* Before even trying let's see if the file actually exists */
1637 if (stat(script, &st)) {
1638 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
1639 return AGI_RESULT_NOTFOUND;
1643 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
1644 return AGI_RESULT_FAILURE;
1646 if (pipe(fromast)) {
1647 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
1650 return AGI_RESULT_FAILURE;
1654 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
1659 return AGI_RESULT_FAILURE;
1661 res = fcntl(audio[1], F_GETFL);
1663 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
1665 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
1672 return AGI_RESULT_FAILURE;
1676 if ((pid = ast_safe_fork(1)) < 0) {
1677 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
1678 return AGI_RESULT_FAILURE;
1681 /* Pass paths to AGI via environmental variables */
1682 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
1683 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
1684 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
1685 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
1686 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
1687 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
1688 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
1689 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
1690 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
1691 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
1692 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
1694 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
1695 ast_set_priority(0);
1697 /* Redirect stdin and out, provide enhanced audio channel if desired */
1698 dup2(fromast[0], STDIN_FILENO);
1699 dup2(toast[1], STDOUT_FILENO);
1701 dup2(audio[0], STDERR_FILENO + 1);
1703 close(STDERR_FILENO + 1);
1705 /* Close everything but stdin/out/error */
1706 ast_close_fds_above_n(STDERR_FILENO + 1);
1708 /* Execute script */
1709 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
1710 execv(script, argv);
1711 /* Can't use ast_log since FD's are closed */
1712 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
1713 /* Special case to set status of AGI to failure */
1714 fprintf(stdout, "failure\n");
1718 ast_verb(3, "Launched AGI Script %s\n", script);
1720 fds[1] = fromast[1];
1723 /* close what we're not using in the parent */
1731 return AGI_RESULT_SUCCESS;
1734 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
1738 /* Print initial environment, with agi_request always being the first
1740 ast_agi_send(fd, chan, "agi_request: %s\n", request);
1741 ast_agi_send(fd, chan, "agi_channel: %s\n", ast_channel_name(chan));
1742 ast_agi_send(fd, chan, "agi_language: %s\n", ast_channel_language(chan));
1743 ast_agi_send(fd, chan, "agi_type: %s\n", ast_channel_tech(chan)->type);
1744 ast_agi_send(fd, chan, "agi_uniqueid: %s\n", ast_channel_uniqueid(chan));
1745 ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
1748 ast_agi_send(fd, chan, "agi_callerid: %s\n",
1749 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "unknown"));
1750 ast_agi_send(fd, chan, "agi_calleridname: %s\n",
1751 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "unknown"));
1752 ast_agi_send(fd, chan, "agi_callingpres: %d\n",
1753 ast_party_id_presentation(&ast_channel_caller(chan)->id));
1754 ast_agi_send(fd, chan, "agi_callingani2: %d\n", ast_channel_caller(chan)->ani2);
1755 ast_agi_send(fd, chan, "agi_callington: %d\n", ast_channel_caller(chan)->id.number.plan);
1756 ast_agi_send(fd, chan, "agi_callingtns: %d\n", ast_channel_dialed(chan)->transit_network_select);
1757 ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(ast_channel_dialed(chan)->number.str, "unknown"));
1758 ast_agi_send(fd, chan, "agi_rdnis: %s\n",
1759 S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, "unknown"));
1761 /* Context information */
1762 ast_agi_send(fd, chan, "agi_context: %s\n", ast_channel_context(chan));
1763 ast_agi_send(fd, chan, "agi_extension: %s\n", ast_channel_exten(chan));
1764 ast_agi_send(fd, chan, "agi_priority: %d\n", ast_channel_priority(chan));
1765 ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
1767 /* User information */
1768 ast_agi_send(fd, chan, "agi_accountcode: %s\n", ast_channel_accountcode(chan) ? ast_channel_accountcode(chan) : "");
1769 ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
1771 /* Send any parameters to the fastagi server that have been passed via the agi application */
1772 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
1773 for(count = 1; count < argc; count++)
1774 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
1776 /* End with empty return */
1777 ast_agi_send(fd, chan, "\n");
1780 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1784 /* Answer the channel */
1785 if (ast_channel_state(chan) != AST_STATE_UP)
1786 res = ast_answer(chan);
1788 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1789 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1792 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1794 ast_agi_send(agi->fd, chan, "200 result=0\n");
1795 return ASYNC_AGI_BREAK;
1798 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1803 return RESULT_SHOWUSAGE;
1804 if (sscanf(argv[3], "%30d", &to) != 1)
1805 return RESULT_SHOWUSAGE;
1806 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
1807 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1808 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1811 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1816 return RESULT_SHOWUSAGE;
1818 /* At the moment, the parser (perhaps broken) returns with
1819 the last argument PLUS the newline at the end of the input
1820 buffer. This probably needs to be fixed, but I wont do that
1821 because other stuff may break as a result. The right way
1822 would probably be to strip off the trailing newline before
1823 parsing, then here, add a newline at the end of the string
1824 before sending it to ast_sendtext --DUDE */
1825 res = ast_sendtext(chan, argv[2]);
1826 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1827 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1830 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1835 return RESULT_SHOWUSAGE;
1837 res = ast_recvchar(chan,atoi(argv[2]));
1839 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
1840 return RESULT_SUCCESS;
1843 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1844 return RESULT_SUCCESS;
1846 ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
1847 return RESULT_FAILURE;
1850 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1855 return RESULT_SHOWUSAGE;
1857 buf = ast_recvtext(chan, atoi(argv[2]));
1859 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
1862 ast_agi_send(agi->fd, chan, "200 result=-1\n");
1864 return RESULT_SUCCESS;
1867 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1872 return RESULT_SHOWUSAGE;
1874 if (!strncasecmp(argv[2],"on",2)) {
1879 if (!strncasecmp(argv[2],"mate",4)) {
1882 if (!strncasecmp(argv[2],"tdd",3)) {
1885 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
1887 /* Set channel option failed */
1888 ast_agi_send(agi->fd, chan, "200 result=0\n");
1890 ast_agi_send(agi->fd, chan, "200 result=1\n");
1892 return RESULT_SUCCESS;
1895 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1900 return RESULT_SHOWUSAGE;
1903 res = ast_send_image(chan, argv[2]);
1904 if (!ast_check_hangup(chan)) {
1907 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1908 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1911 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1913 int res = 0, skipms = 3000;
1914 const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL; /* Default values */
1916 if (argc < 5 || argc > 9) {
1917 return RESULT_SHOWUSAGE;
1920 if (!ast_strlen_zero(argv[4])) {
1924 if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
1925 return RESULT_SHOWUSAGE;
1928 if (argc > 6 && !ast_strlen_zero(argv[6])) {
1932 if (argc > 7 && !ast_strlen_zero(argv[7])) {
1936 if (argc > 8 && !ast_strlen_zero(argv[8])) {
1940 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
1942 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1944 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1947 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1950 struct ast_filestream *fs, *vfs;
1951 long sample_offset = 0, max_length;
1952 const char *edigits = "";
1954 if (argc < 4 || argc > 5) {
1955 return RESULT_SHOWUSAGE;
1962 if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1)) {
1963 return RESULT_SHOWUSAGE;
1966 if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
1967 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
1968 return RESULT_SUCCESS;
1971 if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan)))) {
1972 ast_debug(1, "Ooh, found a video stream, too\n");
1975 ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
1977 ast_seekstream(fs, 0, SEEK_END);
1978 max_length = ast_tellstream(fs);
1979 ast_seekstream(fs, sample_offset, SEEK_SET);
1980 res = ast_applystream(chan, fs);
1982 ast_applystream(chan, vfs);
1986 ast_playstream(vfs);
1989 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
1990 /* this is to check for if ast_waitstream closed the stream, we probably are at
1991 * the end of the stream, return that amount, else check for the amount */
1992 sample_offset = (ast_channel_stream(chan)) ? ast_tellstream(fs) : max_length;
1993 ast_stopstream(chan);
1995 /* Stop this command, don't print a result line, as there is a new command */
1996 return RESULT_SUCCESS;
1998 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
1999 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2002 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
2003 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2006 struct ast_filestream *fs, *vfs;
2007 long sample_offset = 0, max_length;
2009 const char *edigits = "";
2011 if ( argc < 4 || argc > 5 )
2012 return RESULT_SHOWUSAGE;
2018 timeout = atoi(argv[4]);
2019 else if (ast_channel_pbx(chan)->dtimeoutms) {
2020 /* by default dtimeout is set to 5sec */
2021 timeout = ast_channel_pbx(chan)->dtimeoutms; /* in msec */
2024 if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2025 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2026 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2027 return RESULT_SUCCESS;
2030 if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan))))
2031 ast_debug(1, "Ooh, found a video stream, too\n");
2033 ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2035 ast_seekstream(fs, 0, SEEK_END);
2036 max_length = ast_tellstream(fs);
2037 ast_seekstream(fs, sample_offset, SEEK_SET);
2038 res = ast_applystream(chan, fs);
2040 ast_applystream(chan, vfs);
2043 ast_playstream(vfs);
2045 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2046 /* this is to check for if ast_waitstream closed the stream, we probably are at
2047 * the end of the stream, return that amount, else check for the amount */
2048 sample_offset = (ast_channel_stream(chan))?ast_tellstream(fs):max_length;
2049 ast_stopstream(chan);
2051 /* Stop this command, don't print a result line, as there is a new command */
2052 return RESULT_SUCCESS;
2055 /* If the user didnt press a key, wait for digitTimeout*/
2057 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2058 /* Make sure the new result is in the escape digits of the GET OPTION */
2059 if ( !strchr(edigits,res) )
2063 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2064 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2070 /*! \brief Say number in various language syntaxes */
2071 /* While waiting, we're sending a NULL. */
2072 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2076 if (argc < 4 || argc > 5)
2077 return RESULT_SHOWUSAGE;
2078 if (sscanf(argv[2], "%30d", &num) != 1)
2079 return RESULT_SHOWUSAGE;
2080 res = ast_say_number_full(chan, num, argv[3], ast_channel_language(chan), argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2082 return RESULT_SUCCESS;
2083 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2084 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2087 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2092 return RESULT_SHOWUSAGE;
2093 if (sscanf(argv[2], "%30d", &num) != 1)
2094 return RESULT_SHOWUSAGE;
2096 res = ast_say_digit_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2097 if (res == 1) /* New command */
2098 return RESULT_SUCCESS;
2099 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2100 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2103 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2108 return RESULT_SHOWUSAGE;
2110 res = ast_say_character_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2111 if (res == 1) /* New command */
2112 return RESULT_SUCCESS;
2113 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2114 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2117 static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2122 return RESULT_SHOWUSAGE;
2123 if (sscanf(argv[2], "%30d", &num) != 1)
2124 return RESULT_SHOWUSAGE;
2125 res = ast_say_date(chan, num, argv[3], ast_channel_language(chan));
2127 return RESULT_SUCCESS;
2128 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2129 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2132 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2137 return RESULT_SHOWUSAGE;
2138 if (sscanf(argv[2], "%30d", &num) != 1)
2139 return RESULT_SHOWUSAGE;
2140 res = ast_say_time(chan, num, argv[3], ast_channel_language(chan));
2142 return RESULT_SUCCESS;
2143 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2144 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2147 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2151 const char *format, *zone = NULL;
2154 return RESULT_SHOWUSAGE;
2159 /* XXX this doesn't belong here, but in the 'say' module */
2160 if (!strcasecmp(ast_channel_language(chan), "de")) {
2161 format = "A dBY HMS";
2163 format = "ABdY 'digits/at' IMp";
2167 if (argc > 5 && !ast_strlen_zero(argv[5]))
2170 if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2171 return RESULT_SHOWUSAGE;
2173 res = ast_say_date_with_format(chan, unixtime, argv[3], ast_channel_language(chan), format, zone);
2175 return RESULT_SUCCESS;
2177 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2178 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2181 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2186 return RESULT_SHOWUSAGE;
2188 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2189 if (res == 1) /* New command */
2190 return RESULT_SUCCESS;
2191 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2192 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2195 static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2197 int res, max, timeout;
2201 return RESULT_SHOWUSAGE;
2203 timeout = atoi(argv[3]);
2207 max = atoi(argv[4]);
2210 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2211 if (res == 2) /* New command */
2212 return RESULT_SUCCESS;
2214 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2216 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2218 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2219 return RESULT_SUCCESS;
2222 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2226 return RESULT_SHOWUSAGE;
2227 ast_channel_context_set(chan, argv[2]);
2228 ast_agi_send(agi->fd, chan, "200 result=0\n");
2229 return RESULT_SUCCESS;
2232 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2235 return RESULT_SHOWUSAGE;
2236 ast_channel_exten_set(chan, argv[2]);
2237 ast_agi_send(agi->fd, chan, "200 result=0\n");
2238 return RESULT_SUCCESS;
2241 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2246 return RESULT_SHOWUSAGE;
2248 if (sscanf(argv[2], "%30d", &pri) != 1) {
2249 pri = ast_findlabel_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), argv[2],
2250 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));
2252 return RESULT_SHOWUSAGE;
2255 ast_explicit_goto(chan, NULL, NULL, pri);
2256 ast_agi_send(agi->fd, chan, "200 result=0\n");
2257 return RESULT_SUCCESS;
2260 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2262 struct ast_filestream *fs;
2263 struct ast_frame *f;
2264 struct timeval start;
2265 long sample_offset = 0;
2269 struct ast_dsp *sildet=NULL; /* silence detector dsp */
2270 int totalsilence = 0;
2272 int silence = 0; /* amount of silence to allow */
2273 int gotsilence = 0; /* did we timeout for silence? */
2274 char *silencestr = NULL;
2275 struct ast_format rfmt;
2276 ast_format_clear(&rfmt);
2278 /* XXX EAGI FIXME XXX */
2281 return RESULT_SHOWUSAGE;
2282 if (sscanf(argv[5], "%30d", &ms) != 1)
2283 return RESULT_SHOWUSAGE;
2286 silencestr = strchr(argv[6],'s');
2287 if ((argc > 7) && (!silencestr))
2288 silencestr = strchr(argv[7],'s');
2289 if ((argc > 8) && (!silencestr))
2290 silencestr = strchr(argv[8],'s');
2293 if (strlen(silencestr) > 2) {
2294 if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2298 silence = atoi(silencestr);
2306 ast_format_copy(&rfmt, ast_channel_readformat(chan));
2307 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2309 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2310 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2311 return RESULT_FAILURE;
2313 sildet = ast_dsp_new();
2315 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2316 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2317 return RESULT_FAILURE;
2319 ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
2322 /* backward compatibility, if no offset given, arg[6] would have been
2323 * caught below and taken to be a beep, else if it is a digit then it is a
2325 if ((argc >6) && (sscanf(argv[6], "%30ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
2326 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2328 if ((argc > 7) && (!strchr(argv[7], '=')))
2329 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2332 res = ast_waitstream(chan, argv[4]);
2334 ast_agi_send(agi->fd, chan, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
2336 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE);
2339 ast_agi_send(agi->fd, chan, "200 result=%d (writefile)\n", res);
2341 ast_dsp_free(sildet);
2342 return RESULT_FAILURE;
2345 /* Request a video update */
2346 ast_indicate(chan, AST_CONTROL_VIDUPDATE);
2348 ast_channel_stream_set(chan, fs);
2349 ast_applystream(chan,fs);
2350 /* really should have checks */
2351 ast_seekstream(fs, sample_offset, SEEK_SET);
2352 ast_truncstream(fs);
2354 start = ast_tvnow();
2355 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
2356 res = ast_waitfor(chan, ms - ast_tvdiff_ms(ast_tvnow(), start));
2358 ast_closestream(fs);
2359 ast_agi_send(agi->fd, chan, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
2361 ast_dsp_free(sildet);
2362 return RESULT_FAILURE;
2366 ast_agi_send(agi->fd, chan, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
2367 ast_closestream(fs);
2369 ast_dsp_free(sildet);
2370 return RESULT_FAILURE;
2372 switch(f->frametype) {
2373 case AST_FRAME_DTMF:
2374 if (strchr(argv[4], f->subclass.integer)) {
2375 /* This is an interrupting chracter, so rewind to chop off any small
2376 amount of DTMF that may have been recorded
2378 ast_stream_rewind(fs, 200);
2379 ast_truncstream(fs);
2380 sample_offset = ast_tellstream(fs);
2381 ast_agi_send(agi->fd, chan, "200 result=%d (dtmf) endpos=%ld\n", f->subclass.integer, sample_offset);
2382 ast_closestream(fs);
2385 ast_dsp_free(sildet);
2386 return RESULT_SUCCESS;
2389 case AST_FRAME_VOICE:
2390 ast_writestream(fs, f);
2391 /* this is a safe place to check progress since we know that fs
2392 * is valid after a write, and it will then have our current
2394 sample_offset = ast_tellstream(fs);
2397 ast_dsp_silence(sildet, f, &dspsilence);
2399 totalsilence = dspsilence;
2403 if (totalsilence > silence) {
2404 /* Ended happily with silence */
2410 case AST_FRAME_VIDEO:
2411 ast_writestream(fs, f);
2413 /* Ignore all other frames */
2422 ast_stream_rewind(fs, silence-1000);
2423 ast_truncstream(fs);
2424 sample_offset = ast_tellstream(fs);
2426 ast_agi_send(agi->fd, chan, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
2427 ast_closestream(fs);
2431 res = ast_set_read_format(chan, &rfmt);
2433 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
2434 ast_dsp_free(sildet);
2437 return RESULT_SUCCESS;
2440 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2443 struct timeval whentohangup = { 0, 0 };
2446 return RESULT_SHOWUSAGE;
2447 if (sscanf(argv[2], "%30lf", &timeout) != 1)
2448 return RESULT_SHOWUSAGE;
2452 whentohangup.tv_sec = timeout;
2453 whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
2455 ast_channel_setwhentohangup_tv(chan, whentohangup);
2456 ast_agi_send(agi->fd, chan, "200 result=0\n");
2457 return RESULT_SUCCESS;
2460 static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2462 struct ast_channel *c;
2465 /* no argument: hangup the current channel */
2466 ast_set_hangupsource(chan, "dialplan/agi", 0);
2467 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
2468 ast_agi_send(agi->fd, chan, "200 result=1\n");
2469 return RESULT_SUCCESS;
2470 } else if (argc == 2) {
2471 /* one argument: look for info on the specified channel */
2472 if ((c = ast_channel_get_by_name(argv[1]))) {
2473 /* we have a matching channel */
2474 ast_set_hangupsource(c, "dialplan/agi", 0);
2475 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
2476 c = ast_channel_unref(c);
2477 ast_agi_send(agi->fd, chan, "200 result=1\n");
2478 return RESULT_SUCCESS;
2480 /* if we get this far no channel name matched the argument given */
2481 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2482 return RESULT_SUCCESS;
2484 return RESULT_SHOWUSAGE;
2488 static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2490 int res, workaround;
2491 struct ast_app *app_to_exec;
2494 return RESULT_SHOWUSAGE;
2496 ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
2498 if ((app_to_exec = pbx_findapp(argv[1]))) {
2499 if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) {
2500 ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
2502 if (ast_compat_res_agi && argc >= 3 && !ast_strlen_zero(argv[2])) {
2503 char *compat = alloca(strlen(argv[2]) * 2 + 1), *cptr;
2505 for (cptr = compat, vptr = argv[2]; *vptr; vptr++) {
2509 } else if (*vptr == '|') {
2516 res = pbx_exec(chan, app_to_exec, compat);
2518 res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
2521 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
2524 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
2527 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2529 /* Even though this is wrong, users are depending upon this result. */
2533 static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2536 char *l = NULL, *n = NULL;
2539 ast_copy_string(tmp, argv[2], sizeof(tmp));
2540 ast_callerid_parse(tmp, &n, &l);
2542 ast_shrink_phone_number(l);
2547 ast_set_callerid(chan, l, n, NULL);
2550 ast_agi_send(agi->fd, chan, "200 result=1\n");
2551 return RESULT_SUCCESS;
2554 static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2556 struct ast_channel *c;
2558 /* no argument: supply info on the current channel */
2559 ast_agi_send(agi->fd, chan, "200 result=%d\n", ast_channel_state(chan));
2560 return RESULT_SUCCESS;
2561 } else if (argc == 3) {
2562 /* one argument: look for info on the specified channel */
2563 if ((c = ast_channel_get_by_name(argv[2]))) {
2564 ast_agi_send(agi->fd, chan, "200 result=%d\n", ast_channel_state(c));
2565 c = ast_channel_unref(c);
2566 return RESULT_SUCCESS;
2568 /* if we get this far no channel name matched the argument given */
2569 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2570 return RESULT_SUCCESS;
2572 return RESULT_SHOWUSAGE;
2576 static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2579 pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
2581 ast_agi_send(agi->fd, chan, "200 result=1\n");
2582 return RESULT_SUCCESS;
2585 static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2588 char tempstr[1024] = "";
2591 return RESULT_SHOWUSAGE;
2593 /* check if we want to execute an ast_custom_function */
2594 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
2595 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
2597 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
2601 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ret);
2603 ast_agi_send(agi->fd, chan, "200 result=0\n");
2605 return RESULT_SUCCESS;
2608 static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2610 struct ast_channel *chan2 = NULL;
2612 if (argc != 4 && argc != 5) {
2613 return RESULT_SHOWUSAGE;
2617 chan2 = ast_channel_get_by_name(argv[4]);
2619 chan2 = ast_channel_ref(chan);
2623 struct ast_str *str = ast_str_create(16);
2625 ast_agi_send(agi->fd, chan, "200 result=0\n");
2626 return RESULT_SUCCESS;
2628 ast_str_substitute_variables(&str, 0, chan2, argv[3]);
2629 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str));
2632 ast_agi_send(agi->fd, chan, "200 result=0\n");
2636 chan2 = ast_channel_unref(chan2);
2639 return RESULT_SUCCESS;
2642 static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2647 return RESULT_SHOWUSAGE;
2650 sscanf(argv[2], "%30d", &level);
2652 ast_verb(level, "%s: %s\n", ast_channel_data(chan), argv[1]);
2654 ast_agi_send(agi->fd, chan, "200 result=1\n");
2656 return RESULT_SUCCESS;
2659 static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2662 struct ast_str *buf;
2665 return RESULT_SHOWUSAGE;
2667 if (!(buf = ast_str_create(16))) {
2668 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2669 return RESULT_SUCCESS;
2673 res = ast_db_get(argv[2], argv[3], ast_str_buffer(buf), ast_str_size(buf));
2674 ast_str_update(buf);
2675 if (ast_str_strlen(buf) < ast_str_size(buf) - 1) {
2678 if (ast_str_make_space(&buf, ast_str_size(buf) * 2)) {
2684 ast_agi_send(agi->fd, chan, "200 result=0\n");
2686 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(buf));
2689 return RESULT_SUCCESS;
2692 static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2697 return RESULT_SHOWUSAGE;
2698 res = ast_db_put(argv[2], argv[3], argv[4]);
2699 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2700 return RESULT_SUCCESS;
2703 static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2708 return RESULT_SHOWUSAGE;
2709 res = ast_db_del(argv[2], argv[3]);
2710 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2711 return RESULT_SUCCESS;
2714 static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2718 if ((argc < 3) || (argc > 4))
2719 return RESULT_SHOWUSAGE;
2721 res = ast_db_deltree(argv[2], argv[3]);
2723 res = ast_db_deltree(argv[2], NULL);
2725 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2726 return RESULT_SUCCESS;
2729 static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2733 e->command = "agi set debug [on|off]";
2735 "Usage: agi set debug [on|off]\n"
2736 " Enables/disables dumping of AGI transactions for\n"
2737 " debugging purposes.\n";
2744 if (a->argc != e->args)
2745 return CLI_SHOWUSAGE;
2747 if (strncasecmp(a->argv[3], "off", 3) == 0) {
2749 } else if (strncasecmp(a->argv[3], "on", 2) == 0) {
2752 return CLI_SHOWUSAGE;
2754 ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis");
2758 static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, const char * const argv[])
2760 ast_agi_send(agi->fd, chan, "200 result=0\n");
2761 return RESULT_SUCCESS;
2764 static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2767 return RESULT_SHOWUSAGE;
2769 if (!strncasecmp(argv[2], "on", 2))
2770 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
2771 else if (!strncasecmp(argv[2], "off", 3))
2773 ast_agi_send(agi->fd, chan, "200 result=0\n");
2774 return RESULT_SUCCESS;
2777 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2779 struct ast_format_cap *cap;
2780 struct ast_format tmpfmt;
2782 /* If a structure already exists, return an error */
2784 ast_agi_send(agi->fd, chan, "200 result=0\n");
2785 return RESULT_SUCCESS;
2788 if (!(cap = ast_format_cap_alloc_nolock())) {
2789 return RESULT_FAILURE;
2791 ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
2792 if ((agi->speech = ast_speech_new(argv[2], cap))) {
2793 ast_agi_send(agi->fd, chan, "200 result=1\n");
2795 ast_agi_send(agi->fd, chan, "200 result=0\n");
2797 cap = ast_format_cap_destroy(cap);
2799 return RESULT_SUCCESS;
2802 static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2804 /* Check for minimum arguments */
2806 return RESULT_SHOWUSAGE;
2808 /* Check to make sure speech structure exists */
2810 ast_agi_send(agi->fd, chan, "200 result=0\n");
2811 return RESULT_SUCCESS;
2814 ast_speech_change(agi->speech, argv[2], argv[3]);
2815 ast_agi_send(agi->fd, chan, "200 result=1\n");
2817 return RESULT_SUCCESS;
2820 static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2823 ast_speech_destroy(agi->speech);
2825 ast_agi_send(agi->fd, chan, "200 result=1\n");
2827 ast_agi_send(agi->fd, chan, "200 result=0\n");
2830 return RESULT_SUCCESS;
2833 static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2836 return RESULT_SHOWUSAGE;
2839 ast_agi_send(agi->fd, chan, "200 result=0\n");
2840 return RESULT_SUCCESS;
2843 if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
2844 ast_agi_send(agi->fd, chan, "200 result=0\n");
2846 ast_agi_send(agi->fd, chan, "200 result=1\n");
2848 return RESULT_SUCCESS;
2851 static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2854 return RESULT_SHOWUSAGE;
2857 ast_agi_send(agi->fd, chan, "200 result=0\n");
2858 return RESULT_SUCCESS;
2861 if (ast_speech_grammar_unload(agi->speech, argv[3]))
2862 ast_agi_send(agi->fd, chan, "200 result=0\n");
2864 ast_agi_send(agi->fd, chan, "200 result=1\n");
2866 return RESULT_SUCCESS;
2869 static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2872 return RESULT_SHOWUSAGE;
2875 ast_agi_send(agi->fd, chan, "200 result=0\n");
2876 return RESULT_SUCCESS;
2879 if (ast_speech_grammar_activate(agi->speech, argv[3]))
2880 ast_agi_send(agi->fd, chan, "200 result=0\n");
2882 ast_agi_send(agi->fd, chan, "200 result=1\n");
2884 return RESULT_SUCCESS;
2887 static int handle_speechdeactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2890 return RESULT_SHOWUSAGE;
2893 ast_agi_send(agi->fd, chan, "200 result=0\n");
2894 return RESULT_SUCCESS;
2897 if (ast_speech_grammar_deactivate(agi->speech, argv[3]))
2898 ast_agi_send(agi->fd, chan, "200 result=0\n");
2900 ast_agi_send(agi->fd, chan, "200 result=1\n");
2902 return RESULT_SUCCESS;
2905 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang, int offset)
2907 struct ast_filestream *fs = NULL;
2909 if (!(fs = ast_openstream(chan, filename, preflang)))
2913 ast_seekstream(fs, offset, SEEK_SET);
2915 if (ast_applystream(chan, fs))
2918 if (ast_playstream(fs))
2924 static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2926 struct ast_speech *speech = agi->speech;
2928 char dtmf = 0, tmp[4096] = "", *buf = tmp;
2929 int timeout = 0, offset = 0, res = 0, i = 0;
2930 struct ast_format old_read_format;
2931 long current_offset = 0;
2932 const char *reason = NULL;
2933 struct ast_frame *fr = NULL;
2934 struct ast_speech_result *result = NULL;
2935 size_t left = sizeof(tmp);
2936 time_t start = 0, current;
2939 return RESULT_SHOWUSAGE;
2942 ast_agi_send(agi->fd, chan, "200 result=0\n");
2943 return RESULT_SUCCESS;
2947 timeout = atoi(argv[3]);
2949 /* If offset is specified then convert from text to integer */
2951 offset = atoi(argv[4]);
2953 /* We want frames coming in signed linear */
2954 ast_format_copy(&old_read_format, ast_channel_readformat(chan));
2955 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
2956 ast_agi_send(agi->fd, chan, "200 result=0\n");
2957 return RESULT_SUCCESS;
2960 /* Setup speech structure */
2961 if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
2962 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
2963 ast_speech_start(speech);
2966 /* Start playing prompt */
2967 speech_streamfile(chan, prompt, ast_channel_language(chan), offset);
2969 /* Go into loop reading in frames, passing to speech thingy, checking for hangup, all that jazz */
2970 while (ast_strlen_zero(reason)) {
2971 /* Run scheduled items */
2972 ast_sched_runq(ast_channel_sched(chan));
2974 /* See maximum time of waiting */
2975 if ((res = ast_sched_wait(ast_channel_sched(chan))) < 0)
2978 /* Wait for frame */
2979 if (ast_waitfor(chan, res) > 0) {
2980 if (!(fr = ast_read(chan))) {
2986 /* Perform timeout check */
2987 if ((timeout > 0) && (start > 0)) {
2989 if ((current - start) >= timeout) {
2997 /* Check the speech structure for any changes */
2998 ast_mutex_lock(&speech->lock);
3000 /* See if we need to quiet the audio stream playback */
3001 if (ast_test_flag(speech, AST_SPEECH_QUIET) && ast_channel_stream(chan)) {
3002 current_offset = ast_tellstream(ast_channel_stream(chan));
3003 ast_stopstream(chan);
3004 ast_clear_flag(speech, AST_SPEECH_QUIET);
3007 /* Check each state */
3008 switch (speech->state) {
3009 case AST_SPEECH_STATE_READY:
3010 /* If the stream is done, start timeout calculation */
3011 if ((timeout > 0) && start == 0 && ((!ast_channel_stream(chan)) || (ast_channel_streamid(chan) == -1 && ast_channel_timingfunc(chan) == NULL))) {
3012 ast_stopstream(chan);
3015 /* Write audio frame data into speech engine if possible */
3016 if (fr && fr->frametype == AST_FRAME_VOICE)
3017 ast_speech_write(speech, fr->data.ptr, fr->datalen);
3019 case AST_SPEECH_STATE_WAIT:
3020 /* Cue waiting sound if not already playing */
3021 if ((!ast_channel_stream(chan)) || (ast_channel_streamid(chan) == -1 && ast_channel_timingfunc(chan) == NULL)) {
3022 ast_stopstream(chan);
3023 /* If a processing sound exists, or is not none - play it */
3024 if (!ast_strlen_zero(speech->processing_sound) && strcasecmp(speech->processing_sound, "none"))
3025 speech_streamfile(chan, speech->processing_sound, ast_channel_language(chan), 0);
3028 case AST_SPEECH_STATE_DONE:
3029 /* Get the results */
3030 speech->results = ast_speech_results_get(speech);
3031 /* Change state to not ready */
3032 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
3038 ast_mutex_unlock(&speech->lock);
3040 /* Check frame for DTMF or hangup */
3042 if (fr->frametype == AST_FRAME_DTMF) {
3044 dtmf = fr->subclass.integer;
3045 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_HANGUP) {
3052 if (!strcasecmp(reason, "speech")) {
3053 /* Build string containing speech results */
3054 for (result = speech->results; result; result = AST_LIST_NEXT(result, list)) {
3055 /* Build result string */
3056 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);
3057 /* Increment result count */
3061 ast_agi_send(agi->fd, chan, "200 result=1 (speech) endpos=%ld results=%d %s\n", current_offset, i, tmp);
3062 } else if (!strcasecmp(reason, "dtmf")) {
3063 ast_agi_send(agi->fd, chan, "200 result=1 (digit) digit=%c endpos=%ld\n", dtmf, current_offset);
3064 } else if (!strcasecmp(reason, "hangup") || !strcasecmp(reason, "timeout")) {
3065 ast_agi_send(agi->fd, chan, "200 result=1 (%s) endpos=%ld\n", reason, current_offset);
3067 ast_agi_send(agi->fd, chan, "200 result=0 endpos=%ld\n", current_offset);