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"
69 #define AST_API_MODULE
70 #include "asterisk/agi.h"
73 <agi name="answer" language="en_US">
79 <para>Answers channel if not already in answer state. Returns <literal>-1</literal> on
80 channel failure, or <literal>0</literal> if successful.</para>
83 <ref type="agi">hangup</ref>
86 <agi name="asyncagi break" language="en_US">
92 <para>Interrupts expected flow of Async AGI commands and returns control to previous source
93 (typically, the PBX dialplan).</para>
96 <ref type="agi">hangup</ref>
99 <agi name="channel status" language="en_US">
101 Returns status of the connected channel.
104 <parameter name="channelname" />
107 <para>Returns the status of the specified <replaceable>channelname</replaceable>.
108 If no channel name is given then returns the status of the current channel.</para>
109 <para>Return values:</para>
112 <para>Channel is down and available.</para>
115 <para>Channel is down, but reserved.</para>
118 <para>Channel is off hook.</para>
121 <para>Digits (or equivalent) have been dialed.</para>
124 <para>Line is ringing.</para>
127 <para>Remote end is ringing.</para>
130 <para>Line is up.</para>
133 <para>Line is busy.</para>
138 <agi name="control stream file" language="en_US">
140 Sends audio file on channel and allows the listener to control the stream.
143 <parameter name="filename" required="true">
144 <para>The file extension must not be included in the filename.</para>
146 <parameter name="escape_digits" required="true" />
147 <parameter name="skipms" />
148 <parameter name="ffchar">
149 <para>Defaults to <literal>*</literal></para>
151 <parameter name="rewchr">
152 <para>Defaults to <literal>#</literal></para>
154 <parameter name="pausechr" />
157 <para>Send the given file, allowing playback to be controlled by the given
158 digits, if any. Use double quotes for the digits if you wish none to be
159 permitted. Returns <literal>0</literal> if playback completes without a digit
160 being pressed, or the ASCII numerical value of the digit if one was pressed,
161 or <literal>-1</literal> on error or if the channel was disconnected.</para>
164 <agi name="database del" language="en_US">
166 Removes database key/value
169 <parameter name="family" required="true" />
170 <parameter name="key" required="true" />
173 <para>Deletes an entry in the Asterisk database for a given
174 <replaceable>family</replaceable> and <replaceable>key</replaceable>.</para>
175 <para>Returns <literal>1</literal> if successful, <literal>0</literal>
179 <agi name="database deltree" language="en_US">
181 Removes database keytree/value
184 <parameter name="family" required="true" />
185 <parameter name="keytree" />
188 <para>Deletes a <replaceable>family</replaceable> or specific <replaceable>keytree</replaceable>
189 within a <replaceable>family</replaceable> in the Asterisk database.</para>
190 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
193 <agi name="database get" language="en_US">
198 <parameter name="family" required="true" />
199 <parameter name="key" required="true" />
202 <para>Retrieves an entry in the Asterisk database for a given <replaceable>family</replaceable>
203 and <replaceable>key</replaceable>.</para>
204 <para>Returns <literal>0</literal> if <replaceable>key</replaceable> is not set.
205 Returns <literal>1</literal> if <replaceable>key</replaceable> is set and returns the variable
206 in parenthesis.</para>
207 <para>Example return code: 200 result=1 (testvariable)</para>
210 <agi name="database put" language="en_US">
212 Adds/updates database value
215 <parameter name="family" required="true" />
216 <parameter name="key" required="true" />
217 <parameter name="value" required="true" />
220 <para>Adds or updates an entry in the Asterisk database for a given
221 <replaceable>family</replaceable>, <replaceable>key</replaceable>, and
222 <replaceable>value</replaceable>.</para>
223 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
226 <agi name="exec" language="en_US">
228 Executes a given Application
231 <parameter name="application" required="true" />
232 <parameter name="options" required="true" />
235 <para>Executes <replaceable>application</replaceable> with given
236 <replaceable>options</replaceable>.</para>
237 <para>Returns whatever the <replaceable>application</replaceable> returns, or
238 <literal>-2</literal> on failure to find <replaceable>application</replaceable>.</para>
241 <agi name="get data" language="en_US">
243 Prompts for DTMF on a channel
246 <parameter name="file" required="true" />
247 <parameter name="timeout" />
248 <parameter name="maxdigits" />
251 <para>Stream the given <replaceable>file</replaceable>, and receive DTMF data.</para>
252 <para>Returns the digits received from the channel at the other end.</para>
255 <agi name="get full variable" language="en_US">
257 Evaluates a channel expression
260 <parameter name="variablename" required="true" />
261 <parameter name="channel name" />
264 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set
265 or channel does not exist. Returns <literal>1</literal> if <replaceable>variablename</replaceable>
266 is set and returns the variable in parenthesis. Understands complex variable names and builtin
267 variables, unlike GET VARIABLE.</para>
268 <para>Example return code: 200 result=1 (testvariable)</para>
271 <agi name="get option" language="en_US">
273 Stream file, prompt for DTMF, with timeout.
276 <parameter name="filename" required="true" />
277 <parameter name="escape_digits" required="true" />
278 <parameter name="timeout" />
281 <para>Behaves similar to STREAM FILE but used with a timeout option.</para>
284 <ref type="agi">stream file</ref>
287 <agi name="get variable" language="en_US">
289 Gets a channel variable.
292 <parameter name="variablename" required="true" />
295 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set.
296 Returns <literal>1</literal> if <replaceable>variablename</replaceable> is set and returns
297 the variable in parentheses.</para>
298 <para>Example return code: 200 result=1 (testvariable)</para>
301 <agi name="hangup" language="en_US">
306 <parameter name="channelname" />
309 <para>Hangs up the specified channel. If no channel name is given, hangs
310 up the current channel</para>
313 <agi name="noop" language="en_US">
319 <para>Does nothing.</para>
322 <agi name="receive char" language="en_US">
324 Receives one character from channels supporting it.
327 <parameter name="timeout" required="true">
328 <para>The maximum time to wait for input in milliseconds, or <literal>0</literal>
329 for infinite. Most channels</para>
333 <para>Receives a character of text on a channel. Most channels do not support
334 the reception of text. Returns the decimal value of the character
335 if one is received, or <literal>0</literal> if the channel does not support
336 text reception. Returns <literal>-1</literal> only on error/hangup.</para>
339 <agi name="receive text" language="en_US">
341 Receives text from channels supporting it.
344 <parameter name="timeout" required="true">
345 <para>The timeout to be the maximum time to wait for input in
346 milliseconds, or <literal>0</literal> for infinite.</para>
350 <para>Receives a string of text on a channel. Most channels
351 do not support the reception of text. Returns <literal>-1</literal> for failure
352 or <literal>1</literal> for success, and the string in parenthesis.</para>
355 <agi name="record file" language="en_US">
357 Records to a given file.
360 <parameter name="filename" required="true" />
361 <parameter name="format" required="true" />
362 <parameter name="escape_digits" required="true" />
363 <parameter name="timeout" required="true" />
364 <parameter name="offset samples" />
365 <parameter name="BEEP" />
366 <parameter name="s=silence" />
369 <para>Record to a file until a given dtmf digit in the sequence is received.
370 Returns <literal>-1</literal> on hangup or error. The format will specify what kind of file
371 will be recorded. The <replaceable>timeout</replaceable> is the maximum record time in
372 milliseconds, or <literal>-1</literal> for no <replaceable>timeout</replaceable>.
373 <replaceable>offset samples</replaceable> is optional, and, if provided, will seek
374 to the offset without exceeding the end of the file. <replaceable>silence</replaceable> is
375 the number of seconds of silence allowed before the function returns despite the
376 lack of dtmf digits or reaching <replaceable>timeout</replaceable>. <replaceable>silence</replaceable>
377 value must be preceded by <literal>s=</literal> and is also optional.</para>
380 <agi name="say alpha" language="en_US">
382 Says a given character string.
385 <parameter name="number" required="true" />
386 <parameter name="escape_digits" required="true" />
389 <para>Say a given character string, returning early if any of the given DTMF digits
390 are received on the channel. Returns <literal>0</literal> if playback completes
391 without a digit being pressed, or the ASCII numerical value of the digit if one
392 was pressed or <literal>-1</literal> on error/hangup.</para>
395 <agi name="say digits" language="en_US">
397 Says a given digit string.
400 <parameter name="number" required="true" />
401 <parameter name="escape_digits" required="true" />
404 <para>Say a given digit string, returning early if any of the given DTMF digits
405 are received on the channel. Returns <literal>0</literal> if playback completes
406 without a digit being pressed, or the ASCII numerical value of the digit if one
407 was pressed or <literal>-1</literal> on error/hangup.</para>
410 <agi name="say number" language="en_US">
415 <parameter name="number" required="true" />
416 <parameter name="escape_digits" required="true" />
417 <parameter name="gender" />
420 <para>Say a given number, returning early if any of the given DTMF digits
421 are received on the channel. Returns <literal>0</literal> if playback
422 completes without a digit being pressed, or the ASCII numerical value of
423 the digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
426 <agi name="say phonetic" language="en_US">
428 Says a given character string with phonetics.
431 <parameter name="string" required="true" />
432 <parameter name="escape_digits" required="true" />
435 <para>Say a given character string with phonetics, returning early if any of the
436 given DTMF digits are received on the channel. Returns <literal>0</literal> if
437 playback completes without a digit pressed, the ASCII numerical value of the digit
438 if one was pressed, or <literal>-1</literal> on error/hangup.</para>
441 <agi name="say date" language="en_US">
446 <parameter name="date" required="true">
447 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
448 Coordinated Universal Time (UTC).</para>
450 <parameter name="escape_digits" required="true" />
453 <para>Say a given date, returning early if any of the given DTMF digits are
454 received on the channel. Returns <literal>0</literal> if playback
455 completes without a digit being pressed, or the ASCII numerical value of the
456 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
459 <agi name="say time" language="en_US">
464 <parameter name="time" required="true">
465 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
466 Coordinated Universal Time (UTC).</para>
468 <parameter name="escape_digits" required="true" />
471 <para>Say a given time, returning early if any of the given DTMF digits are
472 received on the channel. Returns <literal>0</literal> if playback completes
473 without a digit being pressed, or the ASCII numerical value of the digit if
474 one was pressed or <literal>-1</literal> on error/hangup.</para>
477 <agi name="say datetime" language="en_US">
479 Says a given time as specified by the format given.
482 <parameter name="time" required="true">
483 <para>Is number of seconds elapsed since 00:00:00
484 on January 1, 1970, Coordinated Universal Time (UTC)</para>
486 <parameter name="escape_digits" required="true" />
487 <parameter name="format">
488 <para>Is the format the time should be said in. See
489 <filename>voicemail.conf</filename> (defaults to <literal>ABdY
490 'digits/at' IMp</literal>).</para>
492 <parameter name="timezone">
493 <para>Acceptable values can be found in <filename>/usr/share/zoneinfo</filename>
494 Defaults to machine default.</para>
498 <para>Say a given time, returning early if any of the given DTMF digits are
499 received on the channel. Returns <literal>0</literal> if playback
500 completes without a digit being pressed, or the ASCII numerical value of the
501 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
504 <agi name="send image" language="en_US">
506 Sends images to channels supporting it.
509 <parameter name="image" required="true" />
512 <para>Sends the given image on a channel. Most channels do not support the
513 transmission of images. Returns <literal>0</literal> if image is sent, or if
514 the channel does not support image transmission. Returns <literal>-1</literal>
515 only on error/hangup. Image names should not include extensions.</para>
518 <agi name="send text" language="en_US">
520 Sends text to channels supporting it.
523 <parameter name="text to send" required="true">
524 <para>Text consisting of greater than one word should be placed
525 in quotes since the command only accepts a single argument.</para>
529 <para>Sends the given text on a channel. Most channels do not support the
530 transmission of text. Returns <literal>0</literal> if text is sent, or if the
531 channel does not support text transmission. Returns <literal>-1</literal> only
532 on error/hangup.</para>
535 <agi name="set autohangup" language="en_US">
537 Autohangup channel in some time.
540 <parameter name="time" required="true" />
543 <para>Cause the channel to automatically hangup at <replaceable>time</replaceable>
544 seconds in the future. Of course it can be hungup before then as well. Setting to
545 <literal>0</literal> will cause the autohangup feature to be disabled on this channel.</para>
548 <agi name="set callerid" language="en_US">
550 Sets callerid for the current channel.
553 <parameter name="number" required="true" />
556 <para>Changes the callerid of the current channel.</para>
559 <agi name="set context" language="en_US">
561 Sets channel context.
564 <parameter name="desired context" required="true" />
567 <para>Sets the context for continuation upon exiting the application.</para>
570 <agi name="set extension" language="en_US">
572 Changes channel extension.
575 <parameter name="new extension" required="true" />
578 <para>Changes the extension for continuation upon exiting the application.</para>
581 <agi name="set music" language="en_US">
583 Enable/Disable Music on hold generator
586 <parameter required="true">
589 <parameter name="on" literal="true" required="true" />
592 <parameter name="off" literal="true" required="true" />
596 <parameter name="class" required="true" />
599 <para>Enables/Disables the music on hold generator. If <replaceable>class</replaceable>
600 is not specified, then the <literal>default</literal> music on hold class will be
602 <para>Always returns <literal>0</literal>.</para>
605 <agi name="set priority" language="en_US">
607 Set channel dialplan priority.
610 <parameter name="priority" required="true" />
613 <para>Changes the priority for continuation upon exiting the application.
614 The priority must be a valid priority or label.</para>
617 <agi name="set variable" language="en_US">
619 Sets a channel variable.
622 <parameter name="variablename" required="true" />
623 <parameter name="value" required="true" />
626 <para>Sets a variable to the current channel.</para>
629 <agi name="stream file" language="en_US">
631 Sends audio file on channel.
634 <parameter name="filename" required="true">
635 <para>File name to play. The file extension must not be
636 included in the <replaceable>filename</replaceable>.</para>
638 <parameter name="escape_digits" required="true">
639 <para>Use double quotes for the digits if you wish none to be
642 <parameter name="sample offset">
643 <para>If sample offset is provided then the audio will seek to sample
644 offset before play starts.</para>
648 <para>Send the given file, allowing playback to be interrupted by the given
649 digits, if any. Returns <literal>0</literal> if playback completes without a digit
650 being pressed, or the ASCII numerical value of the digit if one was pressed,
651 or <literal>-1</literal> on error or if the channel was disconnected.</para>
654 <ref type="agi">control stream file</ref>
657 <agi name="tdd mode" language="en_US">
659 Toggles TDD mode (for the deaf).
662 <parameter name="boolean" required="true">
670 <para>Enable/Disable TDD transmission/reception on a channel. Returns <literal>1</literal> if
671 successful, or <literal>0</literal> if channel is not TDD-capable.</para>
674 <agi name="verbose" language="en_US">
676 Logs a message to the asterisk verbose log.
679 <parameter name="message" required="true" />
680 <parameter name="level" required="true" />
683 <para>Sends <replaceable>message</replaceable> to the console via verbose
684 message system. <replaceable>level</replaceable> is the verbose level (1-4).
685 Always returns <literal>1</literal></para>
688 <agi name="wait for digit" language="en_US">
690 Waits for a digit to be pressed.
693 <parameter name="timeout" required="true" />
696 <para>Waits up to <replaceable>timeout</replaceable> milliseconds for channel to
697 receive a DTMF digit. Returns <literal>-1</literal> on channel failure, <literal>0</literal>
698 if no digit is received in the timeout, or the numerical value of the ascii of the digit if
699 one is received. Use <literal>-1</literal> for the <replaceable>timeout</replaceable> value if
700 you desire the call to block indefinitely.</para>
703 <agi name="speech create" language="en_US">
705 Creates a speech object.
708 <parameter name="engine" required="true" />
711 <para>Create a speech object to be used by the other Speech AGI commands.</para>
714 <agi name="speech set" language="en_US">
716 Sets a speech engine setting.
719 <parameter name="name" required="true" />
720 <parameter name="value" required="true" />
723 <para>Set an engine-specific setting.</para>
726 <agi name="speech destroy" language="en_US">
728 Destroys a speech object.
733 <para>Destroy the speech object created by <literal>SPEECH CREATE</literal>.</para>
736 <ref type="agi">speech create</ref>
739 <agi name="speech load grammar" language="en_US">
744 <parameter name="grammar name" required="true" />
745 <parameter name="path to grammar" required="true" />
748 <para>Loads the specified grammar as the specified name.</para>
751 <agi name="speech unload grammar" language="en_US">
756 <parameter name="grammar name" required="true" />
759 <para>Unloads the specified grammar.</para>
762 <agi name="speech activate grammar" language="en_US">
767 <parameter name="grammar name" required="true" />
770 <para>Activates the specified grammar on the speech object.</para>
773 <agi name="speech deactivate grammar" language="en_US">
775 Deactivates a grammar.
778 <parameter name="grammar name" required="true" />
781 <para>Deactivates the specified grammar on the speech object.</para>
784 <agi name="speech recognize" language="en_US">
789 <parameter name="prompt" required="true" />
790 <parameter name="timeout" required="true" />
791 <parameter name="offset" />
794 <para>Plays back given <replaceable>prompt</replaceable> while listening for
795 speech and dtmf.</para>
798 <application name="AGI" language="en_US">
800 Executes an AGI compliant application.
803 <parameter name="command" required="true" />
804 <parameter name="args">
805 <argument name="arg1" required="true" />
806 <argument name="arg2" multiple="yes" />
810 <para>Executes an Asterisk Gateway Interface compliant
811 program on a channel. AGI allows Asterisk to launch external programs written
812 in any language to control a telephony channel, play audio, read DTMF digits,
813 etc. by communicating with the AGI protocol on <emphasis>stdin</emphasis> and
814 <emphasis>stdout</emphasis>. As of <literal>1.6.0</literal>, this channel will
815 not stop dialplan execution on hangup inside of this application. Dialplan
816 execution will continue normally, even upon hangup until the AGI application
817 signals a desire to stop (either by exiting or, in the case of a net script, by
818 closing the connection). A locally executed AGI script will receive SIGHUP on
819 hangup from the channel except when using DeadAGI. A fast AGI server will
820 correspondingly receive a HANGUP inline with the command dialog. Both of theses
821 signals may be disabled by setting the <variable>AGISIGHUP</variable> channel
822 variable to <literal>no</literal> before executing the AGI application.
823 Alternatively, if you would like the AGI application to exit immediately
824 after a channel hangup is detected, set the <variable>AGIEXITONHANGUP</variable>
825 variable to <literal>yes</literal>.</para>
826 <para>Use the CLI command <literal>agi show commands</literal> to list available agi
828 <para>This application sets the following channel variable upon completion:</para>
830 <variable name="AGISTATUS">
831 <para>The status of the attempt to the run the AGI script
832 text string, one of:</para>
833 <value name="SUCCESS" />
834 <value name="FAILURE" />
835 <value name="NOTFOUND" />
836 <value name="HANGUP" />
841 <ref type="application">EAGI</ref>
842 <ref type="application">DeadAGI</ref>
845 <application name="EAGI" language="en_US">
847 Executes an EAGI compliant application.
850 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
851 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
854 <para>Using 'EAGI' provides enhanced AGI, with incoming audio available out of band
855 on file descriptor 3.</para>
856 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
857 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
860 <ref type="application">AGI</ref>
861 <ref type="application">DeadAGI</ref>
864 <application name="DeadAGI" language="en_US">
866 Executes AGI on a hungup channel.
869 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
870 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
873 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
874 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
877 <ref type="application">AGI</ref>
878 <ref type="application">EAGI</ref>
881 <manager name="AGI" language="en_US">
883 Add an AGI command to execute by Async AGI.
886 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
887 <parameter name="Channel" required="true">
888 <para>Channel that is currently in Async AGI.</para>
890 <parameter name="Command" required="true">
891 <para>Application to execute.</para>
893 <parameter name="CommandID">
894 <para>This will be sent back in CommandID header of AsyncAGI exec
895 event notification.</para>
899 <para>Add an AGI command to the execute queue of the channel in Async AGI.</para>
905 #define MAX_CMD_LEN 80
906 #define AGI_NANDFS_RETRY 3
907 #define AGI_BUF_LEN 2048
908 #define SRV_PREFIX "_agi._tcp."
910 static char *app = "AGI";
912 static char *eapp = "EAGI";
914 static char *deadapp = "DeadAGI";
916 static int agidebug = 0;
918 #define TONE_BLOCK_SIZE 200
920 /* Max time to connect to an AGI remote host */
921 #define MAX_AGI_CONNECT 2000
923 #define AGI_PORT 4573
925 /*! Special return code for "asyncagi break" command. */
926 #define ASYNC_AGI_BREAK 3
929 AGI_RESULT_FAILURE = -1,
931 AGI_RESULT_SUCCESS_FAST,
932 AGI_RESULT_SUCCESS_ASYNC,
937 static agi_command *find_command(const char * const cmds[], int exact);
939 AST_THREADSTORAGE(agi_buf);
940 #define AGI_BUF_INITSIZE 256
942 int AST_OPTIONAL_API_NAME(ast_agi_send)(int fd, struct ast_channel *chan, char *fmt, ...)
948 if (!(buf = ast_str_thread_get(&agi_buf, AGI_BUF_INITSIZE)))
952 res = ast_str_set_va(&buf, 0, fmt, ap);
956 ast_log(LOG_ERROR, "Out of memory\n");
962 ast_verbose("<%s>AGI Tx >> %s", ast_channel_name(chan), ast_str_buffer(buf));
964 ast_verbose("AGI Tx >> %s", ast_str_buffer(buf));
968 return ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
971 /* linked list of AGI commands ready to be executed by Async AGI */
975 AST_LIST_ENTRY(agi_cmd) entry;
978 static void free_agi_cmd(struct agi_cmd *cmd)
980 ast_free(cmd->cmd_buffer);
981 ast_free(cmd->cmd_id);
985 /* AGI datastore destructor */
986 static void agi_destroy_commands_cb(void *data)
989 AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
990 AST_LIST_LOCK(chan_cmds);
991 while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
994 AST_LIST_UNLOCK(chan_cmds);
995 AST_LIST_HEAD_DESTROY(chan_cmds);
999 /* channel datastore to keep the queue of AGI commands in the channel */
1000 static const struct ast_datastore_info agi_commands_datastore_info = {
1002 .destroy = agi_destroy_commands_cb
1005 static struct agi_cmd *get_agi_cmd(struct ast_channel *chan)
1007 struct ast_datastore *store;
1008 struct agi_cmd *cmd;
1009 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1011 ast_channel_lock(chan);
1012 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1013 ast_channel_unlock(chan);
1015 ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
1016 ast_channel_name(chan));
1019 agi_commands = store->data;
1020 AST_LIST_LOCK(agi_commands);
1021 cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
1022 AST_LIST_UNLOCK(agi_commands);
1026 /* channel is locked when calling this one either from the CLI or manager thread */
1027 static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
1029 struct ast_datastore *store;
1030 struct agi_cmd *cmd;
1031 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1033 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1035 ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", ast_channel_name(chan));
1038 agi_commands = store->data;
1039 cmd = ast_calloc(1, sizeof(*cmd));
1043 cmd->cmd_buffer = ast_strdup(cmd_buff);
1044 if (!cmd->cmd_buffer) {
1048 cmd->cmd_id = ast_strdup(cmd_id);
1050 ast_free(cmd->cmd_buffer);
1054 AST_LIST_LOCK(agi_commands);
1055 AST_LIST_INSERT_TAIL(agi_commands, cmd, entry);
1056 AST_LIST_UNLOCK(agi_commands);
1060 static int add_to_agi(struct ast_channel *chan)
1062 struct ast_datastore *datastore;
1063 AST_LIST_HEAD(, agi_cmd) *agi_cmds_list;
1065 /* check if already on AGI */
1066 ast_channel_lock(chan);
1067 datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1068 ast_channel_unlock(chan);
1070 /* we already have an AGI datastore, let's just
1075 /* the channel has never been on Async AGI,
1076 let's allocate it's datastore */
1077 datastore = ast_datastore_alloc(&agi_commands_datastore_info, "AGI");
1081 agi_cmds_list = ast_calloc(1, sizeof(*agi_cmds_list));
1082 if (!agi_cmds_list) {
1083 ast_log(LOG_ERROR, "Unable to allocate Async AGI commands list.\n");
1084 ast_datastore_free(datastore);
1087 datastore->data = agi_cmds_list;
1088 AST_LIST_HEAD_INIT(agi_cmds_list);
1089 ast_channel_lock(chan);
1090 ast_channel_datastore_add(chan, datastore);
1091 ast_channel_unlock(chan);
1096 * \brief CLI command to add applications to execute in Async AGI
1101 * \retval CLI_SUCCESS on success
1102 * \retval NULL when init or tab completion is used
1104 static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1106 struct ast_channel *chan;
1109 e->command = "agi exec";
1110 e->usage = "Usage: agi exec <channel name> <app and arguments> [id]\n"
1111 " Add AGI command to the execute queue of the specified channel in Async AGI\n";
1115 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
1120 return CLI_SHOWUSAGE;
1123 if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
1124 ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
1128 ast_channel_lock(chan);
1130 if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
1131 ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", ast_channel_name(chan));
1132 ast_channel_unlock(chan);
1133 chan = ast_channel_unref(chan);
1137 ast_debug(1, "Added AGI command to channel %s queue\n", ast_channel_name(chan));
1139 ast_channel_unlock(chan);
1140 chan = ast_channel_unref(chan);
1146 * \brief Add a new command to execute by the Async AGI application
1150 * It will append the application to the specified channel's queue
1151 * if the channel is not inside Async AGI application it will return an error
1152 * \retval 0 on success or incorrect use
1153 * \retval 1 on failure to add the command ( most likely because the channel
1154 * is not in Async AGI loop )
1156 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
1158 const char *channel = astman_get_header(m, "Channel");
1159 const char *cmdbuff = astman_get_header(m, "Command");
1160 const char *cmdid = astman_get_header(m, "CommandID");
1161 struct ast_channel *chan;
1164 if (ast_strlen_zero(channel) || ast_strlen_zero(cmdbuff)) {
1165 astman_send_error(s, m, "Both, Channel and Command are *required*");
1169 if (!(chan = ast_channel_get_by_name(channel))) {
1170 snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
1171 astman_send_error(s, m, buf);
1175 ast_channel_lock(chan);
1177 if (add_agi_cmd(chan, cmdbuff, cmdid)) {
1178 snprintf(buf, sizeof(buf), "Failed to add AGI command to channel %s queue", ast_channel_name(chan));
1179 astman_send_error(s, m, buf);
1180 ast_channel_unlock(chan);
1181 chan = ast_channel_unref(chan);
1185 ast_channel_unlock(chan);
1186 chan = ast_channel_unref(chan);
1188 astman_send_ack(s, m, "Added AGI command to queue");
1193 static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
1194 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
1198 * \brief Read and handle a channel frame for Async AGI.
1200 * \param chan Channel to read a frame from.
1202 * \retval AGI_RESULT_SUCCESS on success.
1203 * \retval AGI_RESULT_HANGUP on hangup.
1204 * \retval AGI_RESULT_FAILURE on error.
1206 static enum agi_result async_agi_read_frame(struct ast_channel *chan)
1208 struct ast_frame *f;
1212 ast_debug(3, "No frame read on channel %s, going out ...\n", ast_channel_name(chan));
1213 return AGI_RESULT_HANGUP;
1215 if (f->frametype == AST_FRAME_CONTROL) {
1217 * Is there any other frame we should care about besides
1218 * AST_CONTROL_HANGUP?
1220 switch (f->subclass.integer) {
1221 case AST_CONTROL_HANGUP:
1222 ast_debug(3, "Got HANGUP frame on channel %s, going out ...\n", ast_channel_name(chan));
1224 return AGI_RESULT_HANGUP;
1231 return AGI_RESULT_SUCCESS;
1234 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
1236 /* This buffer sizes might cause truncation if the AGI command writes more data
1237 than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
1238 that writes a response larger than 1024 bytes?, I don't think so, most of
1239 them are just result=blah stuff. However probably if GET VARIABLE is called
1240 and the variable has large amount of data, that could be a problem. We could
1241 make this buffers dynamic, but let's leave that as a second step.
1243 AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
1244 number. Some characters of AGI buf will be url encoded to be sent to manager
1245 clients. An URL encoded character will take 3 bytes, but again, to cause
1246 truncation more than about 70% of the AGI buffer should be URL encoded for
1247 that to happen. Not likely at all.
1249 On the other hand. I wonder if read() could eventually return less data than
1250 the amount already available in the pipe? If so, how to deal with that?
1251 So far, my tests on Linux have not had any problems.
1253 #define AGI_BUF_SIZE 1024
1254 #define AMI_BUF_SIZE 2048
1255 enum agi_result cmd_status;
1256 struct agi_cmd *cmd;
1261 char agi_buffer[AGI_BUF_SIZE + 1];
1262 char ami_buffer[AMI_BUF_SIZE];
1263 enum agi_result returnstatus = AGI_RESULT_SUCCESS;
1267 ast_log(LOG_WARNING, "Async AGI does not support Enhanced AGI yet\n");
1268 return AGI_RESULT_FAILURE;
1271 /* add AsyncAGI datastore to the channel */
1272 if (add_to_agi(chan)) {
1273 ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", ast_channel_name(chan));
1274 return AGI_RESULT_FAILURE;
1277 /* this pipe allows us to create a "fake" AGI struct to use
1281 ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
1283 * Intentionally do not remove the datastore added with
1284 * add_to_agi() the from channel. It will be removed when the
1285 * channel is hung up anyway.
1287 return AGI_RESULT_FAILURE;
1290 /* handlers will get the pipe write fd and we read the AGI responses
1291 from the pipe read fd */
1292 async_agi.fd = fds[1];
1293 async_agi.ctrl = fds[1];
1294 async_agi.audio = -1; /* no audio support */
1296 async_agi.speech = NULL;
1298 /* notify possible manager users of a new channel ready to
1300 setup_env(chan, "async", fds[1], 0, 0, NULL);
1301 /* read the environment */
1302 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1304 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
1305 ast_channel_name(chan));
1306 returnstatus = AGI_RESULT_FAILURE;
1307 goto async_agi_abort;
1309 agi_buffer[res] = '\0';
1310 /* encode it and send it thru the manager so whoever is going to take
1311 care of AGI commands on this channel can decide which AGI commands
1312 to execute based on the setup info */
1313 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1314 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1315 "SubEvent: Start\r\n"
1317 "Env: %s\r\n", ast_channel_name(chan), ami_buffer);
1318 hungup = ast_check_hangup(chan);
1321 * Process as many commands as we can. Commands are added via
1322 * the manager or the cli threads.
1324 while (!hungup && (cmd = get_agi_cmd(chan))) {
1325 /* OK, we have a command, let's call the command handler. */
1326 cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
1329 * The command handler must have written to our fake AGI struct
1330 * fd (the pipe), let's read the response.
1332 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1334 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
1335 ast_channel_name(chan));
1337 returnstatus = AGI_RESULT_FAILURE;
1338 goto async_agi_done;
1341 * We have a response, let's send the response thru the manager.
1342 * Include the CommandID if it was specified when the command
1345 agi_buffer[res] = '\0';
1346 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1347 if (ast_strlen_zero(cmd->cmd_id)) {
1348 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1349 "SubEvent: Exec\r\n"
1351 "Result: %s\r\n", ast_channel_name(chan), ami_buffer);
1353 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1354 "SubEvent: Exec\r\n"
1357 "Result: %s\r\n", ast_channel_name(chan), cmd->cmd_id, ami_buffer);
1362 * Check the command status to determine if we should continue
1363 * executing more commands.
1365 hungup = ast_check_hangup(chan);
1366 switch (cmd_status) {
1367 case AGI_RESULT_FAILURE:
1369 /* The failure was not because of a hangup. */
1370 returnstatus = AGI_RESULT_FAILURE;
1371 goto async_agi_done;
1374 case AGI_RESULT_SUCCESS_ASYNC:
1375 /* Only the "asyncagi break" command does this. */
1376 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1377 goto async_agi_done;
1384 /* Wait a bit for a frame to read or to poll for a new command. */
1385 res = ast_waitfor(chan, timeout);
1387 ast_debug(1, "ast_waitfor returned <= 0 on chan %s\n", ast_channel_name(chan));
1388 returnstatus = AGI_RESULT_FAILURE;
1393 * Read the channel control queue until it is dry so we can
1400 cmd_status = async_agi_read_frame(chan);
1401 if (cmd_status != AGI_RESULT_SUCCESS) {
1402 returnstatus = cmd_status;
1403 goto async_agi_done;
1405 hungup = ast_check_hangup(chan);
1408 hungup = ast_check_hangup(chan);
1413 if (async_agi.speech) {
1414 ast_speech_destroy(async_agi.speech);
1416 /* notify manager users this channel cannot be
1417 controlled anymore by Async AGI */
1418 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1420 "Channel: %s\r\n", ast_channel_name(chan));
1423 /* close the pipe */
1428 * Intentionally do not remove the datastore added with
1429 * add_to_agi() the from channel. There might be commands still
1430 * in the queue or in-flight to us and AsyncAGI may get called
1431 * again. The datastore destructor will be called on channel
1432 * destruction anyway.
1435 if (returnstatus == AGI_RESULT_SUCCESS) {
1436 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1438 return returnstatus;
1444 /* launch_netscript: The fastagi handler.
1445 FastAGI defaults to port 4573 */
1446 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
1448 int s, flags, res, port = AGI_PORT;
1449 struct pollfd pfds[1];
1450 char *host, *c, *script;
1451 struct sockaddr_in addr_in;
1453 struct ast_hostent ahp;
1455 /* agiurl is "agi://host.domain[:port][/script/name]" */
1456 host = ast_strdupa(agiurl + 6); /* Remove agi:// */
1457 /* Strip off any script name */
1458 if ((script = strchr(host, '/'))) {
1464 if ((c = strchr(host, ':'))) {
1468 if (!(hp = ast_gethostbyname(host, &ahp))) {
1469 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
1470 return AGI_RESULT_FAILURE;
1472 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1473 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1474 return AGI_RESULT_FAILURE;
1476 if ((flags = fcntl(s, F_GETFL)) < 0) {
1477 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno));
1479 return AGI_RESULT_FAILURE;
1481 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
1482 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno));
1484 return AGI_RESULT_FAILURE;
1486 memset(&addr_in, 0, sizeof(addr_in));
1487 addr_in.sin_family = AF_INET;
1488 addr_in.sin_port = htons(port);
1489 memcpy(&addr_in.sin_addr, hp->h_addr, sizeof(addr_in.sin_addr));
1490 if (connect(s, (struct sockaddr *)&addr_in, sizeof(addr_in)) && (errno != EINPROGRESS)) {
1491 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno));
1493 return AGI_RESULT_FAILURE;
1497 pfds[0].events = POLLOUT;
1498 while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
1499 if (errno != EINTR) {
1501 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
1502 agiurl, MAX_AGI_CONNECT);
1504 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1506 return AGI_RESULT_FAILURE;
1510 if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
1511 if (errno != EINTR) {
1512 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1514 return AGI_RESULT_FAILURE;
1518 /* If we have a script parameter, relay it to the fastagi server */
1519 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
1520 if (!ast_strlen_zero(script))
1521 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
1523 ast_debug(4, "Wow, connected!\n");
1526 return AGI_RESULT_SUCCESS_FAST;
1531 * \brief The HA fastagi handler.
1532 * \param agiurl The request URL as passed to Agi() in the dial plan
1533 * \param argv The parameters after the URL passed to Agi() in the dial plan
1534 * \param fds Input/output file descriptors
1536 * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
1537 * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
1538 * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
1539 * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
1542 * This function parses the URI, resolves the SRV service name, forms new URIs
1543 * with the results of the DNS lookup, and then calls launch_netscript on the
1544 * new URIs until one succeeds.
1546 * \return the result of the AGI operation.
1548 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
1550 char *host, *script;
1551 enum agi_result result;
1552 struct srv_context *context = NULL;
1555 char resolved_uri[1024];
1556 const char *srvhost;
1557 unsigned short srvport;
1559 /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
1560 if (!(host = ast_strdupa(agiurl + 7))) { /* Remove hagi:// */
1561 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
1562 return AGI_RESULT_FAILURE;
1565 /* Strip off any script name */
1566 if ((script = strchr(host, '/'))) {
1572 if (strchr(host, ':')) {
1573 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
1574 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
1577 snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
1579 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
1580 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
1581 result = launch_netscript(resolved_uri, argv, fds);
1582 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
1583 ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
1585 /* The script launched so we must cleanup the context. */
1586 ast_srv_cleanup(&context);
1591 * The DNS SRV lookup failed or we ran out of servers to check.
1592 * ast_srv_lookup() has already cleaned up the context for us.
1595 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
1598 return AGI_RESULT_FAILURE;
1601 static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
1604 int pid, toast[2], fromast[2], audio[2], res;
1607 if (!strncasecmp(script, "agi://", 6)) {
1608 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1610 if (!strncasecmp(script, "hagi://", 7)) {
1611 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1613 if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
1614 return launch_asyncagi(chan, argv, efd);
1617 if (script[0] != '/') {
1618 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
1622 /* Before even trying let's see if the file actually exists */
1623 if (stat(script, &st)) {
1624 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
1625 return AGI_RESULT_NOTFOUND;
1629 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
1630 return AGI_RESULT_FAILURE;
1632 if (pipe(fromast)) {
1633 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
1636 return AGI_RESULT_FAILURE;
1640 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
1645 return AGI_RESULT_FAILURE;
1647 res = fcntl(audio[1], F_GETFL);
1649 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
1651 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
1658 return AGI_RESULT_FAILURE;
1662 if ((pid = ast_safe_fork(1)) < 0) {
1663 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
1664 return AGI_RESULT_FAILURE;
1667 /* Pass paths to AGI via environmental variables */
1668 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
1669 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
1670 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
1671 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
1672 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
1673 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
1674 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
1675 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
1676 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
1677 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
1678 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
1680 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
1681 ast_set_priority(0);
1683 /* Redirect stdin and out, provide enhanced audio channel if desired */
1684 dup2(fromast[0], STDIN_FILENO);
1685 dup2(toast[1], STDOUT_FILENO);
1687 dup2(audio[0], STDERR_FILENO + 1);
1689 close(STDERR_FILENO + 1);
1691 /* Close everything but stdin/out/error */
1692 ast_close_fds_above_n(STDERR_FILENO + 1);
1694 /* Execute script */
1695 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
1696 execv(script, argv);
1697 /* Can't use ast_log since FD's are closed */
1698 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
1699 /* Special case to set status of AGI to failure */
1700 fprintf(stdout, "failure\n");
1704 ast_verb(3, "Launched AGI Script %s\n", script);
1706 fds[1] = fromast[1];
1709 /* close what we're not using in the parent */
1717 return AGI_RESULT_SUCCESS;
1720 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
1724 /* Print initial environment, with agi_request always being the first
1726 ast_agi_send(fd, chan, "agi_request: %s\n", request);
1727 ast_agi_send(fd, chan, "agi_channel: %s\n", ast_channel_name(chan));
1728 ast_agi_send(fd, chan, "agi_language: %s\n", ast_channel_language(chan));
1729 ast_agi_send(fd, chan, "agi_type: %s\n", chan->tech->type);
1730 ast_agi_send(fd, chan, "agi_uniqueid: %s\n", ast_channel_uniqueid(chan));
1731 ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
1734 ast_agi_send(fd, chan, "agi_callerid: %s\n",
1735 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "unknown"));
1736 ast_agi_send(fd, chan, "agi_calleridname: %s\n",
1737 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "unknown"));
1738 ast_agi_send(fd, chan, "agi_callingpres: %d\n",
1739 ast_party_id_presentation(&chan->caller.id));
1740 ast_agi_send(fd, chan, "agi_callingani2: %d\n", chan->caller.ani2);
1741 ast_agi_send(fd, chan, "agi_callington: %d\n", chan->caller.id.number.plan);
1742 ast_agi_send(fd, chan, "agi_callingtns: %d\n", chan->dialed.transit_network_select);
1743 ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(chan->dialed.number.str, "unknown"));
1744 ast_agi_send(fd, chan, "agi_rdnis: %s\n",
1745 S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "unknown"));
1747 /* Context information */
1748 ast_agi_send(fd, chan, "agi_context: %s\n", ast_channel_context(chan));
1749 ast_agi_send(fd, chan, "agi_extension: %s\n", ast_channel_exten(chan));
1750 ast_agi_send(fd, chan, "agi_priority: %d\n", chan->priority);
1751 ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
1753 /* User information */
1754 ast_agi_send(fd, chan, "agi_accountcode: %s\n", ast_channel_accountcode(chan) ? ast_channel_accountcode(chan) : "");
1755 ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
1757 /* Send any parameters to the fastagi server that have been passed via the agi application */
1758 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
1759 for(count = 1; count < argc; count++)
1760 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
1762 /* End with empty return */
1763 ast_agi_send(fd, chan, "\n");
1766 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1770 /* Answer the channel */
1771 if (chan->_state != AST_STATE_UP)
1772 res = ast_answer(chan);
1774 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1775 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1778 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1780 ast_agi_send(agi->fd, chan, "200 result=0\n");
1781 return ASYNC_AGI_BREAK;
1784 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1789 return RESULT_SHOWUSAGE;
1790 if (sscanf(argv[3], "%30d", &to) != 1)
1791 return RESULT_SHOWUSAGE;
1792 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
1793 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1794 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1797 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1802 return RESULT_SHOWUSAGE;
1804 /* At the moment, the parser (perhaps broken) returns with
1805 the last argument PLUS the newline at the end of the input
1806 buffer. This probably needs to be fixed, but I wont do that
1807 because other stuff may break as a result. The right way
1808 would probably be to strip off the trailing newline before
1809 parsing, then here, add a newline at the end of the string
1810 before sending it to ast_sendtext --DUDE */
1811 res = ast_sendtext(chan, argv[2]);
1812 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1813 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1816 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1821 return RESULT_SHOWUSAGE;
1823 res = ast_recvchar(chan,atoi(argv[2]));
1825 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
1826 return RESULT_SUCCESS;
1829 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1830 return RESULT_SUCCESS;
1832 ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
1833 return RESULT_FAILURE;
1836 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1841 return RESULT_SHOWUSAGE;
1843 buf = ast_recvtext(chan, atoi(argv[2]));
1845 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
1848 ast_agi_send(agi->fd, chan, "200 result=-1\n");
1850 return RESULT_SUCCESS;
1853 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1858 return RESULT_SHOWUSAGE;
1860 if (!strncasecmp(argv[2],"on",2)) {
1865 if (!strncasecmp(argv[2],"mate",4)) {
1868 if (!strncasecmp(argv[2],"tdd",3)) {
1871 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
1873 /* Set channel option failed */
1874 ast_agi_send(agi->fd, chan, "200 result=0\n");
1876 ast_agi_send(agi->fd, chan, "200 result=1\n");
1878 return RESULT_SUCCESS;
1881 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1886 return RESULT_SHOWUSAGE;
1889 res = ast_send_image(chan, argv[2]);
1890 if (!ast_check_hangup(chan)) {
1893 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1894 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1897 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1899 int res = 0, skipms = 3000;
1900 const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL; /* Default values */
1902 if (argc < 5 || argc > 9) {
1903 return RESULT_SHOWUSAGE;
1906 if (!ast_strlen_zero(argv[4])) {
1910 if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
1911 return RESULT_SHOWUSAGE;
1914 if (argc > 6 && !ast_strlen_zero(argv[6])) {
1918 if (argc > 7 && !ast_strlen_zero(argv[7])) {
1922 if (argc > 8 && !ast_strlen_zero(argv[8])) {
1926 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
1928 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1930 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1933 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1936 struct ast_filestream *fs, *vfs;
1937 long sample_offset = 0, max_length;
1938 const char *edigits = "";
1940 if (argc < 4 || argc > 5) {
1941 return RESULT_SHOWUSAGE;
1948 if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1)) {
1949 return RESULT_SHOWUSAGE;
1952 if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
1953 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
1954 return RESULT_SUCCESS;
1957 if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan)))) {
1958 ast_debug(1, "Ooh, found a video stream, too\n");
1961 ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
1963 ast_seekstream(fs, 0, SEEK_END);
1964 max_length = ast_tellstream(fs);
1965 ast_seekstream(fs, sample_offset, SEEK_SET);
1966 res = ast_applystream(chan, fs);
1968 ast_applystream(chan, vfs);
1972 ast_playstream(vfs);
1975 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
1976 /* this is to check for if ast_waitstream closed the stream, we probably are at
1977 * the end of the stream, return that amount, else check for the amount */
1978 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
1979 ast_stopstream(chan);
1981 /* Stop this command, don't print a result line, as there is a new command */
1982 return RESULT_SUCCESS;
1984 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
1985 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1988 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
1989 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1992 struct ast_filestream *fs, *vfs;
1993 long sample_offset = 0, max_length;
1995 const char *edigits = "";
1997 if ( argc < 4 || argc > 5 )
1998 return RESULT_SHOWUSAGE;
2004 timeout = atoi(argv[4]);
2005 else if (chan->pbx->dtimeoutms) {
2006 /* by default dtimeout is set to 5sec */
2007 timeout = chan->pbx->dtimeoutms; /* in msec */
2010 if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2011 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2012 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2013 return RESULT_SUCCESS;
2016 if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan))))
2017 ast_debug(1, "Ooh, found a video stream, too\n");
2019 ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2021 ast_seekstream(fs, 0, SEEK_END);
2022 max_length = ast_tellstream(fs);
2023 ast_seekstream(fs, sample_offset, SEEK_SET);
2024 res = ast_applystream(chan, fs);
2026 ast_applystream(chan, vfs);
2029 ast_playstream(vfs);
2031 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2032 /* this is to check for if ast_waitstream closed the stream, we probably are at
2033 * the end of the stream, return that amount, else check for the amount */
2034 sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
2035 ast_stopstream(chan);
2037 /* Stop this command, don't print a result line, as there is a new command */
2038 return RESULT_SUCCESS;
2041 /* If the user didnt press a key, wait for digitTimeout*/
2043 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2044 /* Make sure the new result is in the escape digits of the GET OPTION */
2045 if ( !strchr(edigits,res) )
2049 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2050 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2056 /*! \brief Say number in various language syntaxes */
2057 /* While waiting, we're sending a NULL. */
2058 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2062 if (argc < 4 || argc > 5)
2063 return RESULT_SHOWUSAGE;
2064 if (sscanf(argv[2], "%30d", &num) != 1)
2065 return RESULT_SHOWUSAGE;
2066 res = ast_say_number_full(chan, num, argv[3], ast_channel_language(chan), argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2068 return RESULT_SUCCESS;
2069 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2070 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2073 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2078 return RESULT_SHOWUSAGE;
2079 if (sscanf(argv[2], "%30d", &num) != 1)
2080 return RESULT_SHOWUSAGE;
2082 res = ast_say_digit_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2083 if (res == 1) /* New command */
2084 return RESULT_SUCCESS;
2085 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2086 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2089 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2094 return RESULT_SHOWUSAGE;
2096 res = ast_say_character_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_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2108 return RESULT_SHOWUSAGE;
2109 if (sscanf(argv[2], "%30d", &num) != 1)
2110 return RESULT_SHOWUSAGE;
2111 res = ast_say_date(chan, num, argv[3], ast_channel_language(chan));
2113 return RESULT_SUCCESS;
2114 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2115 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2118 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2123 return RESULT_SHOWUSAGE;
2124 if (sscanf(argv[2], "%30d", &num) != 1)
2125 return RESULT_SHOWUSAGE;
2126 res = ast_say_time(chan, num, argv[3], ast_channel_language(chan));
2128 return RESULT_SUCCESS;
2129 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2130 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2133 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2137 const char *format, *zone = NULL;
2140 return RESULT_SHOWUSAGE;
2145 /* XXX this doesn't belong here, but in the 'say' module */
2146 if (!strcasecmp(ast_channel_language(chan), "de")) {
2147 format = "A dBY HMS";
2149 format = "ABdY 'digits/at' IMp";
2153 if (argc > 5 && !ast_strlen_zero(argv[5]))
2156 if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2157 return RESULT_SHOWUSAGE;
2159 res = ast_say_date_with_format(chan, unixtime, argv[3], ast_channel_language(chan), format, zone);
2161 return RESULT_SUCCESS;
2163 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2164 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2167 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2172 return RESULT_SHOWUSAGE;
2174 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2175 if (res == 1) /* New command */
2176 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_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2183 int res, max, timeout;
2187 return RESULT_SHOWUSAGE;
2189 timeout = atoi(argv[3]);
2193 max = atoi(argv[4]);
2196 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2197 if (res == 2) /* New command */
2198 return RESULT_SUCCESS;
2200 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2202 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2204 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2205 return RESULT_SUCCESS;
2208 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2212 return RESULT_SHOWUSAGE;
2213 ast_channel_context_set(chan, argv[2]);
2214 ast_agi_send(agi->fd, chan, "200 result=0\n");
2215 return RESULT_SUCCESS;
2218 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2221 return RESULT_SHOWUSAGE;
2222 ast_channel_exten_set(chan, argv[2]);
2223 ast_agi_send(agi->fd, chan, "200 result=0\n");
2224 return RESULT_SUCCESS;
2227 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2232 return RESULT_SHOWUSAGE;
2234 if (sscanf(argv[2], "%30d", &pri) != 1) {
2235 pri = ast_findlabel_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), argv[2],
2236 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
2238 return RESULT_SHOWUSAGE;
2241 ast_explicit_goto(chan, NULL, NULL, pri);
2242 ast_agi_send(agi->fd, chan, "200 result=0\n");
2243 return RESULT_SUCCESS;
2246 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2248 struct ast_filestream *fs;
2249 struct ast_frame *f;
2250 struct timeval start;
2251 long sample_offset = 0;
2255 struct ast_dsp *sildet=NULL; /* silence detector dsp */
2256 int totalsilence = 0;
2258 int silence = 0; /* amount of silence to allow */
2259 int gotsilence = 0; /* did we timeout for silence? */
2260 char *silencestr = NULL;
2261 struct ast_format rfmt;
2262 ast_format_clear(&rfmt);
2264 /* XXX EAGI FIXME XXX */
2267 return RESULT_SHOWUSAGE;
2268 if (sscanf(argv[5], "%30d", &ms) != 1)
2269 return RESULT_SHOWUSAGE;
2272 silencestr = strchr(argv[6],'s');
2273 if ((argc > 7) && (!silencestr))
2274 silencestr = strchr(argv[7],'s');
2275 if ((argc > 8) && (!silencestr))
2276 silencestr = strchr(argv[8],'s');
2279 if (strlen(silencestr) > 2) {
2280 if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2284 silence = atoi(silencestr);
2292 ast_format_copy(&rfmt, &chan->readformat);
2293 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2295 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2296 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2297 return RESULT_FAILURE;
2299 sildet = ast_dsp_new();
2301 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2302 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2303 return RESULT_FAILURE;
2305 ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
2308 /* backward compatibility, if no offset given, arg[6] would have been
2309 * caught below and taken to be a beep, else if it is a digit then it is a
2311 if ((argc >6) && (sscanf(argv[6], "%30ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
2312 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2314 if ((argc > 7) && (!strchr(argv[7], '=')))
2315 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2318 res = ast_waitstream(chan, argv[4]);
2320 ast_agi_send(agi->fd, chan, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
2322 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE);
2325 ast_agi_send(agi->fd, chan, "200 result=%d (writefile)\n", res);
2327 ast_dsp_free(sildet);
2328 return RESULT_FAILURE;
2331 /* Request a video update */
2332 ast_indicate(chan, AST_CONTROL_VIDUPDATE);
2335 ast_applystream(chan,fs);
2336 /* really should have checks */
2337 ast_seekstream(fs, sample_offset, SEEK_SET);
2338 ast_truncstream(fs);
2340 start = ast_tvnow();
2341 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
2342 res = ast_waitfor(chan, ms - ast_tvdiff_ms(ast_tvnow(), start));
2344 ast_closestream(fs);
2345 ast_agi_send(agi->fd, chan, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
2347 ast_dsp_free(sildet);
2348 return RESULT_FAILURE;
2352 ast_agi_send(agi->fd, chan, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
2353 ast_closestream(fs);
2355 ast_dsp_free(sildet);
2356 return RESULT_FAILURE;
2358 switch(f->frametype) {
2359 case AST_FRAME_DTMF:
2360 if (strchr(argv[4], f->subclass.integer)) {
2361 /* This is an interrupting chracter, so rewind to chop off any small
2362 amount of DTMF that may have been recorded
2364 ast_stream_rewind(fs, 200);
2365 ast_truncstream(fs);
2366 sample_offset = ast_tellstream(fs);
2367 ast_agi_send(agi->fd, chan, "200 result=%d (dtmf) endpos=%ld\n", f->subclass.integer, sample_offset);
2368 ast_closestream(fs);
2371 ast_dsp_free(sildet);
2372 return RESULT_SUCCESS;
2375 case AST_FRAME_VOICE:
2376 ast_writestream(fs, f);
2377 /* this is a safe place to check progress since we know that fs
2378 * is valid after a write, and it will then have our current
2380 sample_offset = ast_tellstream(fs);
2383 ast_dsp_silence(sildet, f, &dspsilence);
2385 totalsilence = dspsilence;
2389 if (totalsilence > silence) {
2390 /* Ended happily with silence */
2396 case AST_FRAME_VIDEO:
2397 ast_writestream(fs, f);
2399 /* Ignore all other frames */
2408 ast_stream_rewind(fs, silence-1000);
2409 ast_truncstream(fs);
2410 sample_offset = ast_tellstream(fs);
2412 ast_agi_send(agi->fd, chan, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
2413 ast_closestream(fs);
2417 res = ast_set_read_format(chan, &rfmt);
2419 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
2420 ast_dsp_free(sildet);
2423 return RESULT_SUCCESS;
2426 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2429 struct timeval whentohangup = { 0, 0 };
2432 return RESULT_SHOWUSAGE;
2433 if (sscanf(argv[2], "%30lf", &timeout) != 1)
2434 return RESULT_SHOWUSAGE;
2438 whentohangup.tv_sec = timeout;
2439 whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
2441 ast_channel_setwhentohangup_tv(chan, whentohangup);
2442 ast_agi_send(agi->fd, chan, "200 result=0\n");
2443 return RESULT_SUCCESS;
2446 static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2448 struct ast_channel *c;
2451 /* no argument: hangup the current channel */
2452 ast_set_hangupsource(chan, "dialplan/agi", 0);
2453 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
2454 ast_agi_send(agi->fd, chan, "200 result=1\n");
2455 return RESULT_SUCCESS;
2456 } else if (argc == 2) {
2457 /* one argument: look for info on the specified channel */
2458 if ((c = ast_channel_get_by_name(argv[1]))) {
2459 /* we have a matching channel */
2460 ast_set_hangupsource(c, "dialplan/agi", 0);
2461 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
2462 c = ast_channel_unref(c);
2463 ast_agi_send(agi->fd, chan, "200 result=1\n");
2464 return RESULT_SUCCESS;
2466 /* if we get this far no channel name matched the argument given */
2467 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2468 return RESULT_SUCCESS;
2470 return RESULT_SHOWUSAGE;
2474 static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2476 int res, workaround;
2477 struct ast_app *app_to_exec;
2480 return RESULT_SHOWUSAGE;
2482 ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
2484 if ((app_to_exec = pbx_findapp(argv[1]))) {
2485 if (!(workaround = ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS))) {
2486 ast_set_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
2488 if (ast_compat_res_agi && argc >= 3 && !ast_strlen_zero(argv[2])) {
2489 char *compat = alloca(strlen(argv[2]) * 2 + 1), *cptr;
2491 for (cptr = compat, vptr = argv[2]; *vptr; vptr++) {
2495 } else if (*vptr == '|') {
2502 res = pbx_exec(chan, app_to_exec, compat);
2504 res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
2507 ast_clear_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
2510 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
2513 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2515 /* Even though this is wrong, users are depending upon this result. */
2519 static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2522 char *l = NULL, *n = NULL;
2525 ast_copy_string(tmp, argv[2], sizeof(tmp));
2526 ast_callerid_parse(tmp, &n, &l);
2528 ast_shrink_phone_number(l);
2533 ast_set_callerid(chan, l, n, NULL);
2536 ast_agi_send(agi->fd, chan, "200 result=1\n");
2537 return RESULT_SUCCESS;
2540 static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2542 struct ast_channel *c;
2544 /* no argument: supply info on the current channel */
2545 ast_agi_send(agi->fd, chan, "200 result=%d\n", chan->_state);
2546 return RESULT_SUCCESS;
2547 } else if (argc == 3) {
2548 /* one argument: look for info on the specified channel */
2549 if ((c = ast_channel_get_by_name(argv[2]))) {
2550 ast_agi_send(agi->fd, chan, "200 result=%d\n", c->_state);
2551 c = ast_channel_unref(c);
2552 return RESULT_SUCCESS;
2554 /* if we get this far no channel name matched the argument given */
2555 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2556 return RESULT_SUCCESS;
2558 return RESULT_SHOWUSAGE;
2562 static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2565 pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
2567 ast_agi_send(agi->fd, chan, "200 result=1\n");
2568 return RESULT_SUCCESS;
2571 static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2574 char tempstr[1024] = "";
2577 return RESULT_SHOWUSAGE;
2579 /* check if we want to execute an ast_custom_function */
2580 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
2581 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
2583 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
2587 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ret);
2589 ast_agi_send(agi->fd, chan, "200 result=0\n");
2591 return RESULT_SUCCESS;
2594 static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2596 struct ast_channel *chan2 = NULL;
2598 if (argc != 4 && argc != 5) {
2599 return RESULT_SHOWUSAGE;
2603 chan2 = ast_channel_get_by_name(argv[4]);
2605 chan2 = ast_channel_ref(chan);
2609 struct ast_str *str = ast_str_create(16);
2611 ast_agi_send(agi->fd, chan, "200 result=0\n");
2612 return RESULT_SUCCESS;
2614 ast_str_substitute_variables(&str, 0, chan2, argv[3]);
2615 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str));
2618 ast_agi_send(agi->fd, chan, "200 result=0\n");
2622 chan2 = ast_channel_unref(chan2);
2625 return RESULT_SUCCESS;
2628 static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2633 return RESULT_SHOWUSAGE;
2636 sscanf(argv[2], "%30d", &level);
2638 ast_verb(level, "%s: %s\n", ast_channel_data(chan), argv[1]);
2640 ast_agi_send(agi->fd, chan, "200 result=1\n");
2642 return RESULT_SUCCESS;
2645 static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2648 struct ast_str *buf;
2651 return RESULT_SHOWUSAGE;
2653 if (!(buf = ast_str_create(16))) {
2654 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2655 return RESULT_SUCCESS;
2659 res = ast_db_get(argv[2], argv[3], ast_str_buffer(buf), ast_str_size(buf));
2660 ast_str_update(buf);
2661 if (ast_str_strlen(buf) < ast_str_size(buf) - 1) {
2664 if (ast_str_make_space(&buf, ast_str_size(buf) * 2)) {
2670 ast_agi_send(agi->fd, chan, "200 result=0\n");
2672 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(buf));
2675 return RESULT_SUCCESS;
2678 static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2683 return RESULT_SHOWUSAGE;
2684 res = ast_db_put(argv[2], argv[3], argv[4]);
2685 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2686 return RESULT_SUCCESS;
2689 static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2694 return RESULT_SHOWUSAGE;
2695 res = ast_db_del(argv[2], argv[3]);
2696 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2697 return RESULT_SUCCESS;
2700 static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2704 if ((argc < 3) || (argc > 4))
2705 return RESULT_SHOWUSAGE;
2707 res = ast_db_deltree(argv[2], argv[3]);
2709 res = ast_db_deltree(argv[2], NULL);
2711 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2712 return RESULT_SUCCESS;
2715 static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2719 e->command = "agi set debug [on|off]";
2721 "Usage: agi set debug [on|off]\n"
2722 " Enables/disables dumping of AGI transactions for\n"
2723 " debugging purposes.\n";
2730 if (a->argc != e->args)
2731 return CLI_SHOWUSAGE;
2733 if (strncasecmp(a->argv[3], "off", 3) == 0) {
2735 } else if (strncasecmp(a->argv[3], "on", 2) == 0) {
2738 return CLI_SHOWUSAGE;
2740 ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis");
2744 static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, const char * const argv[])
2746 ast_agi_send(agi->fd, chan, "200 result=0\n");
2747 return RESULT_SUCCESS;
2750 static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2753 return RESULT_SHOWUSAGE;
2755 if (!strncasecmp(argv[2], "on", 2))
2756 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
2757 else if (!strncasecmp(argv[2], "off", 3))
2759 ast_agi_send(agi->fd, chan, "200 result=0\n");
2760 return RESULT_SUCCESS;
2763 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2765 struct ast_format_cap *cap;
2766 struct ast_format tmpfmt;
2768 /* If a structure already exists, return an error */
2770 ast_agi_send(agi->fd, chan, "200 result=0\n");
2771 return RESULT_SUCCESS;
2774 if (!(cap = ast_format_cap_alloc_nolock())) {
2775 return RESULT_FAILURE;
2777 ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
2778 if ((agi->speech = ast_speech_new(argv[2], cap))) {
2779 ast_agi_send(agi->fd, chan, "200 result=1\n");
2781 ast_agi_send(agi->fd, chan, "200 result=0\n");
2783 cap = ast_format_cap_destroy(cap);
2785 return RESULT_SUCCESS;
2788 static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2790 /* Check for minimum arguments */
2792 return RESULT_SHOWUSAGE;
2794 /* Check to make sure speech structure exists */
2796 ast_agi_send(agi->fd, chan, "200 result=0\n");
2797 return RESULT_SUCCESS;
2800 ast_speech_change(agi->speech, argv[2], argv[3]);
2801 ast_agi_send(agi->fd, chan, "200 result=1\n");
2803 return RESULT_SUCCESS;
2806 static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2809 ast_speech_destroy(agi->speech);
2811 ast_agi_send(agi->fd, chan, "200 result=1\n");
2813 ast_agi_send(agi->fd, chan, "200 result=0\n");
2816 return RESULT_SUCCESS;
2819 static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2822 return RESULT_SHOWUSAGE;
2825 ast_agi_send(agi->fd, chan, "200 result=0\n");
2826 return RESULT_SUCCESS;
2829 if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
2830 ast_agi_send(agi->fd, chan, "200 result=0\n");
2832 ast_agi_send(agi->fd, chan, "200 result=1\n");
2834 return RESULT_SUCCESS;
2837 static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2840 return RESULT_SHOWUSAGE;
2843 ast_agi_send(agi->fd, chan, "200 result=0\n");
2844 return RESULT_SUCCESS;
2847 if (ast_speech_grammar_unload(agi->speech, argv[3]))
2848 ast_agi_send(agi->fd, chan, "200 result=0\n");
2850 ast_agi_send(agi->fd, chan, "200 result=1\n");
2852 return RESULT_SUCCESS;
2855 static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2858 return RESULT_SHOWUSAGE;
2861 ast_agi_send(agi->fd, chan, "200 result=0\n");
2862 return RESULT_SUCCESS;
2865 if (ast_speech_grammar_activate(agi->speech, argv[3]))
2866 ast_agi_send(agi->fd, chan, "200 result=0\n");
2868 ast_agi_send(agi->fd, chan, "200 result=1\n");
2870 return RESULT_SUCCESS;
2873 static int handle_speechdeactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2876 return RESULT_SHOWUSAGE;
2879 ast_agi_send(agi->fd, chan, "200 result=0\n");
2880 return RESULT_SUCCESS;
2883 if (ast_speech_grammar_deactivate(agi->speech, argv[3]))
2884 ast_agi_send(agi->fd, chan, "200 result=0\n");
2886 ast_agi_send(agi->fd, chan, "200 result=1\n");
2888 return RESULT_SUCCESS;
2891 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang, int offset)
2893 struct ast_filestream *fs = NULL;
2895 if (!(fs = ast_openstream(chan, filename, preflang)))
2899 ast_seekstream(fs, offset, SEEK_SET);
2901 if (ast_applystream(chan, fs))
2904 if (ast_playstream(fs))
2910 static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2912 struct ast_speech *speech = agi->speech;
2914 char dtmf = 0, tmp[4096] = "", *buf = tmp;
2915 int timeout = 0, offset = 0, res = 0, i = 0;
2916 struct ast_format old_read_format;
2917 long current_offset = 0;
2918 const char *reason = NULL;
2919 struct ast_frame *fr = NULL;
2920 struct ast_speech_result *result = NULL;
2921 size_t left = sizeof(tmp);
2922 time_t start = 0, current;
2925 return RESULT_SHOWUSAGE;
2928 ast_agi_send(agi->fd, chan, "200 result=0\n");
2929 return RESULT_SUCCESS;
2933 timeout = atoi(argv[3]);
2935 /* If offset is specified then convert from text to integer */
2937 offset = atoi(argv[4]);
2939 /* We want frames coming in signed linear */
2940 ast_format_copy(&old_read_format, &chan->readformat);
2941 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
2942 ast_agi_send(agi->fd, chan, "200 result=0\n");
2943 return RESULT_SUCCESS;
2946 /* Setup speech structure */
2947 if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
2948 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
2949 ast_speech_start(speech);
2952 /* Start playing prompt */
2953 speech_streamfile(chan, prompt, ast_channel_language(chan), offset);
2955 /* Go into loop reading in frames, passing to speech thingy, checking for hangup, all that jazz */
2956 while (ast_strlen_zero(reason)) {
2957 /* Run scheduled items */
2958 ast_sched_runq(chan->sched);
2960 /* See maximum time of waiting */
2961 if ((res = ast_sched_wait(chan->sched)) < 0)
2964 /* Wait for frame */
2965 if (ast_waitfor(chan, res) > 0) {
2966 if (!(fr = ast_read(chan))) {
2972 /* Perform timeout check */
2973 if ((timeout > 0) && (start > 0)) {
2975 if ((current - start) >= timeout) {
2983 /* Check the speech structure for any changes */
2984 ast_mutex_lock(&speech->lock);
2986 /* See if we need to quiet the audio stream playback */
2987 if (ast_test_flag(speech, AST_SPEECH_QUIET) && chan->stream) {
2988 current_offset = ast_tellstream(chan->stream);
2989 ast_stopstream(chan);
2990 ast_clear_flag(speech, AST_SPEECH_QUIET);
2993 /* Check each state */
2994 switch (speech->state) {
2995 case AST_SPEECH_STATE_READY:
2996 /* If the stream is done, start timeout calculation */
2997 if ((timeout > 0) && start == 0 && ((!chan->stream) || (chan->streamid == -1 && chan->timingfunc == NULL))) {
2998 ast_stopstream(chan);
3001 /* Write audio frame data into speech engine if possible */
3002 if (fr && fr->frametype == AST_FRAME_VOICE)
3003 ast_speech_write(speech, fr->data.ptr, fr->datalen);
3005 case AST_SPEECH_STATE_WAIT:
3006 /* Cue waiting sound if not already playing */
3007 if ((!chan->stream) || (chan->streamid == -1 && chan->timingfunc == NULL)) {
3008 ast_stopstream(chan);
3009 /* If a processing sound exists, or is not none - play it */
3010 if (!ast_strlen_zero(speech->processing_sound) && strcasecmp(speech->processing_sound, "none"))
3011 speech_streamfile(chan, speech->processing_sound, ast_channel_language(chan), 0);
3014 case AST_SPEECH_STATE_DONE:
3015 /* Get the results */
3016 speech->results = ast_speech_results_get(speech);
3017 /* Change state to not ready */
3018 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
3024 ast_mutex_unlock(&speech->lock);
3026 /* Check frame for DTMF or hangup */
3028 if (fr->frametype == AST_FRAME_DTMF) {
3030 dtmf = fr->subclass.integer;
3031 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_HANGUP) {
3038 if (!strcasecmp(reason, "speech")) {
3039 /* Build string containing speech results */
3040 for (result = speech->results; result; result = AST_LIST_NEXT(result, list)) {
3041 /* Build result string */
3042 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);
3043 /* Increment result count */
3047 ast_agi_send(agi->fd, chan, "200 result=1 (speech) endpos=%ld results=%d %s\n", current_offset, i, tmp);
3048 } else if (!strcasecmp(reason, "dtmf")) {
3049 ast_agi_send(agi->fd, chan, "200 result=1 (digit) digit=%c endpos=%ld\n", dtmf, current_offset);
3050 } else if (!strcasecmp(reason, "hangup") || !strcasecmp(reason, "timeout")) {
3051 ast_agi_send(agi->fd, chan, "200 result=1 (%s) endpos=%ld\n", reason, current_offset);
3053 ast_agi_send(agi->fd, chan, "200 result=0 endpos=%ld\n", current_offset);
3056 return RESULT_SUCCESS;
3060 * \brief AGI commands list
3062 static struct agi_command commands[] = {
3063 { { "answer", NULL }, handle_answer, NULL, NULL, 0 },
3064 { { "asyncagi", "break", NULL }, handle_asyncagi_break, NULL, NULL, 1 },
3065 { { "channel", "status", NULL }, handle_channelstatus, NULL, NULL, 0 },
3066 { { "database", "del", NULL }, handle_dbdel, NULL, NULL, 1 },
3067 { { "database", "deltree", NULL }, handle_dbdeltree, NULL, NULL, 1 },
3068 { { "database", "get", NULL }, handle_dbget, NULL, NULL, 1 },
3069 { { "database", "put", NULL }, handle_dbput, NULL, NULL, 1 },
3070 { { "exec", NULL }, handle_exec, NULL, NULL, 1 },