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/features.h"
65 #include "asterisk/term.h"
66 #include "asterisk/xmldoc.h"
67 #include "asterisk/srv.h"
68 #include "asterisk/test.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.</para>
824 <para>Use the CLI command <literal>agi show commands</literal> to list available agi
826 <para>This application sets the following channel variable upon completion:</para>
828 <variable name="AGISTATUS">
829 <para>The status of the attempt to the run the AGI script
830 text string, one of:</para>
831 <value name="SUCCESS" />
832 <value name="FAILURE" />
833 <value name="NOTFOUND" />
834 <value name="HANGUP" />
839 <ref type="application">EAGI</ref>
840 <ref type="application">DeadAGI</ref>
843 <application name="EAGI" language="en_US">
845 Executes an EAGI compliant application.
848 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
849 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
852 <para>Using 'EAGI' provides enhanced AGI, with incoming audio available out of band
853 on file descriptor 3.</para>
854 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
855 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
858 <ref type="application">AGI</ref>
859 <ref type="application">DeadAGI</ref>
862 <application name="DeadAGI" language="en_US">
864 Executes AGI on a hungup channel.
867 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
868 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
871 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
872 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
875 <ref type="application">AGI</ref>
876 <ref type="application">EAGI</ref>
879 <manager name="AGI" language="en_US">
881 Add an AGI command to execute by Async AGI.
884 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
885 <parameter name="Channel" required="true">
886 <para>Channel that is currently in Async AGI.</para>
888 <parameter name="Command" required="true">
889 <para>Application to execute.</para>
891 <parameter name="CommandID">
892 <para>This will be sent back in CommandID header of AsyncAGI exec
893 event notification.</para>
897 <para>Add an AGI command to the execute queue of the channel in Async AGI.</para>
903 #define MAX_CMD_LEN 80
904 #define AGI_NANDFS_RETRY 3
905 #define AGI_BUF_LEN 2048
906 #define SRV_PREFIX "_agi._tcp."
908 static char *app = "AGI";
910 static char *eapp = "EAGI";
912 static char *deadapp = "DeadAGI";
914 static int agidebug = 0;
916 #define TONE_BLOCK_SIZE 200
918 /* Max time to connect to an AGI remote host */
919 #define MAX_AGI_CONNECT 2000
921 #define AGI_PORT 4573
923 /*! Special return code for "asyncagi break" command. */
924 #define ASYNC_AGI_BREAK 3
927 AGI_RESULT_FAILURE = -1,
929 AGI_RESULT_SUCCESS_FAST,
930 AGI_RESULT_SUCCESS_ASYNC,
935 static agi_command *find_command(const char * const cmds[], int exact);
937 AST_THREADSTORAGE(agi_buf);
938 #define AGI_BUF_INITSIZE 256
940 int AST_OPTIONAL_API_NAME(ast_agi_send)(int fd, struct ast_channel *chan, char *fmt, ...)
946 if (!(buf = ast_str_thread_get(&agi_buf, AGI_BUF_INITSIZE)))
950 res = ast_str_set_va(&buf, 0, fmt, ap);
954 ast_log(LOG_ERROR, "Out of memory\n");
960 ast_verbose("<%s>AGI Tx >> %s", chan->name, ast_str_buffer(buf));
962 ast_verbose("AGI Tx >> %s", ast_str_buffer(buf));
966 return ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
969 /* linked list of AGI commands ready to be executed by Async AGI */
973 AST_LIST_ENTRY(agi_cmd) entry;
976 static void free_agi_cmd(struct agi_cmd *cmd)
978 ast_free(cmd->cmd_buffer);
979 ast_free(cmd->cmd_id);
983 /* AGI datastore destructor */
984 static void agi_destroy_commands_cb(void *data)
987 AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
988 AST_LIST_LOCK(chan_cmds);
989 while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
992 AST_LIST_UNLOCK(chan_cmds);
993 AST_LIST_HEAD_DESTROY(chan_cmds);
997 /* channel datastore to keep the queue of AGI commands in the channel */
998 static const struct ast_datastore_info agi_commands_datastore_info = {
1000 .destroy = agi_destroy_commands_cb
1003 static struct agi_cmd *get_agi_cmd(struct ast_channel *chan)
1005 struct ast_datastore *store;
1006 struct agi_cmd *cmd;
1007 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1009 ast_channel_lock(chan);
1010 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1011 ast_channel_unlock(chan);
1013 ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
1017 agi_commands = store->data;
1018 AST_LIST_LOCK(agi_commands);
1019 cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
1020 AST_LIST_UNLOCK(agi_commands);
1024 /* channel is locked when calling this one either from the CLI or manager thread */
1025 static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
1027 struct ast_datastore *store;
1028 struct agi_cmd *cmd;
1029 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1031 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1033 ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", chan->name);
1036 agi_commands = store->data;
1037 cmd = ast_calloc(1, sizeof(*cmd));
1041 cmd->cmd_buffer = ast_strdup(cmd_buff);
1042 if (!cmd->cmd_buffer) {
1046 cmd->cmd_id = ast_strdup(cmd_id);
1048 ast_free(cmd->cmd_buffer);
1052 AST_LIST_LOCK(agi_commands);
1053 AST_LIST_INSERT_TAIL(agi_commands, cmd, entry);
1054 AST_LIST_UNLOCK(agi_commands);
1058 static int add_to_agi(struct ast_channel *chan)
1060 struct ast_datastore *datastore;
1061 AST_LIST_HEAD(, agi_cmd) *agi_cmds_list;
1063 /* check if already on AGI */
1064 ast_channel_lock(chan);
1065 datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1066 ast_channel_unlock(chan);
1068 /* we already have an AGI datastore, let's just
1073 /* the channel has never been on Async AGI,
1074 let's allocate it's datastore */
1075 datastore = ast_datastore_alloc(&agi_commands_datastore_info, "AGI");
1079 agi_cmds_list = ast_calloc(1, sizeof(*agi_cmds_list));
1080 if (!agi_cmds_list) {
1081 ast_log(LOG_ERROR, "Unable to allocate Async AGI commands list.\n");
1082 ast_datastore_free(datastore);
1085 datastore->data = agi_cmds_list;
1086 AST_LIST_HEAD_INIT(agi_cmds_list);
1087 ast_channel_lock(chan);
1088 ast_channel_datastore_add(chan, datastore);
1089 ast_channel_unlock(chan);
1094 * \brief CLI command to add applications to execute in Async AGI
1099 * \retval CLI_SUCCESS on success
1100 * \retval NULL when init or tab completion is used
1102 static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1104 struct ast_channel *chan;
1107 e->command = "agi exec";
1108 e->usage = "Usage: agi exec <channel name> <app and arguments> [id]\n"
1109 " Add AGI command to the execute queue of the specified channel in Async AGI\n";
1113 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
1118 return CLI_SHOWUSAGE;
1121 if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
1122 ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
1126 ast_channel_lock(chan);
1128 if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
1129 ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", chan->name);
1130 ast_channel_unlock(chan);
1131 chan = ast_channel_unref(chan);
1135 ast_debug(1, "Added AGI command to channel %s queue\n", chan->name);
1137 ast_channel_unlock(chan);
1138 chan = ast_channel_unref(chan);
1144 * \brief Add a new command to execute by the Async AGI application
1148 * It will append the application to the specified channel's queue
1149 * if the channel is not inside Async AGI application it will return an error
1150 * \retval 0 on success or incorrect use
1151 * \retval 1 on failure to add the command ( most likely because the channel
1152 * is not in Async AGI loop )
1154 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
1156 const char *channel = astman_get_header(m, "Channel");
1157 const char *cmdbuff = astman_get_header(m, "Command");
1158 const char *cmdid = astman_get_header(m, "CommandID");
1159 struct ast_channel *chan;
1162 if (ast_strlen_zero(channel) || ast_strlen_zero(cmdbuff)) {
1163 astman_send_error(s, m, "Both, Channel and Command are *required*");
1167 if (!(chan = ast_channel_get_by_name(channel))) {
1168 snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
1169 astman_send_error(s, m, buf);
1173 ast_channel_lock(chan);
1175 if (add_agi_cmd(chan, cmdbuff, cmdid)) {
1176 snprintf(buf, sizeof(buf), "Failed to add AGI command to channel %s queue", chan->name);
1177 astman_send_error(s, m, buf);
1178 ast_channel_unlock(chan);
1179 chan = ast_channel_unref(chan);
1183 ast_channel_unlock(chan);
1184 chan = ast_channel_unref(chan);
1186 astman_send_ack(s, m, "Added AGI command to queue");
1191 static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
1192 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
1196 * \brief Read and handle a channel frame for Async AGI.
1198 * \param chan Channel to read a frame from.
1200 * \retval AGI_RESULT_SUCCESS on success.
1201 * \retval AGI_RESULT_HANGUP on hangup.
1202 * \retval AGI_RESULT_FAILURE on error.
1204 static enum agi_result async_agi_read_frame(struct ast_channel *chan)
1206 struct ast_frame *f;
1210 ast_debug(3, "No frame read on channel %s, going out ...\n", chan->name);
1211 return AGI_RESULT_HANGUP;
1213 if (f->frametype == AST_FRAME_CONTROL) {
1215 * Is there any other frame we should care about besides
1216 * AST_CONTROL_HANGUP?
1218 switch (f->subclass.integer) {
1219 case AST_CONTROL_HANGUP:
1220 ast_debug(3, "Got HANGUP frame on channel %s, going out ...\n", chan->name);
1222 return AGI_RESULT_HANGUP;
1229 return AGI_RESULT_SUCCESS;
1232 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
1234 /* This buffer sizes might cause truncation if the AGI command writes more data
1235 than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
1236 that writes a response larger than 1024 bytes?, I don't think so, most of
1237 them are just result=blah stuff. However probably if GET VARIABLE is called
1238 and the variable has large amount of data, that could be a problem. We could
1239 make this buffers dynamic, but let's leave that as a second step.
1241 AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
1242 number. Some characters of AGI buf will be url encoded to be sent to manager
1243 clients. An URL encoded character will take 3 bytes, but again, to cause
1244 truncation more than about 70% of the AGI buffer should be URL encoded for
1245 that to happen. Not likely at all.
1247 On the other hand. I wonder if read() could eventually return less data than
1248 the amount already available in the pipe? If so, how to deal with that?
1249 So far, my tests on Linux have not had any problems.
1251 #define AGI_BUF_SIZE 1024
1252 #define AMI_BUF_SIZE 2048
1253 enum agi_result cmd_status;
1254 struct agi_cmd *cmd;
1259 char agi_buffer[AGI_BUF_SIZE + 1];
1260 char ami_buffer[AMI_BUF_SIZE];
1261 enum agi_result returnstatus = AGI_RESULT_SUCCESS;
1265 ast_log(LOG_WARNING, "Async AGI does not support Enhanced AGI yet\n");
1266 return AGI_RESULT_FAILURE;
1269 /* add AsyncAGI datastore to the channel */
1270 if (add_to_agi(chan)) {
1271 ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", chan->name);
1272 return AGI_RESULT_FAILURE;
1275 /* this pipe allows us to create a "fake" AGI struct to use
1279 ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
1281 * Intentionally do not remove the datastore added with
1282 * add_to_agi() the from channel. It will be removed when the
1283 * channel is hung up anyway.
1285 return AGI_RESULT_FAILURE;
1288 /* handlers will get the pipe write fd and we read the AGI responses
1289 from the pipe read fd */
1290 async_agi.fd = fds[1];
1291 async_agi.ctrl = fds[1];
1292 async_agi.audio = -1; /* no audio support */
1294 async_agi.speech = NULL;
1296 /* notify possible manager users of a new channel ready to
1298 setup_env(chan, "async", fds[1], 0, 0, NULL);
1299 /* read the environment */
1300 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1302 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
1304 returnstatus = AGI_RESULT_FAILURE;
1305 goto async_agi_abort;
1307 agi_buffer[res] = '\0';
1308 /* encode it and send it thru the manager so whoever is going to take
1309 care of AGI commands on this channel can decide which AGI commands
1310 to execute based on the setup info */
1311 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1312 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1313 "SubEvent: Start\r\n"
1315 "Env: %s\r\n", chan->name, ami_buffer);
1316 hungup = ast_check_hangup(chan);
1319 * Process as many commands as we can. Commands are added via
1320 * the manager or the cli threads.
1322 while (!hungup && (cmd = get_agi_cmd(chan))) {
1323 /* OK, we have a command, let's call the command handler. */
1324 cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
1327 * The command handler must have written to our fake AGI struct
1328 * fd (the pipe), let's read the response.
1330 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1332 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
1335 returnstatus = AGI_RESULT_FAILURE;
1336 goto async_agi_done;
1339 * We have a response, let's send the response thru the manager.
1340 * Include the CommandID if it was specified when the command
1343 agi_buffer[res] = '\0';
1344 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1345 if (ast_strlen_zero(cmd->cmd_id)) {
1346 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1347 "SubEvent: Exec\r\n"
1349 "Result: %s\r\n", chan->name, ami_buffer);
1351 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1352 "SubEvent: Exec\r\n"
1355 "Result: %s\r\n", chan->name, cmd->cmd_id, ami_buffer);
1360 * Check the command status to determine if we should continue
1361 * executing more commands.
1363 hungup = ast_check_hangup(chan);
1364 switch (cmd_status) {
1365 case AGI_RESULT_FAILURE:
1367 /* The failure was not because of a hangup. */
1368 returnstatus = AGI_RESULT_FAILURE;
1369 goto async_agi_done;
1372 case AGI_RESULT_SUCCESS_ASYNC:
1373 /* Only the "asyncagi break" command does this. */
1374 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1375 goto async_agi_done;
1382 /* Wait a bit for a frame to read or to poll for a new command. */
1383 res = ast_waitfor(chan, timeout);
1385 ast_debug(1, "ast_waitfor returned <= 0 on chan %s\n", chan->name);
1386 returnstatus = AGI_RESULT_FAILURE;
1391 * Read the channel control queue until it is dry so we can
1398 cmd_status = async_agi_read_frame(chan);
1399 if (cmd_status != AGI_RESULT_SUCCESS) {
1400 returnstatus = cmd_status;
1401 goto async_agi_done;
1403 hungup = ast_check_hangup(chan);
1406 hungup = ast_check_hangup(chan);
1411 if (async_agi.speech) {
1412 ast_speech_destroy(async_agi.speech);
1414 /* notify manager users this channel cannot be
1415 controlled anymore by Async AGI */
1416 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1418 "Channel: %s\r\n", chan->name);
1421 /* close the pipe */
1426 * Intentionally do not remove the datastore added with
1427 * add_to_agi() the from channel. There might be commands still
1428 * in the queue or in-flight to us and AsyncAGI may get called
1429 * again. The datastore destructor will be called on channel
1430 * destruction anyway.
1433 if (returnstatus == AGI_RESULT_SUCCESS) {
1434 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1436 return returnstatus;
1442 /* launch_netscript: The fastagi handler.
1443 FastAGI defaults to port 4573 */
1444 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
1446 int s, flags, res, port = AGI_PORT;
1447 struct pollfd pfds[1];
1448 char *host, *c, *script;
1449 struct sockaddr_in addr_in;
1451 struct ast_hostent ahp;
1453 /* agiurl is "agi://host.domain[:port][/script/name]" */
1454 host = ast_strdupa(agiurl + 6); /* Remove agi:// */
1455 /* Strip off any script name */
1456 if ((script = strchr(host, '/'))) {
1462 if ((c = strchr(host, ':'))) {
1466 if (!(hp = ast_gethostbyname(host, &ahp))) {
1467 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
1468 return AGI_RESULT_FAILURE;
1470 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1471 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1472 return AGI_RESULT_FAILURE;
1474 if ((flags = fcntl(s, F_GETFL)) < 0) {
1475 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno));
1477 return AGI_RESULT_FAILURE;
1479 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
1480 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno));
1482 return AGI_RESULT_FAILURE;
1484 memset(&addr_in, 0, sizeof(addr_in));
1485 addr_in.sin_family = AF_INET;
1486 addr_in.sin_port = htons(port);
1487 memcpy(&addr_in.sin_addr, hp->h_addr, sizeof(addr_in.sin_addr));
1488 if (connect(s, (struct sockaddr *)&addr_in, sizeof(addr_in)) && (errno != EINPROGRESS)) {
1489 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno));
1491 return AGI_RESULT_FAILURE;
1495 pfds[0].events = POLLOUT;
1496 while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
1497 if (errno != EINTR) {
1499 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
1500 agiurl, MAX_AGI_CONNECT);
1502 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1504 return AGI_RESULT_FAILURE;
1508 if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
1509 if (errno != EINTR) {
1510 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1512 return AGI_RESULT_FAILURE;
1516 /* If we have a script parameter, relay it to the fastagi server */
1517 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
1518 if (!ast_strlen_zero(script))
1519 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
1521 ast_debug(4, "Wow, connected!\n");
1524 return AGI_RESULT_SUCCESS_FAST;
1529 * \brief The HA fastagi handler.
1530 * \param agiurl The request URL as passed to Agi() in the dial plan
1531 * \param argv The parameters after the URL passed to Agi() in the dial plan
1532 * \param fds Input/output file descriptors
1534 * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
1535 * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
1536 * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
1537 * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
1540 * This function parses the URI, resolves the SRV service name, forms new URIs
1541 * with the results of the DNS lookup, and then calls launch_netscript on the
1542 * new URIs until one succeeds.
1544 * \return the result of the AGI operation.
1546 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
1548 char *host, *script;
1549 enum agi_result result;
1550 struct srv_context *context = NULL;
1553 char resolved_uri[1024];
1554 const char *srvhost;
1555 unsigned short srvport;
1557 /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
1558 if (!(host = ast_strdupa(agiurl + 7))) { /* Remove hagi:// */
1559 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
1560 return AGI_RESULT_FAILURE;
1563 /* Strip off any script name */
1564 if ((script = strchr(host, '/'))) {
1570 if (strchr(host, ':')) {
1571 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
1572 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
1575 snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
1577 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
1578 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
1579 result = launch_netscript(resolved_uri, argv, fds);
1580 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
1581 ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
1583 /* The script launched so we must cleanup the context. */
1584 ast_srv_cleanup(&context);
1589 * The DNS SRV lookup failed or we ran out of servers to check.
1590 * ast_srv_lookup() has already cleaned up the context for us.
1593 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
1596 return AGI_RESULT_FAILURE;
1599 static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
1602 int pid, toast[2], fromast[2], audio[2], res;
1605 if (!strncasecmp(script, "agi://", 6)) {
1606 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1608 if (!strncasecmp(script, "hagi://", 7)) {
1609 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1611 if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
1612 return launch_asyncagi(chan, argv, efd);
1615 if (script[0] != '/') {
1616 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
1620 /* Before even trying let's see if the file actually exists */
1621 if (stat(script, &st)) {
1622 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
1623 return AGI_RESULT_NOTFOUND;
1627 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
1628 return AGI_RESULT_FAILURE;
1630 if (pipe(fromast)) {
1631 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
1634 return AGI_RESULT_FAILURE;
1638 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
1643 return AGI_RESULT_FAILURE;
1645 res = fcntl(audio[1], F_GETFL);
1647 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
1649 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
1656 return AGI_RESULT_FAILURE;
1660 if ((pid = ast_safe_fork(1)) < 0) {
1661 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
1662 return AGI_RESULT_FAILURE;
1665 /* Pass paths to AGI via environmental variables */
1666 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
1667 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
1668 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
1669 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
1670 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
1671 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
1672 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
1673 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
1674 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
1675 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
1676 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
1678 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
1679 ast_set_priority(0);
1681 /* Redirect stdin and out, provide enhanced audio channel if desired */
1682 dup2(fromast[0], STDIN_FILENO);
1683 dup2(toast[1], STDOUT_FILENO);
1685 dup2(audio[0], STDERR_FILENO + 1);
1687 close(STDERR_FILENO + 1);
1689 /* Close everything but stdin/out/error */
1690 ast_close_fds_above_n(STDERR_FILENO + 1);
1692 /* Execute script */
1693 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
1694 execv(script, argv);
1695 /* Can't use ast_log since FD's are closed */
1696 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
1697 /* Special case to set status of AGI to failure */
1698 fprintf(stdout, "failure\n");
1702 ast_verb(3, "Launched AGI Script %s\n", script);
1704 fds[1] = fromast[1];
1707 /* close what we're not using in the parent */
1715 return AGI_RESULT_SUCCESS;
1718 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
1722 /* Print initial environment, with agi_request always being the first
1724 ast_agi_send(fd, chan, "agi_request: %s\n", request);
1725 ast_agi_send(fd, chan, "agi_channel: %s\n", chan->name);
1726 ast_agi_send(fd, chan, "agi_language: %s\n", chan->language);
1727 ast_agi_send(fd, chan, "agi_type: %s\n", chan->tech->type);
1728 ast_agi_send(fd, chan, "agi_uniqueid: %s\n", chan->uniqueid);
1729 ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
1732 ast_agi_send(fd, chan, "agi_callerid: %s\n",
1733 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "unknown"));
1734 ast_agi_send(fd, chan, "agi_calleridname: %s\n",
1735 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "unknown"));
1736 ast_agi_send(fd, chan, "agi_callingpres: %d\n",
1737 ast_party_id_presentation(&chan->caller.id));
1738 ast_agi_send(fd, chan, "agi_callingani2: %d\n", chan->caller.ani2);
1739 ast_agi_send(fd, chan, "agi_callington: %d\n", chan->caller.id.number.plan);
1740 ast_agi_send(fd, chan, "agi_callingtns: %d\n", chan->dialed.transit_network_select);
1741 ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(chan->dialed.number.str, "unknown"));
1742 ast_agi_send(fd, chan, "agi_rdnis: %s\n",
1743 S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "unknown"));
1745 /* Context information */
1746 ast_agi_send(fd, chan, "agi_context: %s\n", chan->context);
1747 ast_agi_send(fd, chan, "agi_extension: %s\n", chan->exten);
1748 ast_agi_send(fd, chan, "agi_priority: %d\n", chan->priority);
1749 ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
1751 /* User information */
1752 ast_agi_send(fd, chan, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
1753 ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
1755 /* Send any parameters to the fastagi server that have been passed via the agi application */
1756 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
1757 for(count = 1; count < argc; count++)
1758 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
1760 /* End with empty return */
1761 ast_agi_send(fd, chan, "\n");
1764 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1768 /* Answer the channel */
1769 if (chan->_state != AST_STATE_UP)
1770 res = ast_answer(chan);
1772 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1773 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1776 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1778 ast_agi_send(agi->fd, chan, "200 result=0\n");
1779 return ASYNC_AGI_BREAK;
1782 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1787 return RESULT_SHOWUSAGE;
1788 if (sscanf(argv[3], "%30d", &to) != 1)
1789 return RESULT_SHOWUSAGE;
1790 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
1791 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1792 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1795 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1800 return RESULT_SHOWUSAGE;
1802 /* At the moment, the parser (perhaps broken) returns with
1803 the last argument PLUS the newline at the end of the input
1804 buffer. This probably needs to be fixed, but I wont do that
1805 because other stuff may break as a result. The right way
1806 would probably be to strip off the trailing newline before
1807 parsing, then here, add a newline at the end of the string
1808 before sending it to ast_sendtext --DUDE */
1809 res = ast_sendtext(chan, argv[2]);
1810 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1811 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1814 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1819 return RESULT_SHOWUSAGE;
1821 res = ast_recvchar(chan,atoi(argv[2]));
1823 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
1824 return RESULT_SUCCESS;
1827 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1828 return RESULT_SUCCESS;
1830 ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
1831 return RESULT_FAILURE;
1834 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1839 return RESULT_SHOWUSAGE;
1841 buf = ast_recvtext(chan, atoi(argv[2]));
1843 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
1846 ast_agi_send(agi->fd, chan, "200 result=-1\n");
1848 return RESULT_SUCCESS;
1851 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1856 return RESULT_SHOWUSAGE;
1858 if (!strncasecmp(argv[2],"on",2)) {
1863 if (!strncasecmp(argv[2],"mate",4)) {
1866 if (!strncasecmp(argv[2],"tdd",3)) {
1869 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
1871 /* Set channel option failed */
1872 ast_agi_send(agi->fd, chan, "200 result=0\n");
1874 ast_agi_send(agi->fd, chan, "200 result=1\n");
1876 return RESULT_SUCCESS;
1879 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1884 return RESULT_SHOWUSAGE;
1887 res = ast_send_image(chan, argv[2]);
1888 if (!ast_check_hangup(chan)) {
1891 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1892 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1895 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1897 int res = 0, skipms = 3000;
1898 const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL; /* Default values */
1900 if (argc < 5 || argc > 9) {
1901 return RESULT_SHOWUSAGE;
1904 if (!ast_strlen_zero(argv[4])) {
1908 if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
1909 return RESULT_SHOWUSAGE;
1912 if (argc > 6 && !ast_strlen_zero(argv[6])) {
1916 if (argc > 7 && !ast_strlen_zero(argv[7])) {
1920 if (argc > 8 && !ast_strlen_zero(argv[8])) {
1924 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
1926 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1928 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1931 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1934 struct ast_filestream *fs, *vfs;
1935 long sample_offset = 0, max_length;
1936 const char *edigits = "";
1938 if (argc < 4 || argc > 5) {
1939 return RESULT_SHOWUSAGE;
1946 if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1)) {
1947 return RESULT_SHOWUSAGE;
1950 if (!(fs = ast_openstream(chan, argv[2], chan->language))) {
1951 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
1952 return RESULT_SUCCESS;
1955 if ((vfs = ast_openvstream(chan, argv[2], chan->language))) {
1956 ast_debug(1, "Ooh, found a video stream, too\n");
1959 ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
1961 ast_seekstream(fs, 0, SEEK_END);
1962 max_length = ast_tellstream(fs);
1963 ast_seekstream(fs, sample_offset, SEEK_SET);
1964 res = ast_applystream(chan, fs);
1966 ast_applystream(chan, vfs);
1970 ast_playstream(vfs);
1973 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
1974 /* this is to check for if ast_waitstream closed the stream, we probably are at
1975 * the end of the stream, return that amount, else check for the amount */
1976 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
1977 ast_stopstream(chan);
1979 /* Stop this command, don't print a result line, as there is a new command */
1980 return RESULT_SUCCESS;
1982 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
1983 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1986 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
1987 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1990 struct ast_filestream *fs, *vfs;
1991 long sample_offset = 0, max_length;
1993 const char *edigits = "";
1995 if ( argc < 4 || argc > 5 )
1996 return RESULT_SHOWUSAGE;
2002 timeout = atoi(argv[4]);
2003 else if (chan->pbx->dtimeoutms) {
2004 /* by default dtimeout is set to 5sec */
2005 timeout = chan->pbx->dtimeoutms; /* in msec */
2008 if (!(fs = ast_openstream(chan, argv[2], chan->language))) {
2009 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2010 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2011 return RESULT_SUCCESS;
2014 if ((vfs = ast_openvstream(chan, argv[2], chan->language)))
2015 ast_debug(1, "Ooh, found a video stream, too\n");
2017 ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2019 ast_seekstream(fs, 0, SEEK_END);
2020 max_length = ast_tellstream(fs);
2021 ast_seekstream(fs, sample_offset, SEEK_SET);
2022 res = ast_applystream(chan, fs);
2024 ast_applystream(chan, vfs);
2027 ast_playstream(vfs);
2029 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2030 /* this is to check for if ast_waitstream closed the stream, we probably are at
2031 * the end of the stream, return that amount, else check for the amount */
2032 sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
2033 ast_stopstream(chan);
2035 /* Stop this command, don't print a result line, as there is a new command */
2036 return RESULT_SUCCESS;
2039 /* If the user didnt press a key, wait for digitTimeout*/
2041 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2042 /* Make sure the new result is in the escape digits of the GET OPTION */
2043 if ( !strchr(edigits,res) )
2047 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2048 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2054 /*! \brief Say number in various language syntaxes */
2055 /* While waiting, we're sending a NULL. */
2056 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2060 if (argc < 4 || argc > 5)
2061 return RESULT_SHOWUSAGE;
2062 if (sscanf(argv[2], "%30d", &num) != 1)
2063 return RESULT_SHOWUSAGE;
2064 res = ast_say_number_full(chan, num, argv[3], chan->language, argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2066 return RESULT_SUCCESS;
2067 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2068 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2071 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2076 return RESULT_SHOWUSAGE;
2077 if (sscanf(argv[2], "%30d", &num) != 1)
2078 return RESULT_SHOWUSAGE;
2080 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
2081 if (res == 1) /* New command */
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_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2092 return RESULT_SHOWUSAGE;
2094 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
2095 if (res == 1) /* New command */
2096 return RESULT_SUCCESS;
2097 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2098 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2101 static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2106 return RESULT_SHOWUSAGE;
2107 if (sscanf(argv[2], "%30d", &num) != 1)
2108 return RESULT_SHOWUSAGE;
2109 res = ast_say_date(chan, num, argv[3], chan->language);
2111 return RESULT_SUCCESS;
2112 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2113 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2116 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2121 return RESULT_SHOWUSAGE;
2122 if (sscanf(argv[2], "%30d", &num) != 1)
2123 return RESULT_SHOWUSAGE;
2124 res = ast_say_time(chan, num, argv[3], chan->language);
2126 return RESULT_SUCCESS;
2127 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2128 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2131 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2135 const char *format, *zone = NULL;
2138 return RESULT_SHOWUSAGE;
2143 /* XXX this doesn't belong here, but in the 'say' module */
2144 if (!strcasecmp(chan->language, "de")) {
2145 format = "A dBY HMS";
2147 format = "ABdY 'digits/at' IMp";
2151 if (argc > 5 && !ast_strlen_zero(argv[5]))
2154 if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2155 return RESULT_SHOWUSAGE;
2157 res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone);
2159 return RESULT_SUCCESS;
2161 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2162 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2165 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2170 return RESULT_SHOWUSAGE;
2172 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
2173 if (res == 1) /* New command */
2174 return RESULT_SUCCESS;
2175 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2176 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2179 static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2181 int res, max, timeout;
2185 return RESULT_SHOWUSAGE;
2187 timeout = atoi(argv[3]);
2191 max = atoi(argv[4]);
2194 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2195 if (res == 2) /* New command */
2196 return RESULT_SUCCESS;
2198 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2200 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2202 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2203 return RESULT_SUCCESS;
2206 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2210 return RESULT_SHOWUSAGE;
2211 ast_copy_string(chan->context, argv[2], sizeof(chan->context));
2212 ast_agi_send(agi->fd, chan, "200 result=0\n");
2213 return RESULT_SUCCESS;
2216 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2219 return RESULT_SHOWUSAGE;
2220 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
2221 ast_agi_send(agi->fd, chan, "200 result=0\n");
2222 return RESULT_SUCCESS;
2225 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2230 return RESULT_SHOWUSAGE;
2232 if (sscanf(argv[2], "%30d", &pri) != 1) {
2233 pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2],
2234 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
2236 return RESULT_SHOWUSAGE;
2239 ast_explicit_goto(chan, NULL, NULL, pri);
2240 ast_agi_send(agi->fd, chan, "200 result=0\n");
2241 return RESULT_SUCCESS;
2244 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2246 struct ast_filestream *fs;
2247 struct ast_frame *f;
2248 struct timeval start;
2249 long sample_offset = 0;
2253 struct ast_dsp *sildet=NULL; /* silence detector dsp */
2254 int totalsilence = 0;
2256 int silence = 0; /* amount of silence to allow */
2257 int gotsilence = 0; /* did we timeout for silence? */
2258 char *silencestr = NULL;
2259 struct ast_format rfmt;
2260 ast_format_clear(&rfmt);
2262 /* XXX EAGI FIXME XXX */
2265 return RESULT_SHOWUSAGE;
2266 if (sscanf(argv[5], "%30d", &ms) != 1)
2267 return RESULT_SHOWUSAGE;
2270 silencestr = strchr(argv[6],'s');
2271 if ((argc > 7) && (!silencestr))
2272 silencestr = strchr(argv[7],'s');
2273 if ((argc > 8) && (!silencestr))
2274 silencestr = strchr(argv[8],'s');
2277 if (strlen(silencestr) > 2) {
2278 if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2282 silence = atoi(silencestr);
2290 ast_format_copy(&rfmt, &chan->readformat);
2291 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2293 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2294 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2295 return RESULT_FAILURE;
2297 sildet = ast_dsp_new();
2299 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2300 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2301 return RESULT_FAILURE;
2303 ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
2306 /* backward compatibility, if no offset given, arg[6] would have been
2307 * caught below and taken to be a beep, else if it is a digit then it is a
2309 if ((argc >6) && (sscanf(argv[6], "%30ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
2310 res = ast_streamfile(chan, "beep", chan->language);
2312 if ((argc > 7) && (!strchr(argv[7], '=')))
2313 res = ast_streamfile(chan, "beep", chan->language);
2316 res = ast_waitstream(chan, argv[4]);
2318 ast_agi_send(agi->fd, chan, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
2320 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE);
2323 ast_agi_send(agi->fd, chan, "200 result=%d (writefile)\n", res);
2325 ast_dsp_free(sildet);
2326 return RESULT_FAILURE;
2329 /* Request a video update */
2330 ast_indicate(chan, AST_CONTROL_VIDUPDATE);
2333 ast_applystream(chan,fs);
2334 /* really should have checks */
2335 ast_seekstream(fs, sample_offset, SEEK_SET);
2336 ast_truncstream(fs);
2338 start = ast_tvnow();
2339 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
2340 res = ast_waitfor(chan, ms - ast_tvdiff_ms(ast_tvnow(), start));
2342 ast_closestream(fs);
2343 ast_agi_send(agi->fd, chan, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
2345 ast_dsp_free(sildet);
2346 return RESULT_FAILURE;
2350 ast_agi_send(agi->fd, chan, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
2351 ast_closestream(fs);
2353 ast_dsp_free(sildet);
2354 return RESULT_FAILURE;
2356 switch(f->frametype) {
2357 case AST_FRAME_DTMF:
2358 if (strchr(argv[4], f->subclass.integer)) {
2359 /* This is an interrupting chracter, so rewind to chop off any small
2360 amount of DTMF that may have been recorded
2362 ast_stream_rewind(fs, 200);
2363 ast_truncstream(fs);
2364 sample_offset = ast_tellstream(fs);
2365 ast_agi_send(agi->fd, chan, "200 result=%d (dtmf) endpos=%ld\n", f->subclass.integer, sample_offset);
2366 ast_closestream(fs);
2369 ast_dsp_free(sildet);
2370 return RESULT_SUCCESS;
2373 case AST_FRAME_VOICE:
2374 ast_writestream(fs, f);
2375 /* this is a safe place to check progress since we know that fs
2376 * is valid after a write, and it will then have our current
2378 sample_offset = ast_tellstream(fs);
2381 ast_dsp_silence(sildet, f, &dspsilence);
2383 totalsilence = dspsilence;
2387 if (totalsilence > silence) {
2388 /* Ended happily with silence */
2394 case AST_FRAME_VIDEO:
2395 ast_writestream(fs, f);
2397 /* Ignore all other frames */
2406 ast_stream_rewind(fs, silence-1000);
2407 ast_truncstream(fs);
2408 sample_offset = ast_tellstream(fs);
2410 ast_agi_send(agi->fd, chan, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
2411 ast_closestream(fs);
2415 res = ast_set_read_format(chan, &rfmt);
2417 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
2418 ast_dsp_free(sildet);
2421 return RESULT_SUCCESS;
2424 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2427 struct timeval whentohangup = { 0, 0 };
2430 return RESULT_SHOWUSAGE;
2431 if (sscanf(argv[2], "%30lf", &timeout) != 1)
2432 return RESULT_SHOWUSAGE;
2436 whentohangup.tv_sec = timeout;
2437 whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
2439 ast_channel_setwhentohangup_tv(chan, whentohangup);
2440 ast_agi_send(agi->fd, chan, "200 result=0\n");
2441 return RESULT_SUCCESS;
2444 static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2446 struct ast_channel *c;
2449 /* no argument: hangup the current channel */
2450 ast_set_hangupsource(chan, "dialplan/agi", 0);
2451 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
2452 ast_agi_send(agi->fd, chan, "200 result=1\n");
2453 return RESULT_SUCCESS;
2454 } else if (argc == 2) {
2455 /* one argument: look for info on the specified channel */
2456 if ((c = ast_channel_get_by_name(argv[1]))) {
2457 /* we have a matching channel */
2458 ast_set_hangupsource(c, "dialplan/agi", 0);
2459 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
2460 c = ast_channel_unref(c);
2461 ast_agi_send(agi->fd, chan, "200 result=1\n");
2462 return RESULT_SUCCESS;
2464 /* if we get this far no channel name matched the argument given */
2465 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2466 return RESULT_SUCCESS;
2468 return RESULT_SHOWUSAGE;
2472 static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2474 int res, workaround;
2475 struct ast_app *app_to_exec;
2478 return RESULT_SHOWUSAGE;
2480 ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
2482 if ((app_to_exec = pbx_findapp(argv[1]))) {
2483 if(!strcasecmp(argv[1], PARK_APP_NAME)) {
2484 ast_masq_park_call(chan, NULL, 0, NULL);
2486 if (!(workaround = ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS))) {
2487 ast_set_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
2489 if (ast_compat_res_agi && argc >= 3 && !ast_strlen_zero(argv[2])) {
2490 char *compat = alloca(strlen(argv[2]) * 2 + 1), *cptr;
2492 for (cptr = compat, vptr = argv[2]; *vptr; vptr++) {
2496 } else if (*vptr == '|') {
2503 res = pbx_exec(chan, app_to_exec, compat);
2505 res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
2508 ast_clear_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS);
2511 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
2514 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2516 /* Even though this is wrong, users are depending upon this result. */
2520 static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2523 char *l = NULL, *n = NULL;
2526 ast_copy_string(tmp, argv[2], sizeof(tmp));
2527 ast_callerid_parse(tmp, &n, &l);
2529 ast_shrink_phone_number(l);
2534 ast_set_callerid(chan, l, n, NULL);
2537 ast_agi_send(agi->fd, chan, "200 result=1\n");
2538 return RESULT_SUCCESS;
2541 static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2543 struct ast_channel *c;
2545 /* no argument: supply info on the current channel */
2546 ast_agi_send(agi->fd, chan, "200 result=%d\n", chan->_state);
2547 return RESULT_SUCCESS;
2548 } else if (argc == 3) {
2549 /* one argument: look for info on the specified channel */
2550 if ((c = ast_channel_get_by_name(argv[2]))) {
2551 ast_agi_send(agi->fd, chan, "200 result=%d\n", c->_state);
2552 c = ast_channel_unref(c);
2553 return RESULT_SUCCESS;
2555 /* if we get this far no channel name matched the argument given */
2556 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2557 return RESULT_SUCCESS;
2559 return RESULT_SHOWUSAGE;
2563 static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2566 pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
2568 ast_agi_send(agi->fd, chan, "200 result=1\n");
2569 return RESULT_SUCCESS;
2572 static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2575 char tempstr[1024] = "";
2578 return RESULT_SHOWUSAGE;
2580 /* check if we want to execute an ast_custom_function */
2581 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
2582 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
2584 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
2588 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ret);
2590 ast_agi_send(agi->fd, chan, "200 result=0\n");
2592 return RESULT_SUCCESS;
2595 static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2597 struct ast_channel *chan2 = NULL;
2599 if (argc != 4 && argc != 5) {
2600 return RESULT_SHOWUSAGE;
2604 chan2 = ast_channel_get_by_name(argv[4]);
2606 chan2 = ast_channel_ref(chan);
2610 struct ast_str *str = ast_str_create(16);
2612 ast_agi_send(agi->fd, chan, "200 result=0\n");
2613 return RESULT_SUCCESS;
2615 ast_str_substitute_variables(&str, 0, chan2, argv[3]);
2616 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str));
2619 ast_agi_send(agi->fd, chan, "200 result=0\n");
2623 chan2 = ast_channel_unref(chan2);
2626 return RESULT_SUCCESS;
2629 static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2634 return RESULT_SHOWUSAGE;
2637 sscanf(argv[2], "%30d", &level);
2639 ast_verb(level, "%s: %s\n", chan->data, argv[1]);
2641 ast_agi_send(agi->fd, chan, "200 result=1\n");
2643 return RESULT_SUCCESS;
2646 static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2649 struct ast_str *buf;
2652 return RESULT_SHOWUSAGE;
2654 if (!(buf = ast_str_create(16))) {
2655 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2656 return RESULT_SUCCESS;
2660 res = ast_db_get(argv[2], argv[3], ast_str_buffer(buf), ast_str_size(buf));
2661 ast_str_update(buf);
2662 if (ast_str_strlen(buf) < ast_str_size(buf) - 1) {
2665 if (ast_str_make_space(&buf, ast_str_size(buf) * 2)) {
2671 ast_agi_send(agi->fd, chan, "200 result=0\n");
2673 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(buf));
2676 return RESULT_SUCCESS;
2679 static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2684 return RESULT_SHOWUSAGE;
2685 res = ast_db_put(argv[2], argv[3], argv[4]);
2686 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2687 return RESULT_SUCCESS;
2690 static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2695 return RESULT_SHOWUSAGE;
2696 res = ast_db_del(argv[2], argv[3]);
2697 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2698 return RESULT_SUCCESS;
2701 static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2705 if ((argc < 3) || (argc > 4))
2706 return RESULT_SHOWUSAGE;
2708 res = ast_db_deltree(argv[2], argv[3]);
2710 res = ast_db_deltree(argv[2], NULL);
2712 ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2713 return RESULT_SUCCESS;
2716 static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2720 e->command = "agi set debug [on|off]";
2722 "Usage: agi set debug [on|off]\n"
2723 " Enables/disables dumping of AGI transactions for\n"
2724 " debugging purposes.\n";
2731 if (a->argc != e->args)
2732 return CLI_SHOWUSAGE;
2734 if (strncasecmp(a->argv[3], "off", 3) == 0) {
2736 } else if (strncasecmp(a->argv[3], "on", 2) == 0) {
2739 return CLI_SHOWUSAGE;
2741 ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis");
2745 static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, const char * const argv[])
2747 ast_agi_send(agi->fd, chan, "200 result=0\n");
2748 return RESULT_SUCCESS;
2751 static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2754 return RESULT_SHOWUSAGE;
2756 if (!strncasecmp(argv[2], "on", 2))
2757 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
2758 else if (!strncasecmp(argv[2], "off", 3))
2760 ast_agi_send(agi->fd, chan, "200 result=0\n");
2761 return RESULT_SUCCESS;
2764 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2766 struct ast_format_cap *cap;
2767 struct ast_format tmpfmt;
2769 /* If a structure already exists, return an error */
2771 ast_agi_send(agi->fd, chan, "200 result=0\n");
2772 return RESULT_SUCCESS;
2775 if (!(cap = ast_format_cap_alloc_nolock())) {
2776 return RESULT_FAILURE;
2778 ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
2779 if ((agi->speech = ast_speech_new(argv[2], cap))) {
2780 ast_agi_send(agi->fd, chan, "200 result=1\n");
2782 ast_agi_send(agi->fd, chan, "200 result=0\n");
2784 cap = ast_format_cap_destroy(cap);
2786 return RESULT_SUCCESS;
2789 static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2791 /* Check for minimum arguments */
2793 return RESULT_SHOWUSAGE;
2795 /* Check to make sure speech structure exists */
2797 ast_agi_send(agi->fd, chan, "200 result=0\n");
2798 return RESULT_SUCCESS;
2801 ast_speech_change(agi->speech, argv[2], argv[3]);
2802 ast_agi_send(agi->fd, chan, "200 result=1\n");
2804 return RESULT_SUCCESS;
2807 static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2810 ast_speech_destroy(agi->speech);
2812 ast_agi_send(agi->fd, chan, "200 result=1\n");
2814 ast_agi_send(agi->fd, chan, "200 result=0\n");
2817 return RESULT_SUCCESS;
2820 static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2823 return RESULT_SHOWUSAGE;
2826 ast_agi_send(agi->fd, chan, "200 result=0\n");
2827 return RESULT_SUCCESS;
2830 if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
2831 ast_agi_send(agi->fd, chan, "200 result=0\n");
2833 ast_agi_send(agi->fd, chan, "200 result=1\n");
2835 return RESULT_SUCCESS;
2838 static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2841 return RESULT_SHOWUSAGE;
2844 ast_agi_send(agi->fd, chan, "200 result=0\n");
2845 return RESULT_SUCCESS;
2848 if (ast_speech_grammar_unload(agi->speech, argv[3]))
2849 ast_agi_send(agi->fd, chan, "200 result=0\n");
2851 ast_agi_send(agi->fd, chan, "200 result=1\n");
2853 return RESULT_SUCCESS;
2856 static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2859 return RESULT_SHOWUSAGE;
2862 ast_agi_send(agi->fd, chan, "200 result=0\n");
2863 return RESULT_SUCCESS;
2866 if (ast_speech_grammar_activate(agi->speech, argv[3]))
2867 ast_agi_send(agi->fd, chan, "200 result=0\n");
2869 ast_agi_send(agi->fd, chan, "200 result=1\n");
2871 return RESULT_SUCCESS;
2874 static int handle_speechdeactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2877 return RESULT_SHOWUSAGE;
2880 ast_agi_send(agi->fd, chan, "200 result=0\n");
2881 return RESULT_SUCCESS;
2884 if (ast_speech_grammar_deactivate(agi->speech, argv[3]))
2885 ast_agi_send(agi->fd, chan, "200 result=0\n");
2887 ast_agi_send(agi->fd, chan, "200 result=1\n");
2889 return RESULT_SUCCESS;
2892 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang, int offset)
2894 struct ast_filestream *fs = NULL;
2896 if (!(fs = ast_openstream(chan, filename, preflang)))
2900 ast_seekstream(fs, offset, SEEK_SET);
2902 if (ast_applystream(chan, fs))
2905 if (ast_playstream(fs))
2911 static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2913 struct ast_speech *speech = agi->speech;
2915 char dtmf = 0, tmp[4096] = "", *buf = tmp;
2916 int timeout = 0, offset = 0, res = 0, i = 0;
2917 struct ast_format old_read_format;
2918 long current_offset = 0;
2919 const char *reason = NULL;
2920 struct ast_frame *fr = NULL;
2921 struct ast_speech_result *result = NULL;
2922 size_t left = sizeof(tmp);
2923 time_t start = 0, current;
2926 return RESULT_SHOWUSAGE;
2929 ast_agi_send(agi->fd, chan, "200 result=0\n");
2930 return RESULT_SUCCESS;
2934 timeout = atoi(argv[3]);
2936 /* If offset is specified then convert from text to integer */
2938 offset = atoi(argv[4]);
2940 /* We want frames coming in signed linear */
2941 ast_format_copy(&old_read_format, &chan->readformat);
2942 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
2943 ast_agi_send(agi->fd, chan, "200 result=0\n");
2944 return RESULT_SUCCESS;
2947 /* Setup speech structure */
2948 if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
2949 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
2950 ast_speech_start(speech);
2953 /* Start playing prompt */
2954 speech_streamfile(chan, prompt, chan->language, offset);
2956 /* Go into loop reading in frames, passing to speech thingy, checking for hangup, all that jazz */
2957 while (ast_strlen_zero(reason)) {
2958 /* Run scheduled items */
2959 ast_sched_runq(chan->sched);
2961 /* See maximum time of waiting */
2962 if ((res = ast_sched_wait(chan->sched)) < 0)
2965 /* Wait for frame */
2966 if (ast_waitfor(chan, res) > 0) {
2967 if (!(fr = ast_read(chan))) {
2973 /* Perform timeout check */
2974 if ((timeout > 0) && (start > 0)) {
2976 if ((current - start) >= timeout) {
2984 /* Check the speech structure for any changes */
2985 ast_mutex_lock(&speech->lock);
2987 /* See if we need to quiet the audio stream playback */
2988 if (ast_test_flag(speech, AST_SPEECH_QUIET) && chan->stream) {
2989 current_offset = ast_tellstream(chan->stream);
2990 ast_stopstream(chan);
2991 ast_clear_flag(speech, AST_SPEECH_QUIET);
2994 /* Check each state */
2995 switch (speech->state) {
2996 case AST_SPEECH_STATE_READY:
2997 /* If the stream is done, start timeout calculation */
2998 if ((timeout > 0) && start == 0 && ((!chan->stream) || (chan->streamid == -1 && chan->timingfunc == NULL))) {
2999 ast_stopstream(chan);
3002 /* Write audio frame data into speech engine if possible */
3003 if (fr && fr->frametype == AST_FRAME_VOICE)
3004 ast_speech_write(speech, fr->data.ptr, fr->datalen);
3006 case AST_SPEECH_STATE_WAIT:
3007 /* Cue waiting sound if not already playing */
3008 if ((!chan->stream) || (chan->streamid == -1 && chan->timingfunc == NULL)) {
3009 ast_stopstream(chan);
3010 /* If a processing sound exists, or is not none - play it */
3011 if (!ast_strlen_zero(speech->processing_sound) && strcasecmp(speech->processing_sound, "none"))
3012 speech_streamfile(chan, speech->processing_sound, chan->language, 0);
3015 case AST_SPEECH_STATE_DONE:
3016 /* Get the results */
3017 speech->results = ast_speech_results_get(speech);
3018 /* Change state to not ready */
3019 ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
3025 ast_mutex_unlock(&speech->lock);
3027 /* Check frame for DTMF or hangup */
3029 if (fr->frametype == AST_FRAME_DTMF) {
3031 dtmf = fr->subclass.integer;
3032 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_HANGUP) {
3039 if (!strcasecmp(reason, "speech")) {
3040 /* Build string containing speech results */
3041 for (result = speech->results; result; result = AST_LIST_NEXT(result, list)) {
3042 /* Build result string */
3043 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);
3044 /* Increment result count */
3048 ast_agi_send(agi->fd, chan, "200 result=1 (speech) endpos=%ld results=%d %s\n", current_offset, i, tmp);
3049 } else if (!strcasecmp(reason, "dtmf")) {
3050 ast_agi_send(agi->fd, chan, "200 result=1 (digit) digit=%c endpos=%ld\n", dtmf, current_offset);
3051 } else if (!strcasecmp(reason, "hangup") || !strcasecmp(reason, "timeout")) {
3052 ast_agi_send(agi->fd, chan, "200 result=1 (%s) endpos=%ld\n", reason, current_offset);
3054 ast_agi_send(agi->fd, chan, "200 result=0 endpos=%ld\n", current_offset);
3057 return RESULT_SUCCESS;
3061 * \brief AGI commands list
3063 static struct agi_command commands[] = {
3064 { { "answer", NULL }, handle_answer, NULL, NULL, 0 },
3065 { { "asyncagi", "break", NULL }, handle_asyncagi_break, NULL, NULL, 1 },
3066 { { "channel", "status", NULL }, handle_channelstatus, NULL, NULL, 0 },
3067 { { "database", "del", NULL }, handle_dbdel, NULL, NULL, 1 },
3068 { { "database", "deltree", NULL }, handle_dbdeltree, NULL, NULL, 1 },
3069 { { "database", "get", NULL }, handle_dbget, NULL, NULL, 1 },
3070 { { "database", "put", NULL }, handle_dbput, NULL, NULL, 1 },
3071 { { "exec", NULL }, handle_exec, NULL, NULL, 1 },
3072 { { "get", "data", NULL }, handle_getdata, NULL, NULL, 0 },