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>
28 <support_level>core</support_level>
40 #include "asterisk/paths.h" /* use many ast_config_AST_*_DIR */
41 #include "asterisk/network.h"
42 #include "asterisk/file.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/pbx.h"
45 #include "asterisk/module.h"
46 #include "asterisk/astdb.h"
47 #include "asterisk/callerid.h"
48 #include "asterisk/cli.h"
49 #include "asterisk/image.h"
50 #include "asterisk/say.h"
51 #include "asterisk/app.h"
52 #include "asterisk/dsp.h"
53 #include "asterisk/musiconhold.h"
54 #include "asterisk/utils.h"
55 #include "asterisk/lock.h"
56 #include "asterisk/strings.h"
57 #include "asterisk/manager.h"
58 #include "asterisk/ast_version.h"
59 #include "asterisk/speech.h"
60 #include "asterisk/manager.h"
61 #include "asterisk/term.h"
62 #include "asterisk/xmldoc.h"
63 #include "asterisk/srv.h"
64 #include "asterisk/test.h"
65 #include "asterisk/netsock2.h"
66 #include "asterisk/stasis_channels.h"
67 #include "asterisk/stasis_message_router.h"
68 #include "asterisk/format_cache.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>
85 <ref type="application">AGI</ref>
88 <agi name="asyncagi break" language="en_US">
94 <para>Interrupts expected flow of Async AGI commands and returns control to previous source
95 (typically, the PBX dialplan).</para>
98 <ref type="agi">hangup</ref>
99 <ref type="application">AGI</ref>
102 <agi name="channel status" language="en_US">
104 Returns status of the connected channel.
107 <parameter name="channelname" />
110 <para>Returns the status of the specified <replaceable>channelname</replaceable>.
111 If no channel name is given then returns the status of the current channel.</para>
112 <para>Return values:</para>
115 <para>Channel is down and available.</para>
118 <para>Channel is down, but reserved.</para>
121 <para>Channel is off hook.</para>
124 <para>Digits (or equivalent) have been dialed.</para>
127 <para>Line is ringing.</para>
130 <para>Remote end is ringing.</para>
133 <para>Line is up.</para>
136 <para>Line is busy.</para>
141 <ref type="application">AGI</ref>
144 <agi name="control stream file" language="en_US">
146 Sends audio file on channel and allows the listener to control the stream.
149 <parameter name="filename" required="true">
150 <para>The file extension must not be included in the filename.</para>
152 <parameter name="escape_digits" required="true" />
153 <parameter name="skipms" />
154 <parameter name="ffchar">
155 <para>Defaults to <literal>#</literal></para>
157 <parameter name="rewchr">
158 <para>Defaults to <literal>*</literal></para>
160 <parameter name="pausechr" />
161 <parameter name="offsetms">
162 <para>Offset, in milliseconds, to start the audio playback</para>
166 <para>Send the given file, allowing playback to be controlled by the given
167 digits, if any. Use double quotes for the digits if you wish none to be
168 permitted. If offsetms is provided then the audio will seek to offsetms
169 before play starts. Returns <literal>0</literal> if playback completes without a digit
170 being pressed, or the ASCII numerical value of the digit if one was pressed,
171 or <literal>-1</literal> on error or if the channel was disconnected. Returns the
172 position where playback was terminated as endpos.</para>
174 <para>It sets the following channel variables upon completion:</para>
176 <variable name="CPLAYBACKSTATUS">
177 <para>Contains the status of the attempt as a text string</para>
178 <value name="SUCCESS" />
179 <value name="USERSTOPPED" />
180 <value name="REMOTESTOPPED" />
181 <value name="ERROR" />
183 <variable name="CPLAYBACKOFFSET">
184 <para>Contains the offset in ms into the file where playback
185 was at when it stopped. <literal>-1</literal> is end of file.</para>
187 <variable name="CPLAYBACKSTOPKEY">
188 <para>If the playback is stopped by the user this variable contains
189 the key that was pressed.</para>
194 <ref type="agi">get option</ref>
195 <ref type="agi">control stream file</ref>
196 <ref type="application">AGI</ref>
199 <agi name="database del" language="en_US">
201 Removes database key/value
204 <parameter name="family" required="true" />
205 <parameter name="key" required="true" />
208 <para>Deletes an entry in the Asterisk database for a given
209 <replaceable>family</replaceable> and <replaceable>key</replaceable>.</para>
210 <para>Returns <literal>1</literal> if successful, <literal>0</literal>
214 <ref type="agi">database get</ref>
215 <ref type="agi">database put</ref>
216 <ref type="agi">database deltree</ref>
217 <ref type="application">AGI</ref>
220 <agi name="database deltree" language="en_US">
222 Removes database keytree/value
225 <parameter name="family" required="true" />
226 <parameter name="keytree" />
229 <para>Deletes a <replaceable>family</replaceable> or specific <replaceable>keytree</replaceable>
230 within a <replaceable>family</replaceable> in the Asterisk database.</para>
231 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
234 <ref type="agi">database get</ref>
235 <ref type="agi">database put</ref>
236 <ref type="agi">database del</ref>
237 <ref type="application">AGI</ref>
240 <agi name="database get" language="en_US">
245 <parameter name="family" required="true" />
246 <parameter name="key" required="true" />
249 <para>Retrieves an entry in the Asterisk database for a given <replaceable>family</replaceable>
250 and <replaceable>key</replaceable>.</para>
251 <para>Returns <literal>0</literal> if <replaceable>key</replaceable> is not set.
252 Returns <literal>1</literal> if <replaceable>key</replaceable> is set and returns the variable
253 in parenthesis.</para>
254 <para>Example return code: 200 result=1 (testvariable)</para>
257 <ref type="agi">database put</ref>
258 <ref type="agi">database del</ref>
259 <ref type="agi">database deltree</ref>
260 <ref type="application">AGI</ref>
263 <agi name="database put" language="en_US">
265 Adds/updates database value
268 <parameter name="family" required="true" />
269 <parameter name="key" required="true" />
270 <parameter name="value" required="true" />
273 <para>Adds or updates an entry in the Asterisk database for a given
274 <replaceable>family</replaceable>, <replaceable>key</replaceable>, and
275 <replaceable>value</replaceable>.</para>
276 <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
279 <ref type="agi">database get</ref>
280 <ref type="agi">database del</ref>
281 <ref type="agi">database deltree</ref>
282 <ref type="application">AGI</ref>
285 <agi name="exec" language="en_US">
287 Executes a given Application
290 <parameter name="application" required="true" />
291 <parameter name="options" required="true" />
294 <para>Executes <replaceable>application</replaceable> with given
295 <replaceable>options</replaceable>.</para>
296 <para>Returns whatever the <replaceable>application</replaceable> returns, or
297 <literal>-2</literal> on failure to find <replaceable>application</replaceable>.</para>
300 <ref type="application">AGI</ref>
303 <agi name="get data" language="en_US">
305 Prompts for DTMF on a channel
308 <parameter name="file" required="true" />
309 <parameter name="timeout" />
310 <parameter name="maxdigits" />
313 <para>Stream the given <replaceable>file</replaceable>, and receive DTMF data.</para>
314 <para>Returns the digits received from the channel at the other end.</para>
317 <ref type="application">AGI</ref>
320 <agi name="get full variable" language="en_US">
322 Evaluates a channel expression
325 <parameter name="variablename" required="true" />
326 <parameter name="channel name" />
329 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set
330 or channel does not exist. Returns <literal>1</literal> if <replaceable>variablename</replaceable>
331 is set and returns the variable in parenthesis. Understands complex variable names and builtin
332 variables, unlike GET VARIABLE.</para>
333 <para>Example return code: 200 result=1 (testvariable)</para>
336 <ref type="agi">get variable</ref>
337 <ref type="agi">set variable</ref>
338 <ref type="application">AGI</ref>
341 <agi name="get option" language="en_US">
343 Stream file, prompt for DTMF, with timeout.
346 <parameter name="filename" required="true" />
347 <parameter name="escape_digits" required="true" />
348 <parameter name="timeout" />
351 <para>Behaves similar to STREAM FILE but used with a timeout option.</para>
354 <ref type="agi">stream file</ref>
355 <ref type="agi">control stream file</ref>
356 <ref type="application">AGI</ref>
359 <agi name="get variable" language="en_US">
361 Gets a channel variable.
364 <parameter name="variablename" required="true" />
367 <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set.
368 Returns <literal>1</literal> if <replaceable>variablename</replaceable> is set and returns
369 the variable in parentheses.</para>
370 <para>Example return code: 200 result=1 (testvariable)</para>
373 <ref type="agi">get full variable</ref>
374 <ref type="agi">set variable</ref>
375 <ref type="application">AGI</ref>
378 <agi name="hangup" language="en_US">
383 <parameter name="channelname" />
386 <para>Hangs up the specified channel. If no channel name is given, hangs
387 up the current channel</para>
390 <ref type="application">AGI</ref>
393 <agi name="noop" language="en_US">
399 <para>Does nothing.</para>
402 <ref type="application">AGI</ref>
405 <agi name="receive char" language="en_US">
407 Receives one character from channels supporting it.
410 <parameter name="timeout" required="true">
411 <para>The maximum time to wait for input in milliseconds, or <literal>0</literal>
412 for infinite. Most channels</para>
416 <para>Receives a character of text on a channel. Most channels do not support
417 the reception of text. Returns the decimal value of the character
418 if one is received, or <literal>0</literal> if the channel does not support
419 text reception. Returns <literal>-1</literal> only on error/hangup.</para>
422 <ref type="agi">receive text</ref>
423 <ref type="application">AGI</ref>
426 <agi name="receive text" language="en_US">
428 Receives text from channels supporting it.
431 <parameter name="timeout" required="true">
432 <para>The timeout to be the maximum time to wait for input in
433 milliseconds, or <literal>0</literal> for infinite.</para>
437 <para>Receives a string of text on a channel. Most channels
438 do not support the reception of text. Returns <literal>-1</literal> for failure
439 or <literal>1</literal> for success, and the string in parenthesis.</para>
442 <ref type="agi">receive char</ref>
443 <ref type="agi">send text</ref>
444 <ref type="application">AGI</ref>
447 <agi name="record file" language="en_US">
449 Records to a given file.
452 <parameter name="filename" required="true">
453 <para>The destination filename of the recorded audio.</para>
455 <parameter name="format" required="true">
456 <para>The audio format in which to save the resulting file.</para>
458 <parameter name="escape_digits" required="true">
459 <para>The DTMF digits that will terminate the recording process.</para>
461 <parameter name="timeout" required="true">
462 <para>The maximum recording time in milliseconds. Set to -1 for no
465 <parameter name="offset_samples">
466 <para>Causes the recording to first seek to the specified offset before
467 recording begins.</para>
469 <parameter name="beep">
470 <para>Causes Asterisk to play a beep as recording begins. This argument
471 can take any value.</para>
473 <parameter name="s=silence">
474 <para>The number of seconds of silence that are permitted before the
475 recording is terminated, regardless of the
476 <replaceable>escape_digits</replaceable> or <replaceable>timeout</replaceable>
477 arguments. If specified, this parameter must be preceded by
478 <literal>s=</literal>.</para>
482 <para>Record to a file until a given dtmf digit in the sequence is received.
483 Returns <literal>-1</literal> on hangup or error. The format will specify what kind of file
484 will be recorded. The <replaceable>timeout</replaceable> is the maximum record time in
485 milliseconds, or <literal>-1</literal> for no <replaceable>timeout</replaceable>.
486 <replaceable>offset samples</replaceable> is optional, and, if provided, will seek
487 to the offset without exceeding the end of the
488 file. <replaceable>beep</replaceable> can take any value, and causes Asterisk
489 to play a beep to the channel that is about to be recorded. <replaceable>silence</replaceable> is
490 the number of seconds of silence allowed before the function returns despite the
491 lack of dtmf digits or reaching <replaceable>timeout</replaceable>. <replaceable>silence</replaceable>
492 value must be preceded by <literal>s=</literal> and is also optional.</para>
495 <ref type="application">AGI</ref>
498 <agi name="say alpha" language="en_US">
500 Says a given character string.
503 <parameter name="number" required="true" />
504 <parameter name="escape_digits" required="true" />
507 <para>Say a given character string, returning early if any of the given DTMF digits
508 are received on the channel. Returns <literal>0</literal> if playback completes
509 without a digit being pressed, or the ASCII numerical value of the digit if one
510 was pressed or <literal>-1</literal> on error/hangup.</para>
513 <ref type="agi">say digits</ref>
514 <ref type="agi">say number</ref>
515 <ref type="agi">say phonetic</ref>
516 <ref type="agi">say date</ref>
517 <ref type="agi">say time</ref>
518 <ref type="agi">say datetime</ref>
519 <ref type="application">AGI</ref>
522 <agi name="say digits" language="en_US">
524 Says a given digit string.
527 <parameter name="number" required="true" />
528 <parameter name="escape_digits" required="true" />
531 <para>Say a given digit string, returning early if any of the given DTMF digits
532 are received on the channel. Returns <literal>0</literal> if playback completes
533 without a digit being pressed, or the ASCII numerical value of the digit if one
534 was pressed or <literal>-1</literal> on error/hangup.</para>
537 <ref type="agi">say alpha</ref>
538 <ref type="agi">say number</ref>
539 <ref type="agi">say phonetic</ref>
540 <ref type="agi">say date</ref>
541 <ref type="agi">say time</ref>
542 <ref type="agi">say datetime</ref>
543 <ref type="application">AGI</ref>
546 <agi name="say number" language="en_US">
551 <parameter name="number" required="true" />
552 <parameter name="escape_digits" required="true" />
553 <parameter name="gender" />
556 <para>Say a given number, returning early if any of the given DTMF digits
557 are received on the channel. Returns <literal>0</literal> if playback
558 completes without a digit being pressed, or the ASCII numerical value of
559 the digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
562 <ref type="agi">say alpha</ref>
563 <ref type="agi">say digits</ref>
564 <ref type="agi">say phonetic</ref>
565 <ref type="agi">say date</ref>
566 <ref type="agi">say time</ref>
567 <ref type="agi">say datetime</ref>
568 <ref type="application">AGI</ref>
571 <agi name="say phonetic" language="en_US">
573 Says a given character string with phonetics.
576 <parameter name="string" required="true" />
577 <parameter name="escape_digits" required="true" />
580 <para>Say a given character string with phonetics, returning early if any of the
581 given DTMF digits are received on the channel. Returns <literal>0</literal> if
582 playback completes without a digit pressed, the ASCII numerical value of the digit
583 if one was pressed, or <literal>-1</literal> on error/hangup.</para>
586 <ref type="agi">say alpha</ref>
587 <ref type="agi">say digits</ref>
588 <ref type="agi">say number</ref>
589 <ref type="agi">say date</ref>
590 <ref type="agi">say time</ref>
591 <ref type="agi">say datetime</ref>
592 <ref type="application">AGI</ref>
595 <agi name="say date" language="en_US">
600 <parameter name="date" required="true">
601 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
602 Coordinated Universal Time (UTC).</para>
604 <parameter name="escape_digits" required="true" />
607 <para>Say a given date, returning early if any of the given DTMF digits are
608 received on the channel. Returns <literal>0</literal> if playback
609 completes without a digit being pressed, or the ASCII numerical value of the
610 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
613 <ref type="agi">say alpha</ref>
614 <ref type="agi">say digits</ref>
615 <ref type="agi">say number</ref>
616 <ref type="agi">say phonetic</ref>
617 <ref type="agi">say time</ref>
618 <ref type="agi">say datetime</ref>
619 <ref type="application">AGI</ref>
622 <agi name="say time" language="en_US">
627 <parameter name="time" required="true">
628 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
629 Coordinated Universal Time (UTC).</para>
631 <parameter name="escape_digits" required="true" />
634 <para>Say a given time, returning early if any of the given DTMF digits are
635 received on the channel. Returns <literal>0</literal> if playback completes
636 without a digit being pressed, or the ASCII numerical value of the digit if
637 one was pressed or <literal>-1</literal> on error/hangup.</para>
640 <ref type="agi">say alpha</ref>
641 <ref type="agi">say digits</ref>
642 <ref type="agi">say number</ref>
643 <ref type="agi">say phonetic</ref>
644 <ref type="agi">say date</ref>
645 <ref type="agi">say datetime</ref>
646 <ref type="application">AGI</ref>
649 <agi name="say datetime" language="en_US">
651 Says a given time as specified by the format given.
654 <parameter name="time" required="true">
655 <para>Is number of seconds elapsed since 00:00:00
656 on January 1, 1970, Coordinated Universal Time (UTC)</para>
658 <parameter name="escape_digits" required="true" />
659 <parameter name="format">
660 <para>Is the format the time should be said in. See
661 <filename>voicemail.conf</filename> (defaults to <literal>ABdY
662 'digits/at' IMp</literal>).</para>
664 <parameter name="timezone">
665 <para>Acceptable values can be found in <filename>/usr/share/zoneinfo</filename>
666 Defaults to machine default.</para>
670 <para>Say a given time, returning early if any of the given DTMF digits are
671 received on the channel. Returns <literal>0</literal> if playback
672 completes without a digit being pressed, or the ASCII numerical value of the
673 digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
676 <ref type="agi">say alpha</ref>
677 <ref type="agi">say digits</ref>
678 <ref type="agi">say number</ref>
679 <ref type="agi">say phonetic</ref>
680 <ref type="agi">say date</ref>
681 <ref type="agi">say time</ref>
682 <ref type="application">AGI</ref>
685 <agi name="send image" language="en_US">
687 Sends images to channels supporting it.
690 <parameter name="image" required="true" />
693 <para>Sends the given image on a channel. Most channels do not support the
694 transmission of images. Returns <literal>0</literal> if image is sent, or if
695 the channel does not support image transmission. Returns <literal>-1</literal>
696 only on error/hangup. Image names should not include extensions.</para>
699 <ref type="application">AGI</ref>
702 <agi name="send text" language="en_US">
704 Sends text to channels supporting it.
707 <parameter name="text to send" required="true">
708 <para>Text consisting of greater than one word should be placed
709 in quotes since the command only accepts a single argument.</para>
713 <para>Sends the given text on a channel. Most channels do not support the
714 transmission of text. Returns <literal>0</literal> if text is sent, or if the
715 channel does not support text transmission. Returns <literal>-1</literal> only
716 on error/hangup.</para>
719 <ref type="agi">receive text</ref>
720 <ref type="application">AGI</ref>
723 <agi name="set autohangup" language="en_US">
725 Autohangup channel in some time.
728 <parameter name="time" required="true" />
731 <para>Cause the channel to automatically hangup at <replaceable>time</replaceable>
732 seconds in the future. Of course it can be hungup before then as well. Setting to
733 <literal>0</literal> will cause the autohangup feature to be disabled on this channel.</para>
736 <ref type="application">AGI</ref>
739 <agi name="set callerid" language="en_US">
741 Sets callerid for the current channel.
744 <parameter name="number" required="true" />
747 <para>Changes the callerid of the current channel.</para>
750 <ref type="application">AGI</ref>
753 <agi name="set context" language="en_US">
755 Sets channel context.
758 <parameter name="desired context" required="true" />
761 <para>Sets the context for continuation upon exiting the application.</para>
764 <ref type="agi">set extension</ref>
765 <ref type="agi">set priority</ref>
766 <ref type="application">AGI</ref>
769 <agi name="set extension" language="en_US">
771 Changes channel extension.
774 <parameter name="new extension" required="true" />
777 <para>Changes the extension for continuation upon exiting the application.</para>
780 <ref type="agi">set context</ref>
781 <ref type="agi">set priority</ref>
782 <ref type="application">AGI</ref>
785 <agi name="set music" language="en_US">
787 Enable/Disable Music on hold generator
790 <parameter required="true">
793 <parameter name="on" literal="true" required="true" />
796 <parameter name="off" literal="true" required="true" />
800 <parameter name="class" required="true" />
803 <para>Enables/Disables the music on hold generator. If <replaceable>class</replaceable>
804 is not specified, then the <literal>default</literal> music on hold class will be
805 used. This generator will be stopped automatically when playing a file.</para>
806 <para>Always returns <literal>0</literal>.</para>
809 <ref type="application">AGI</ref>
812 <agi name="set priority" language="en_US">
814 Set channel dialplan priority.
817 <parameter name="priority" required="true" />
820 <para>Changes the priority for continuation upon exiting the application.
821 The priority must be a valid priority or label.</para>
824 <ref type="agi">set context</ref>
825 <ref type="agi">set extension</ref>
826 <ref type="application">AGI</ref>
829 <agi name="set variable" language="en_US">
831 Sets a channel variable.
834 <parameter name="variablename" required="true" />
835 <parameter name="value" required="true" />
838 <para>Sets a variable to the current channel.</para>
841 <ref type="agi">get variable</ref>
842 <ref type="agi">get full variable</ref>
843 <ref type="application">AGI</ref>
846 <agi name="stream file" language="en_US">
848 Sends audio file on channel.
851 <parameter name="filename" required="true">
852 <para>File name to play. The file extension must not be
853 included in the <replaceable>filename</replaceable>.</para>
855 <parameter name="escape_digits" required="true">
856 <para>Use double quotes for the digits if you wish none to be
859 <parameter name="sample offset">
860 <para>If sample offset is provided then the audio will seek to sample
861 offset before play starts.</para>
865 <para>Send the given file, allowing playback to be interrupted by the given
866 digits, if any. Returns <literal>0</literal> if playback completes without a digit
867 being pressed, or the ASCII numerical value of the digit if one was pressed,
868 or <literal>-1</literal> on error or if the channel was disconnected. If
869 musiconhold is playing before calling stream file it will be automatically
870 stopped and will not be restarted after completion.</para>
871 <para>It sets the following channel variables upon completion:</para>
873 <variable name="PLAYBACKSTATUS">
874 <para>The status of the playback attempt as a text string.</para>
875 <value name="SUCCESS"/>
876 <value name="FAILED"/>
881 <ref type="agi">control stream file</ref>
882 <ref type="agi">get option</ref>
883 <ref type="application">AGI</ref>
886 <agi name="tdd mode" language="en_US">
888 Toggles TDD mode (for the deaf).
891 <parameter name="boolean" required="true">
899 <para>Enable/Disable TDD transmission/reception on a channel. Returns <literal>1</literal> if
900 successful, or <literal>0</literal> if channel is not TDD-capable.</para>
903 <ref type="application">AGI</ref>
906 <agi name="verbose" language="en_US">
908 Logs a message to the asterisk verbose log.
911 <parameter name="message" required="true" />
912 <parameter name="level" required="true" />
915 <para>Sends <replaceable>message</replaceable> to the console via verbose
916 message system. <replaceable>level</replaceable> is the verbose level (1-4).
917 Always returns <literal>1</literal></para>
920 <ref type="application">AGI</ref>
923 <agi name="wait for digit" language="en_US">
925 Waits for a digit to be pressed.
928 <parameter name="timeout" required="true" />
931 <para>Waits up to <replaceable>timeout</replaceable> milliseconds for channel to
932 receive a DTMF digit. Returns <literal>-1</literal> on channel failure, <literal>0</literal>
933 if no digit is received in the timeout, or the numerical value of the ascii of the digit if
934 one is received. Use <literal>-1</literal> for the <replaceable>timeout</replaceable> value if
935 you desire the call to block indefinitely.</para>
938 <ref type="application">AGI</ref>
941 <agi name="speech create" language="en_US">
943 Creates a speech object.
946 <parameter name="engine" required="true" />
949 <para>Create a speech object to be used by the other Speech AGI commands.</para>
952 <ref type="agi">speech set</ref>
953 <ref type="agi">speech destroy</ref>
954 <ref type="agi">speech load grammar</ref>
955 <ref type="agi">speech unload grammar</ref>
956 <ref type="agi">speech activate grammar</ref>
957 <ref type="agi">speech deactivate grammar</ref>
958 <ref type="agi">speech recognize</ref>
959 <ref type="application">AGI</ref>
962 <agi name="speech set" language="en_US">
964 Sets a speech engine setting.
967 <parameter name="name" required="true" />
968 <parameter name="value" required="true" />
971 <para>Set an engine-specific setting.</para>
974 <ref type="agi">speech create</ref>
975 <ref type="agi">speech destroy</ref>
976 <ref type="agi">speech load grammar</ref>
977 <ref type="agi">speech unload grammar</ref>
978 <ref type="agi">speech activate grammar</ref>
979 <ref type="agi">speech deactivate grammar</ref>
980 <ref type="agi">speech recognize</ref>
981 <ref type="application">AGI</ref>
984 <agi name="speech destroy" language="en_US">
986 Destroys a speech object.
991 <para>Destroy the speech object created by <literal>SPEECH CREATE</literal>.</para>
994 <ref type="agi">speech create</ref>
995 <ref type="agi">speech set</ref>
996 <ref type="agi">speech load grammar</ref>
997 <ref type="agi">speech unload grammar</ref>
998 <ref type="agi">speech activate grammar</ref>
999 <ref type="agi">speech deactivate grammar</ref>
1000 <ref type="agi">speech recognize</ref>
1001 <ref type="application">AGI</ref>
1004 <agi name="speech load grammar" language="en_US">
1009 <parameter name="grammar name" required="true" />
1010 <parameter name="path to grammar" required="true" />
1013 <para>Loads the specified grammar as the specified name.</para>
1016 <ref type="agi">speech create</ref>
1017 <ref type="agi">speech set</ref>
1018 <ref type="agi">speech destroy</ref>
1019 <ref type="agi">speech unload grammar</ref>
1020 <ref type="agi">speech activate grammar</ref>
1021 <ref type="agi">speech deactivate grammar</ref>
1022 <ref type="agi">speech recognize</ref>
1023 <ref type="application">AGI</ref>
1026 <agi name="speech unload grammar" language="en_US">
1031 <parameter name="grammar name" required="true" />
1034 <para>Unloads the specified grammar.</para>
1037 <ref type="agi">speech create</ref>
1038 <ref type="agi">speech set</ref>
1039 <ref type="agi">speech destroy</ref>
1040 <ref type="agi">speech load grammar</ref>
1041 <ref type="agi">speech activate grammar</ref>
1042 <ref type="agi">speech deactivate grammar</ref>
1043 <ref type="agi">speech recognize</ref>
1044 <ref type="application">AGI</ref>
1047 <agi name="speech activate grammar" language="en_US">
1049 Activates a grammar.
1052 <parameter name="grammar name" required="true" />
1055 <para>Activates the specified grammar on the speech object.</para>
1058 <ref type="agi">speech create</ref>
1059 <ref type="agi">speech set</ref>
1060 <ref type="agi">speech destroy</ref>
1061 <ref type="agi">speech load grammar</ref>
1062 <ref type="agi">speech unload grammar</ref>
1063 <ref type="agi">speech deactivate grammar</ref>
1064 <ref type="agi">speech recognize</ref>
1065 <ref type="application">AGI</ref>
1068 <agi name="speech deactivate grammar" language="en_US">
1070 Deactivates a grammar.
1073 <parameter name="grammar name" required="true" />
1076 <para>Deactivates the specified grammar on the speech object.</para>
1079 <ref type="agi">speech create</ref>
1080 <ref type="agi">speech set</ref>
1081 <ref type="agi">speech destroy</ref>
1082 <ref type="agi">speech load grammar</ref>
1083 <ref type="agi">speech unload grammar</ref>
1084 <ref type="agi">speech activate grammar</ref>
1085 <ref type="agi">speech recognize</ref>
1086 <ref type="application">AGI</ref>
1089 <agi name="speech recognize" language="en_US">
1094 <parameter name="prompt" required="true" />
1095 <parameter name="timeout" required="true" />
1096 <parameter name="offset" />
1099 <para>Plays back given <replaceable>prompt</replaceable> while listening for
1100 speech and dtmf.</para>
1103 <ref type="agi">speech create</ref>
1104 <ref type="agi">speech set</ref>
1105 <ref type="agi">speech destroy</ref>
1106 <ref type="agi">speech load grammar</ref>
1107 <ref type="agi">speech unload grammar</ref>
1108 <ref type="agi">speech activate grammar</ref>
1109 <ref type="agi">speech deactivate grammar</ref>
1110 <ref type="application">AGI</ref>
1113 <application name="AGI" language="en_US">
1115 Executes an AGI compliant application.
1118 <parameter name="command" required="true">
1119 <para>How AGI should be invoked on the channel.</para>
1121 <parameter name="args">
1122 <para>Arguments to pass to the AGI script or server.</para>
1123 <argument name="arg1" required="true" />
1124 <argument name="arg2" multiple="yes" />
1128 <para>Executes an Asterisk Gateway Interface compliant
1129 program on a channel. AGI allows Asterisk to launch external programs written
1130 in any language to control a telephony channel, play audio, read DTMF digits,
1131 etc. by communicating with the AGI protocol.</para>
1132 <para>The following variants of AGI exist, and are chosen based on the value
1133 passed to <replaceable>command</replaceable>:</para>
1136 <para>The classic variant of AGI, this will launch the script
1137 specified by <replaceable>command</replaceable> as a new process.
1138 Communication with the script occurs on <literal>stdin</literal> and
1139 <literal>stdout</literal>. If the full path to the script is not
1140 provided, the <directory>astagidir</directory> specified in
1141 <filename>asterisk.conf</filename> will be used.
1144 <enum name="FastAGI">
1145 <para>Connect Asterisk to a FastAGI server using a TCP connection.
1146 The URI to the FastAGI server should be given in the form
1147 <literal>[scheme]://host.domain[:port][/script/name]</literal>,
1148 where <replaceable>scheme</replaceable> is either <literal>agi</literal>
1149 or <literal>hagi</literal>.</para>
1150 <para>In the case of <literal>hagi</literal>, an SRV lookup will be
1151 performed to try to connect to a list of FastAGI servers. The hostname in
1152 the URI must be prefixed with <literal>_agi._tcp</literal>. prior to the DNS resolution. For
1153 example, if you specify the URI <literal>hagi://agi.example.com/foo.agi</literal>
1154 the DNS query would be for <literal>_agi._tcp.agi.example.com</literal>. You
1155 will need to make sure this resolves correctly.</para>
1157 <enum name="AsyncAGI">
1158 <para>Use AMI to control the channel in AGI. AGI commands can be invoked
1159 using the <literal>AMI</literal> action, with a variety of AGI specific
1160 events passed back over the AMI connection. AsyncAGI should be invoked
1161 by passing <literal>agi:async</literal> to the <replaceable>command</replaceable>
1166 <para>As of <literal>1.6.0</literal>, this channel will
1167 not stop dialplan execution on hangup inside of this application. Dialplan
1168 execution will continue normally, even upon hangup until the AGI application
1169 signals a desire to stop (either by exiting or, in the case of a net script, by
1170 closing the connection).</para>
1171 <para>A locally executed AGI script will receive <literal>SIGHUP</literal> on
1172 hangup from the channel except when using <literal>DeadAGI</literal>
1173 (or when the channel is already hungup). A fast AGI server will
1174 correspondingly receive a <literal>HANGUP</literal> inline with the command dialog.
1175 Both of these signals may be disabled by setting the <variable>AGISIGHUP</variable>
1176 channel variable to <literal>no</literal> before executing the AGI application.
1177 Alternatively, if you would like the AGI application to exit immediately
1178 after a channel hangup is detected, set the <variable>AGIEXITONHANGUP</variable>
1179 variable to <literal>yes</literal>.</para>
1181 <example title="AGI invocation examples">
1182 ; Start the AGI script /tmp/my-cool-script.sh, passing it the contents
1183 ; of the channel variable FOO
1184 same => n,AGI(/tmp/my-cool-script.sh,${FOO})
1186 ; Start the AGI script my-cool-script.sh located in the astagidir
1187 ; directory, specified in asterisk.conf
1188 same => n,AGI(my-cool-script.sh)
1190 ; Connect to the FastAGI server located at 127.0.0.1 and start the script
1192 same => n,AGI(agi://127.0.0.1/awesome-script)
1195 same => n,AGI(agi:async)
1197 <para>This application sets the following channel variable upon completion:</para>
1199 <variable name="AGISTATUS">
1200 <para>The status of the attempt to the run the AGI script
1201 text string, one of:</para>
1202 <value name="SUCCESS" />
1203 <value name="FAILURE" />
1204 <value name="NOTFOUND" />
1205 <value name="HANGUP" />
1210 <ref type="manager">AGI</ref>
1211 <ref type="managerEvent">AsyncAGIStart</ref>
1212 <ref type="managerEvent">AsyncAGIEnd</ref>
1213 <ref type="application">EAGI</ref>
1214 <ref type="application">DeadAGI</ref>
1215 <ref type="filename">asterisk.conf</ref>
1218 <application name="EAGI" language="en_US">
1220 Executes an EAGI compliant application.
1223 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
1224 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
1227 <para>Using 'EAGI' provides enhanced AGI, with incoming audio available out of band
1228 on file descriptor 3. In all other respects, it behaves in the same fashion as
1229 AGI. See the documentation for the <literal>AGI</literal> dialplan application for
1230 more information on invoking AGI on a channel.</para>
1231 <para>This application sets the following channel variable upon completion:</para>
1232 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
1235 <ref type="application">AGI</ref>
1236 <ref type="application">DeadAGI</ref>
1239 <application name="DeadAGI" language="en_US">
1241 Executes AGI on a hungup channel.
1244 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
1245 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
1249 <para>This application is deprecated and may be removed in a future version
1250 of Asterisk. Use the replacement application <literal>AGI</literal> instead
1251 of <literal>DeadAGI</literal>.
1254 <para>Execute AGI on a 'dead' or hungup channel. See the documentation for the
1255 <literal>AGI</literal> dialplan application for more information on invoking
1256 AGI on a channel.</para>
1257 <para>This application sets the following channel variable upon completion:</para>
1258 <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
1261 <ref type="application">AGI</ref>
1262 <ref type="application">EAGI</ref>
1265 <manager name="AGI" language="en_US">
1267 Add an AGI command to execute by Async AGI.
1270 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
1271 <parameter name="Channel" required="true">
1272 <para>Channel that is currently in Async AGI.</para>
1274 <parameter name="Command" required="true">
1275 <para>Application to execute.</para>
1277 <parameter name="CommandID">
1278 <para>This will be sent back in CommandID header of AsyncAGI exec
1279 event notification.</para>
1283 <para>Add an AGI command to the execute queue of the channel in Async AGI.</para>
1286 <ref type="managerEvent">AsyncAGIStart</ref>
1287 <ref type="managerEvent">AsyncAGIExec</ref>
1288 <ref type="managerEvent">AsyncAGIEnd</ref>
1291 <managerEvent language="en_US" name="AsyncAGIStart">
1292 <managerEventInstance class="EVENT_FLAG_AGI">
1293 <synopsis>Raised when a channel starts AsyncAGI command processing.</synopsis>
1296 <parameter name="Env">
1297 <para>URL encoded string read from the AsyncAGI server.</para>
1301 <ref type="managerEvent">AsyncAGIEnd</ref>
1302 <ref type="managerEvent">AsyncAGIExec</ref>
1303 <ref type="application">AGI</ref>
1304 <ref type="manager">AGI</ref>
1306 </managerEventInstance>
1308 <managerEvent language="en_US" name="AsyncAGIEnd">
1309 <managerEventInstance class="EVENT_FLAG_AGI">
1310 <synopsis>Raised when a channel stops AsyncAGI command processing.</synopsis>
1315 <ref type="managerEvent">AsyncAGIStart</ref>
1316 <ref type="managerEvent">AsyncAGIExec</ref>
1317 <ref type="application">AGI</ref>
1318 <ref type="manager">AGI</ref>
1320 </managerEventInstance>
1322 <managerEvent language="en_US" name="AsyncAGIExec">
1323 <managerEventInstance class="EVENT_FLAG_AGI">
1324 <synopsis>Raised when AsyncAGI completes an AGI command.</synopsis>
1327 <parameter name="CommandID" required="false">
1328 <para>Optional command ID sent by the AsyncAGI server to identify the command.</para>
1330 <parameter name="Result">
1331 <para>URL encoded result string from the executed AGI command.</para>
1335 <ref type="managerEvent">AsyncAGIStart</ref>
1336 <ref type="managerEvent">AsyncAGIEnd</ref>
1337 <ref type="application">AGI</ref>
1338 <ref type="manager">AGI</ref>
1340 </managerEventInstance>
1342 <managerEvent language="en_US" name="AGIExecStart">
1343 <managerEventInstance class="EVENT_FLAG_AGI">
1344 <synopsis>Raised when a received AGI command starts processing.</synopsis>
1347 <parameter name="Command">
1348 <para>The AGI command as received from the external source.</para>
1350 <parameter name="CommandId">
1351 <para>Random identification number assigned to the execution of this command.</para>
1355 <ref type="managerEvent">AGIExecEnd</ref>
1356 <ref type="application">AGI</ref>
1358 </managerEventInstance>
1360 <managerEvent language="en_US" name="AGIExecEnd">
1361 <managerEventInstance class="EVENT_FLAG_AGI">
1362 <synopsis>Raised when a received AGI command completes processing.</synopsis>
1365 <xi:include xpointer="xpointer(/docs/managerEvent[@name='AGIExecStart']/managerEventInstance/syntax/parameter)" />
1366 <parameter name="ResultCode">
1367 <para>The numeric result code from AGI</para>
1369 <parameter name="Result">
1370 <para>The text result reason from AGI</para>
1374 <ref type="managerEvent">AGIExecStart</ref>
1375 <ref type="application">AGI</ref>
1377 </managerEventInstance>
1381 #define MAX_ARGS 128
1382 #define MAX_CMD_LEN 80
1383 #define AGI_NANDFS_RETRY 3
1384 #define AGI_BUF_LEN 2048
1385 #define SRV_PREFIX "_agi._tcp."
1387 static char *app = "AGI";
1389 static char *eapp = "EAGI";
1391 static char *deadapp = "DeadAGI";
1393 static int agidebug = 0;
1395 #define TONE_BLOCK_SIZE 200
1397 /* Max time to connect to an AGI remote host */
1398 #define MAX_AGI_CONNECT 2000
1400 #define AGI_PORT 4573
1402 /*! Special return code for "asyncagi break" command. */
1403 #define ASYNC_AGI_BREAK 3
1406 AGI_RESULT_FAILURE = -1,
1408 AGI_RESULT_SUCCESS_FAST,
1409 AGI_RESULT_SUCCESS_ASYNC,
1410 AGI_RESULT_NOTFOUND,
1414 static struct ast_manager_event_blob *agi_channel_to_ami(const char *type, struct stasis_message *message)
1416 struct ast_channel_blob *obj = stasis_message_data(message);
1417 RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
1418 RAII_VAR(struct ast_str *, event_string, NULL, ast_free);
1420 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1421 event_string = ast_manager_str_from_json_object(obj->blob, NULL);
1422 if (!channel_string || !event_string) {
1426 return ast_manager_event_blob_create(EVENT_FLAG_AGI, type,
1429 ast_str_buffer(channel_string),
1430 ast_str_buffer(event_string));
1433 static struct ast_manager_event_blob *agi_exec_start_to_ami(struct stasis_message *message)
1435 return agi_channel_to_ami("AGIExecStart", message);
1438 static struct ast_manager_event_blob *agi_exec_end_to_ami(struct stasis_message *message)
1440 return agi_channel_to_ami("AGIExecEnd", message);
1443 static struct ast_manager_event_blob *agi_async_start_to_ami(struct stasis_message *message)
1445 return agi_channel_to_ami("AsyncAGIStart", message);
1448 static struct ast_manager_event_blob *agi_async_exec_to_ami(struct stasis_message *message)
1450 return agi_channel_to_ami("AsyncAGIExec", message);
1453 static struct ast_manager_event_blob *agi_async_end_to_ami(struct stasis_message *message)
1455 return agi_channel_to_ami("AsyncAGIEnd", message);
1458 STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_exec_start_type,
1459 .to_ami = agi_exec_start_to_ami,
1461 STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_exec_end_type,
1462 .to_ami = agi_exec_end_to_ami,
1464 STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_start_type,
1465 .to_ami = agi_async_start_to_ami,
1467 STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_exec_type,
1468 .to_ami = agi_async_exec_to_ami,
1470 STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_end_type,
1471 .to_ami = agi_async_end_to_ami,
1474 static agi_command *find_command(const char * const cmds[], int exact);
1476 AST_THREADSTORAGE(agi_buf);
1477 #define AGI_BUF_INITSIZE 256
1479 int AST_OPTIONAL_API_NAME(ast_agi_send)(int fd, struct ast_channel *chan, char *fmt, ...)
1483 struct ast_str *buf;
1485 if (!(buf = ast_str_thread_get(&agi_buf, AGI_BUF_INITSIZE)))
1489 res = ast_str_set_va(&buf, 0, fmt, ap);
1493 ast_log(LOG_ERROR, "Out of memory\n");
1499 ast_verbose("<%s>AGI Tx >> %s", ast_channel_name(chan), ast_str_buffer(buf));
1501 ast_verbose("AGI Tx >> %s", ast_str_buffer(buf));
1505 return ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
1508 /* linked list of AGI commands ready to be executed by Async AGI */
1512 AST_LIST_ENTRY(agi_cmd) entry;
1515 static void free_agi_cmd(struct agi_cmd *cmd)
1517 ast_free(cmd->cmd_buffer);
1518 ast_free(cmd->cmd_id);
1522 /* AGI datastore destructor */
1523 static void agi_destroy_commands_cb(void *data)
1525 struct agi_cmd *cmd;
1526 AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
1527 AST_LIST_LOCK(chan_cmds);
1528 while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
1531 AST_LIST_UNLOCK(chan_cmds);
1532 AST_LIST_HEAD_DESTROY(chan_cmds);
1533 ast_free(chan_cmds);
1536 /* channel datastore to keep the queue of AGI commands in the channel */
1537 static const struct ast_datastore_info agi_commands_datastore_info = {
1539 .destroy = agi_destroy_commands_cb
1543 * \brief Retrieve the list head to the requested channel's AGI datastore
1544 * \param chan Channel datastore is requested for
1545 * \param cmd Pointer to the struct pointer which will reference the head of the agi command list.
1547 * \retval 0 if the datastore was valid and the list head was retrieved appropriately (even if it's
1548 * NULL and the list is empty)
1549 * \retval -1 if the datastore could not be retrieved causing an error
1551 static int get_agi_cmd(struct ast_channel *chan, struct agi_cmd **cmd)
1553 struct ast_datastore *store;
1554 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1556 ast_channel_lock(chan);
1557 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1558 ast_channel_unlock(chan);
1560 ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
1561 ast_channel_name(chan));
1565 agi_commands = store->data;
1566 AST_LIST_LOCK(agi_commands);
1567 *cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
1568 AST_LIST_UNLOCK(agi_commands);
1572 /* channel is locked when calling this one either from the CLI or manager thread */
1573 static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
1575 struct ast_datastore *store;
1576 struct agi_cmd *cmd;
1577 AST_LIST_HEAD(, agi_cmd) *agi_commands;
1579 store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1581 ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", ast_channel_name(chan));
1584 agi_commands = store->data;
1585 cmd = ast_calloc(1, sizeof(*cmd));
1589 cmd->cmd_buffer = ast_strdup(cmd_buff);
1590 if (!cmd->cmd_buffer) {
1594 cmd->cmd_id = ast_strdup(cmd_id);
1596 ast_free(cmd->cmd_buffer);
1600 AST_LIST_LOCK(agi_commands);
1601 AST_LIST_INSERT_TAIL(agi_commands, cmd, entry);
1602 AST_LIST_UNLOCK(agi_commands);
1606 static int add_to_agi(struct ast_channel *chan)
1608 struct ast_datastore *datastore;
1609 AST_LIST_HEAD(, agi_cmd) *agi_cmds_list;
1611 /* check if already on AGI */
1612 ast_channel_lock(chan);
1613 datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1614 ast_channel_unlock(chan);
1616 /* we already have an AGI datastore, let's just
1621 /* the channel has never been on Async AGI,
1622 let's allocate it's datastore */
1623 datastore = ast_datastore_alloc(&agi_commands_datastore_info, "AGI");
1627 agi_cmds_list = ast_calloc(1, sizeof(*agi_cmds_list));
1628 if (!agi_cmds_list) {
1629 ast_log(LOG_ERROR, "Unable to allocate Async AGI commands list.\n");
1630 ast_datastore_free(datastore);
1633 datastore->data = agi_cmds_list;
1634 AST_LIST_HEAD_INIT(agi_cmds_list);
1635 ast_channel_lock(chan);
1636 ast_channel_datastore_add(chan, datastore);
1637 ast_channel_unlock(chan);
1642 * \brief CLI command to add applications to execute in Async AGI
1647 * \retval CLI_SUCCESS on success
1648 * \retval NULL when init or tab completion is used
1650 static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1652 struct ast_channel *chan;
1655 e->command = "agi exec";
1656 e->usage = "Usage: agi exec <channel name> <app and arguments> [id]\n"
1657 " Add AGI command to the execute queue of the specified channel in Async AGI\n";
1661 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
1666 return CLI_SHOWUSAGE;
1669 if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
1670 ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
1674 ast_channel_lock(chan);
1676 if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
1677 ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", ast_channel_name(chan));
1678 ast_channel_unlock(chan);
1679 chan = ast_channel_unref(chan);
1683 ast_debug(1, "Added AGI command to channel %s queue\n", ast_channel_name(chan));
1685 ast_channel_unlock(chan);
1686 chan = ast_channel_unref(chan);
1692 * \brief Add a new command to execute by the Async AGI application
1696 * It will append the application to the specified channel's queue
1697 * if the channel is not inside Async AGI application it will return an error
1698 * \retval 0 on success or incorrect use
1699 * \retval 1 on failure to add the command ( most likely because the channel
1700 * is not in Async AGI loop )
1702 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
1704 const char *channel = astman_get_header(m, "Channel");
1705 const char *cmdbuff = astman_get_header(m, "Command");
1706 const char *cmdid = astman_get_header(m, "CommandID");
1707 struct ast_channel *chan;
1710 if (ast_strlen_zero(channel) || ast_strlen_zero(cmdbuff)) {
1711 astman_send_error(s, m, "Both, Channel and Command are *required*");
1715 if (!(chan = ast_channel_get_by_name(channel))) {
1716 snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
1717 astman_send_error(s, m, buf);
1721 ast_channel_lock(chan);
1723 if (add_agi_cmd(chan, cmdbuff, cmdid)) {
1724 snprintf(buf, sizeof(buf), "Failed to add AGI command to channel %s queue", ast_channel_name(chan));
1725 astman_send_error(s, m, buf);
1726 ast_channel_unlock(chan);
1727 chan = ast_channel_unref(chan);
1731 ast_channel_unlock(chan);
1732 chan = ast_channel_unref(chan);
1734 astman_send_ack(s, m, "Added AGI command to queue");
1739 static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
1740 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
1744 * \brief Read and handle a channel frame for Async AGI.
1746 * \param chan Channel to read a frame from.
1748 * \retval AGI_RESULT_SUCCESS on success.
1749 * \retval AGI_RESULT_HANGUP on hangup.
1750 * \retval AGI_RESULT_FAILURE on error.
1752 static enum agi_result async_agi_read_frame(struct ast_channel *chan)
1754 struct ast_frame *f;
1758 ast_debug(3, "No frame read on channel %s, going out ...\n", ast_channel_name(chan));
1759 return AGI_RESULT_HANGUP;
1761 if (f->frametype == AST_FRAME_CONTROL) {
1763 * Is there any other frame we should care about besides
1764 * AST_CONTROL_HANGUP?
1766 switch (f->subclass.integer) {
1767 case AST_CONTROL_HANGUP:
1768 ast_debug(3, "Got HANGUP frame on channel %s, going out ...\n", ast_channel_name(chan));
1770 return AGI_RESULT_HANGUP;
1777 return AGI_RESULT_SUCCESS;
1780 static enum agi_result launch_asyncagi(struct ast_channel *chan, int argc, char *argv[], int *efd)
1782 /* This buffer sizes might cause truncation if the AGI command writes more data
1783 than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
1784 that writes a response larger than 1024 bytes?, I don't think so, most of
1785 them are just result=blah stuff. However probably if GET VARIABLE is called
1786 and the variable has large amount of data, that could be a problem. We could
1787 make this buffers dynamic, but let's leave that as a second step.
1789 AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
1790 number. Some characters of AGI buf will be url encoded to be sent to manager
1791 clients. An URL encoded character will take 3 bytes, but again, to cause
1792 truncation more than about 70% of the AGI buffer should be URL encoded for
1793 that to happen. Not likely at all.
1795 On the other hand. I wonder if read() could eventually return less data than
1796 the amount already available in the pipe? If so, how to deal with that?
1797 So far, my tests on Linux have not had any problems.
1799 #define AGI_BUF_SIZE 1024
1800 #define AMI_BUF_SIZE 2048
1801 enum agi_result cmd_status;
1802 struct agi_cmd *cmd;
1807 char agi_buffer[AGI_BUF_SIZE + 1];
1808 char ami_buffer[AMI_BUF_SIZE];
1809 enum agi_result returnstatus = AGI_RESULT_SUCCESS;
1811 RAII_VAR(struct ast_json *, startblob, NULL, ast_json_unref);
1814 ast_log(LOG_WARNING, "Async AGI does not support Enhanced AGI yet\n");
1815 return AGI_RESULT_FAILURE;
1818 /* add AsyncAGI datastore to the channel */
1819 if (add_to_agi(chan)) {
1820 ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", ast_channel_name(chan));
1821 return AGI_RESULT_FAILURE;
1824 /* this pipe allows us to create a "fake" AGI struct to use
1828 ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
1830 * Intentionally do not remove the datastore added with
1831 * add_to_agi() the from channel. It will be removed when the
1832 * channel is hung up anyway.
1834 return AGI_RESULT_FAILURE;
1837 /* handlers will get the pipe write fd and we read the AGI responses
1838 from the pipe read fd */
1839 async_agi.fd = fds[1];
1840 async_agi.ctrl = fds[1];
1841 async_agi.audio = -1; /* no audio support */
1843 async_agi.speech = NULL;
1845 /* notify possible manager users of a new channel ready to
1847 setup_env(chan, "async", fds[1], 0, argc, argv);
1848 /* read the environment */
1849 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1851 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s: %s\n",
1852 ast_channel_name(chan), res < 0 ? strerror(errno) : "EOF");
1853 returnstatus = AGI_RESULT_FAILURE;
1854 goto async_agi_abort;
1856 agi_buffer[res] = '\0';
1857 /* encode it and send it thru the manager so whoever is going to take
1858 care of AGI commands on this channel can decide which AGI commands
1859 to execute based on the setup info */
1860 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1861 startblob = ast_json_pack("{s: s}", "Env", ami_buffer);
1863 ast_channel_publish_cached_blob(chan, agi_async_start_type(), startblob);
1865 hungup = ast_check_hangup_locked(chan);
1869 * Process as many commands as we can. Commands are added via
1870 * the manager or the cli threads.
1873 RAII_VAR(struct ast_json *, execblob, NULL, ast_json_unref);
1874 res = get_agi_cmd(chan, &cmd);
1877 returnstatus = AGI_RESULT_FAILURE;
1878 goto async_agi_done;
1883 /* OK, we have a command, let's call the command handler. */
1884 cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
1887 * The command handler must have written to our fake AGI struct
1888 * fd (the pipe), let's read the response.
1890 res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1892 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s: %s\n",
1893 ast_channel_name(chan), res < 0 ? strerror(errno) : "EOF");
1895 returnstatus = AGI_RESULT_FAILURE;
1896 goto async_agi_done;
1899 * We have a response, let's send the response thru the manager.
1900 * Include the CommandID if it was specified when the command
1903 agi_buffer[res] = '\0';
1904 ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1906 execblob = ast_json_pack("{s: s}", "Result", ami_buffer);
1907 if (execblob && !ast_strlen_zero(cmd->cmd_id)) {
1908 ast_json_object_set(execblob, "CommandId", ast_json_string_create(cmd->cmd_id));
1910 ast_channel_publish_cached_blob(chan, agi_async_exec_type(), execblob);
1915 * Check the command status to determine if we should continue
1916 * executing more commands.
1918 hungup = ast_check_hangup(chan);
1919 switch (cmd_status) {
1920 case AGI_RESULT_FAILURE:
1922 /* The failure was not because of a hangup. */
1923 returnstatus = AGI_RESULT_FAILURE;
1924 goto async_agi_done;
1927 case AGI_RESULT_SUCCESS_ASYNC:
1928 /* Only the "asyncagi break" command does this. */
1929 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1930 goto async_agi_done;
1937 /* Wait a bit for a frame to read or to poll for a new command. */
1938 res = ast_waitfor(chan, timeout);
1940 ast_debug(1, "ast_waitfor returned <= 0 on chan %s\n", ast_channel_name(chan));
1941 returnstatus = AGI_RESULT_FAILURE;
1946 * Read the channel control queue until it is dry so we can
1953 cmd_status = async_agi_read_frame(chan);
1954 if (cmd_status != AGI_RESULT_SUCCESS) {
1955 returnstatus = cmd_status;
1956 goto async_agi_done;
1958 hungup = ast_check_hangup(chan);
1961 hungup = ast_check_hangup(chan);
1966 if (async_agi.speech) {
1967 ast_speech_destroy(async_agi.speech);
1969 /* notify manager users this channel cannot be controlled anymore by Async AGI */
1970 ast_channel_publish_cached_blob(chan, agi_async_end_type(), NULL);
1973 /* close the pipe */
1978 * Intentionally do not remove the datastore added with
1979 * add_to_agi() the from channel. There might be commands still
1980 * in the queue or in-flight to us and AsyncAGI may get called
1981 * again. The datastore destructor will be called on channel
1982 * destruction anyway.
1985 if (returnstatus == AGI_RESULT_SUCCESS) {
1986 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1988 return returnstatus;
1996 * \brief Handle the connection that was started by launch_netscript.
1998 * \param agiurl Url that we are trying to connect to.
1999 * \param addr Address that host was resolved to.
2000 * \param netsockfd File descriptor of socket.
2002 * \retval 0 when connection is succesful.
2003 * \retval 1 when there is an error.
2005 static int handle_connection(const char *agiurl, const struct ast_sockaddr addr, const int netsockfd)
2007 struct pollfd pfds[1];
2011 reslen = sizeof(conresult);
2013 pfds[0].fd = netsockfd;
2014 pfds[0].events = POLLOUT;
2016 while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
2017 if (errno != EINTR) {
2019 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
2020 agiurl, MAX_AGI_CONNECT);
2022 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
2029 if (getsockopt(pfds[0].fd, SOL_SOCKET, SO_ERROR, &conresult, &reslen) < 0) {
2030 ast_log(LOG_WARNING, "Connection to %s failed with error: %s\n",
2031 ast_sockaddr_stringify(&addr), strerror(errno));
2036 ast_log(LOG_WARNING, "Connecting to '%s' failed for url '%s': %s\n",
2037 ast_sockaddr_stringify(&addr), agiurl, strerror(conresult));
2044 /* launch_netscript: The fastagi handler.
2045 FastAGI defaults to port 4573 */
2046 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
2049 char *host, *script;
2050 int num_addrs = 0, i = 0;
2051 struct ast_sockaddr *addrs;
2053 /* agiurl is "agi://host.domain[:port][/script/name]" */
2054 host = ast_strdupa(agiurl + 6); /* Remove agi:// */
2056 /* Strip off any script name */
2057 if ((script = strchr(host, '/'))) {
2063 if (!(num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC))) {
2064 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
2065 return AGI_RESULT_FAILURE;
2068 for (i = 0; i < num_addrs; i++) {
2069 if (!ast_sockaddr_port(&addrs[i])) {
2070 ast_sockaddr_set_port(&addrs[i], AGI_PORT);
2073 if ((s = socket(addrs[i].ss.ss_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
2074 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
2078 if ((flags = fcntl(s, F_GETFL)) < 0) {
2079 ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
2084 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
2085 ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
2090 if (ast_connect(s, &addrs[i]) && errno == EINPROGRESS) {
2092 if (handle_connection(agiurl, addrs[i], s)) {
2098 ast_log(LOG_WARNING, "Connection to %s failed with unexpected error: %s\n",
2099 ast_sockaddr_stringify(&addrs[i]), strerror(errno));
2107 if (i == num_addrs) {
2108 ast_log(LOG_WARNING, "Couldn't connect to any host. FastAGI failed.\n");
2109 return AGI_RESULT_FAILURE;
2112 if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
2113 if (errno != EINTR) {
2114 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
2116 return AGI_RESULT_FAILURE;
2120 /* If we have a script parameter, relay it to the fastagi server */
2121 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
2122 if (!ast_strlen_zero(script)) {
2123 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
2126 ast_debug(4, "Wow, connected!\n");
2129 return AGI_RESULT_SUCCESS_FAST;
2134 * \brief The HA fastagi handler.
2135 * \param agiurl The request URL as passed to Agi() in the dial plan
2136 * \param argv The parameters after the URL passed to Agi() in the dial plan
2137 * \param fds Input/output file descriptors
2139 * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
2140 * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
2141 * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
2142 * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
2145 * This function parses the URI, resolves the SRV service name, forms new URIs
2146 * with the results of the DNS lookup, and then calls launch_netscript on the
2147 * new URIs until one succeeds.
2149 * \return the result of the AGI operation.
2151 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
2153 char *host, *script;
2154 enum agi_result result;
2155 struct srv_context *context = NULL;
2158 char resolved_uri[1024];
2159 const char *srvhost;
2160 unsigned short srvport;
2162 /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
2163 if (strlen(agiurl) < 7) { /* Remove hagi:// */
2164 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
2165 return AGI_RESULT_FAILURE;
2167 host = ast_strdupa(agiurl + 7);
2169 /* Strip off any script name */
2170 if ((script = strchr(host, '/'))) {
2176 if (strchr(host, ':')) {
2177 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
2178 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
2181 snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
2183 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
2184 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
2185 result = launch_netscript(resolved_uri, argv, fds);
2186 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
2187 ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
2189 /* The script launched so we must cleanup the context. */
2190 ast_srv_cleanup(&context);
2195 * The DNS SRV lookup failed or we ran out of servers to check.
2196 * ast_srv_lookup() has already cleaned up the context for us.
2199 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
2202 return AGI_RESULT_FAILURE;
2205 static enum agi_result launch_script(struct ast_channel *chan, char *script, int argc, char *argv[], int *fds, int *efd, int *opid)
2208 int pid, toast[2], fromast[2], audio[2], res;
2211 if (!strncasecmp(script, "agi://", 6)) {
2212 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
2214 if (!strncasecmp(script, "hagi://", 7)) {
2215 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
2217 if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
2218 return launch_asyncagi(chan, argc, argv, efd);
2221 if (script[0] != '/') {
2222 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
2226 /* Before even trying let's see if the file actually exists */
2227 if (stat(script, &st)) {
2228 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
2229 return AGI_RESULT_NOTFOUND;
2233 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
2234 return AGI_RESULT_FAILURE;
2236 if (pipe(fromast)) {
2237 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
2240 return AGI_RESULT_FAILURE;
2244 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
2249 return AGI_RESULT_FAILURE;
2251 res = fcntl(audio[1], F_GETFL);
2253 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
2255 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
2262 return AGI_RESULT_FAILURE;
2266 if ((pid = ast_safe_fork(1)) < 0) {
2267 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
2268 return AGI_RESULT_FAILURE;
2271 /* Pass paths to AGI via environmental variables */
2272 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
2273 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
2274 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
2275 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
2276 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
2277 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
2278 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
2279 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
2280 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
2281 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
2282 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
2284 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
2285 ast_set_priority(0);
2287 /* Redirect stdin and out, provide enhanced audio channel if desired */
2288 dup2(fromast[0], STDIN_FILENO);
2289 dup2(toast[1], STDOUT_FILENO);
2291 dup2(audio[0], STDERR_FILENO + 1);
2293 close(STDERR_FILENO + 1);
2295 /* Close everything but stdin/out/error */
2296 ast_close_fds_above_n(STDERR_FILENO + 1);
2298 /* Execute script */
2299 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
2300 execv(script, argv);
2301 /* Can't use ast_log since FD's are closed */
2302 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
2303 /* Special case to set status of AGI to failure */
2304 fprintf(stdout, "failure\n");
2308 ast_verb(3, "Launched AGI Script %s\n", script);
2310 fds[1] = fromast[1];
2313 /* close what we're not using in the parent */
2321 return AGI_RESULT_SUCCESS;
2324 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
2328 /* Print initial environment, with agi_request always being the first
2330 ast_agi_send(fd, chan, "agi_request: %s\n", request);
2331 ast_agi_send(fd, chan, "agi_channel: %s\n", ast_channel_name(chan));
2332 ast_agi_send(fd, chan, "agi_language: %s\n", ast_channel_language(chan));
2333 ast_agi_send(fd, chan, "agi_type: %s\n", ast_channel_tech(chan)->type);
2334 ast_agi_send(fd, chan, "agi_uniqueid: %s\n", ast_channel_uniqueid(chan));
2335 ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
2338 ast_agi_send(fd, chan, "agi_callerid: %s\n",
2339 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "unknown"));
2340 ast_agi_send(fd, chan, "agi_calleridname: %s\n",
2341 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "unknown"));
2342 ast_agi_send(fd, chan, "agi_callingpres: %d\n",
2343 ast_party_id_presentation(&ast_channel_caller(chan)->id));
2344 ast_agi_send(fd, chan, "agi_callingani2: %d\n", ast_channel_caller(chan)->ani2);
2345 ast_agi_send(fd, chan, "agi_callington: %d\n", ast_channel_caller(chan)->id.number.plan);
2346 ast_agi_send(fd, chan, "agi_callingtns: %d\n", ast_channel_dialed(chan)->transit_network_select);
2347 ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(ast_channel_dialed(chan)->number.str, "unknown"));
2348 ast_agi_send(fd, chan, "agi_rdnis: %s\n",
2349 S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, "unknown"));
2351 /* Context information */
2352 ast_agi_send(fd, chan, "agi_context: %s\n", ast_channel_context(chan));
2353 ast_agi_send(fd, chan, "agi_extension: %s\n", ast_channel_exten(chan));
2354 ast_agi_send(fd, chan, "agi_priority: %d\n", ast_channel_priority(chan));
2355 ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
2357 /* User information */
2358 ast_agi_send(fd, chan, "agi_accountcode: %s\n", ast_channel_accountcode(chan) ? ast_channel_accountcode(chan) : "");
2359 ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
2361 /* Send any parameters to the fastagi server that have been passed via the agi application */
2362 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
2363 for(count = 1; count < argc; count++)
2364 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
2366 /* End with empty return */
2367 ast_agi_send(fd, chan, "\n");
2370 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2374 /* Answer the channel */
2375 if (ast_channel_state(chan) != AST_STATE_UP)
2376 res = ast_answer(chan);
2378 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2379 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2382 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2384 ast_agi_send(agi->fd, chan, "200 result=0\n");
2385 return ASYNC_AGI_BREAK;
2388 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2393 return RESULT_SHOWUSAGE;
2394 if (sscanf(argv[3], "%30d", &to) != 1)
2395 return RESULT_SHOWUSAGE;
2396 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
2397 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2398 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2401 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2406 return RESULT_SHOWUSAGE;
2408 /* At the moment, the parser (perhaps broken) returns with
2409 the last argument PLUS the newline at the end of the input
2410 buffer. This probably needs to be fixed, but I wont do that
2411 because other stuff may break as a result. The right way
2412 would probably be to strip off the trailing newline before
2413 parsing, then here, add a newline at the end of the string
2414 before sending it to ast_sendtext --DUDE */
2415 res = ast_sendtext(chan, argv[2]);
2416 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2417 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2420 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2425 return RESULT_SHOWUSAGE;
2427 res = ast_recvchar(chan,atoi(argv[2]));
2429 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
2430 return RESULT_SUCCESS;
2433 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2434 return RESULT_SUCCESS;
2436 ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
2437 return RESULT_FAILURE;
2440 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2445 return RESULT_SHOWUSAGE;
2447 buf = ast_recvtext(chan, atoi(argv[2]));
2449 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
2452 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2454 return RESULT_SUCCESS;
2457 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2462 return RESULT_SHOWUSAGE;
2464 if (!strncasecmp(argv[2],"on",2)) {
2469 if (!strncasecmp(argv[2],"mate",4)) {
2472 if (!strncasecmp(argv[2],"tdd",3)) {
2475 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
2477 /* Set channel option failed */
2478 ast_agi_send(agi->fd, chan, "200 result=0\n");
2480 ast_agi_send(agi->fd, chan, "200 result=1\n");
2482 return RESULT_SUCCESS;
2485 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2490 return RESULT_SHOWUSAGE;
2493 res = ast_send_image(chan, argv[2]);
2494 if (!ast_check_hangup(chan)) {
2497 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2498 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2501 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2503 int res = 0, skipms = 3000;
2504 const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL; /* Default values */
2509 if (argc < 5 || argc > 10) {
2510 return RESULT_SHOWUSAGE;
2513 if (!ast_strlen_zero(argv[4])) {
2517 if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
2518 return RESULT_SHOWUSAGE;
2521 if (argc > 6 && !ast_strlen_zero(argv[6])) {
2525 if (argc > 7 && !ast_strlen_zero(argv[7])) {
2529 if (argc > 8 && !ast_strlen_zero(argv[8])) {
2533 if (argc > 9 && (sscanf(argv[9], "%30ld", &offsetms) != 1)) {
2534 return RESULT_SHOWUSAGE;
2537 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, &offsetms);
2539 /* If we stopped on one of our stop keys, return 0 */
2540 if (res > 0 && stop && strchr(stop, res)) {
2541 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
2542 snprintf(stopkeybuf, sizeof(stopkeybuf), "%c", res);
2543 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTOPKEY", stopkeybuf);
2544 } else if (res > 0 && res == AST_CONTROL_STREAM_STOP) {
2545 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "REMOTESTOPPED");
2549 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "ERROR");
2551 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS");
2555 snprintf(offsetbuf, sizeof(offsetbuf), "%ld", offsetms);
2556 pbx_builtin_setvar_helper(chan, "CPLAYBACKOFFSET", offsetbuf);
2558 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, offsetms);
2560 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2563 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2566 struct ast_filestream *fs, *vfs;
2567 long sample_offset = 0, max_length;
2568 const char *edigits = "";
2570 if (argc < 4 || argc > 5) {
2571 return RESULT_SHOWUSAGE;
2578 if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1)) {
2579 return RESULT_SHOWUSAGE;
2582 if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2583 ast_agi_send(agi->fd, chan, "200 result=-1 endpos=%ld\n", sample_offset);
2584 return RESULT_FAILURE;
2587 if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan)))) {
2588 ast_debug(1, "Ooh, found a video stream, too\n");
2590 ast_verb(3, "<%s> Playing '%s.%s' (escape_digits=%s) (sample_offset %ld) (language '%s')\n",
2591 ast_channel_name(chan), argv[2], ast_format_get_name(ast_channel_writeformat(chan)),
2592 edigits, sample_offset, S_OR(ast_channel_language(chan), "default"));
2594 ast_seekstream(fs, 0, SEEK_END);
2595 max_length = ast_tellstream(fs);
2596 ast_seekstream(fs, sample_offset, SEEK_SET);
2597 res = ast_applystream(chan, fs);
2599 ast_applystream(chan, vfs);
2603 ast_playstream(vfs);
2606 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2607 /* this is to check for if ast_waitstream closed the stream, we probably are at
2608 * the end of the stream, return that amount, else check for the amount */
2609 sample_offset = (ast_channel_stream(chan)) ? ast_tellstream(fs) : max_length;
2610 ast_stopstream(chan);
2612 /* Stop this command, don't print a result line, as there is a new command */
2613 return RESULT_SUCCESS;
2615 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2616 pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", res ? "FAILED" : "SUCCESS");
2618 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2621 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
2622 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2625 struct ast_filestream *fs, *vfs;
2626 long sample_offset = 0, max_length;
2628 const char *edigits = "";
2630 if ( argc < 4 || argc > 5 )
2631 return RESULT_SHOWUSAGE;
2637 timeout = atoi(argv[4]);
2638 else if (ast_channel_pbx(chan)->dtimeoutms) {
2639 /* by default dtimeout is set to 5sec */
2640 timeout = ast_channel_pbx(chan)->dtimeoutms; /* in msec */
2643 if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2644 ast_agi_send(agi->fd, chan, "200 result=-1 endpos=%ld\n", sample_offset);
2645 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2646 return RESULT_FAILURE;
2649 if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan))))
2650 ast_debug(1, "Ooh, found a video stream, too\n");
2652 ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2654 ast_seekstream(fs, 0, SEEK_END);
2655 max_length = ast_tellstream(fs);
2656 ast_seekstream(fs, sample_offset, SEEK_SET);
2657 res = ast_applystream(chan, fs);
2659 ast_applystream(chan, vfs);
2662 ast_playstream(vfs);
2664 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2665 /* this is to check for if ast_waitstream closed the stream, we probably are at
2666 * the end of the stream, return that amount, else check for the amount */
2667 sample_offset = (ast_channel_stream(chan))?ast_tellstream(fs):max_length;
2668 ast_stopstream(chan);
2670 /* Stop this command, don't print a result line, as there is a new command */
2671 return RESULT_SUCCESS;
2674 /* If the user didnt press a key, wait for digitTimeout*/
2676 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2677 /* Make sure the new result is in the escape digits of the GET OPTION */
2678 if ( !strchr(edigits,res) )
2682 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2683 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2689 /*! \brief Say number in various language syntaxes */
2690 /* While waiting, we're sending a NULL. */
2691 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2695 if (argc < 4 || argc > 5)
2696 return RESULT_SHOWUSAGE;
2697 if (sscanf(argv[2], "%30d", &num) != 1)
2698 return RESULT_SHOWUSAGE;
2699 res = ast_say_number_full(chan, num, argv[3], ast_channel_language(chan), argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2701 return RESULT_SUCCESS;
2702 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2703 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2706 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2711 return RESULT_SHOWUSAGE;
2712 if (sscanf(argv[2], "%30d", &num) != 1)
2713 return RESULT_SHOWUSAGE;
2715 res = ast_say_digit_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2716 if (res == 1) /* New command */
2717 return RESULT_SUCCESS;
2718 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2719 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2722 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2725 int sensitivity = AST_SAY_CASE_NONE;
2727 if (argc < 4 || argc > 5) {
2728 return RESULT_SHOWUSAGE;
2732 switch (argv[4][0]) {
2735 sensitivity = AST_SAY_CASE_ALL;
2739 sensitivity = AST_SAY_CASE_LOWER;
2743 sensitivity = AST_SAY_CASE_NONE;
2747 sensitivity = AST_SAY_CASE_UPPER;
2752 return RESULT_SHOWUSAGE;
2755 res = ast_say_character_str_full(chan, argv[2], argv[3], ast_channel_language(chan), sensitivity, agi->audio, agi->ctrl);
2756 if (res == 1) /* New command */
2757 return RESULT_SUCCESS;
2758 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2759 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2762 static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2767 return RESULT_SHOWUSAGE;
2768 if (sscanf(argv[2], "%30d", &num) != 1)
2769 return RESULT_SHOWUSAGE;
2770 res = ast_say_date(chan, num, argv[3], ast_channel_language(chan));
2772 return RESULT_SUCCESS;
2773 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2774 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2777 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2782 return RESULT_SHOWUSAGE;
2783 if (sscanf(argv[2], "%30d", &num) != 1)
2784 return RESULT_SHOWUSAGE;
2785 res = ast_say_time(chan, num, argv[3], ast_channel_language(chan));
2787 return RESULT_SUCCESS;
2788 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2789 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2792 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2796 const char *format, *zone = NULL;
2799 return RESULT_SHOWUSAGE;
2804 /* XXX this doesn't belong here, but in the 'say' module */
2805 if (!strcasecmp(ast_channel_language(chan), "de")) {
2806 format = "A dBY HMS";
2808 format = "ABdY 'digits/at' IMp";
2812 if (argc > 5 && !ast_strlen_zero(argv[5]))
2815 if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2816 return RESULT_SHOWUSAGE;
2818 res = ast_say_date_with_format(chan, unixtime, argv[3], ast_channel_language(chan), format, zone);
2820 return RESULT_SUCCESS;
2822 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2823 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2826 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2831 return RESULT_SHOWUSAGE;
2833 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2834 if (res == 1) /* New command */
2835 return RESULT_SUCCESS;
2836 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2837 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2840 static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2842 int res, max, timeout;
2846 return RESULT_SHOWUSAGE;
2848 timeout = atoi(argv[3]);
2852 max = atoi(argv[4]);
2855 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2856 if (res == 2) /* New command */
2857 return RESULT_SUCCESS;
2859 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2861 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2863 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2864 return RESULT_SUCCESS;
2867 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2871 return RESULT_SHOWUSAGE;
2872 ast_channel_context_set(chan, argv[2]);
2873 ast_agi_send(agi->fd, chan, "200 result=0\n");
2874 return RESULT_SUCCESS;
2877 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2880 return RESULT_SHOWUSAGE;
2881 ast_channel_exten_set(chan, argv[2]);
2882 ast_agi_send(agi->fd, chan, "200 result=0\n");
2883 return RESULT_SUCCESS;
2886 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2891 return RESULT_SHOWUSAGE;
2893 if (sscanf(argv[2], "%30d", &pri) != 1) {
2894 pri = ast_findlabel_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), argv[2],
2895 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));
2897 return RESULT_SHOWUSAGE;
2900 ast_explicit_goto(chan, NULL, NULL, pri);
2901 ast_agi_send(agi->fd, chan, "200 result=0\n");
2902 return RESULT_SUCCESS;
2905 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2907 struct ast_filestream *fs;
2908 struct ast_frame *f;
2909 struct timeval start;
2910 long sample_offset = 0;
2914 struct ast_dsp *sildet=NULL; /* silence detector dsp */
2915 int totalsilence = 0;
2917 int silence = 0; /* amount of silence to allow */
2918 int gotsilence = 0; /* did we timeout for silence? */
2919 char *silencestr = NULL;
2920 RAII_VAR(struct ast_format *, rfmt, NULL, ao2_cleanup);
2922 /* XXX EAGI FIXME XXX */
2925 return RESULT_SHOWUSAGE;
2926 if (sscanf(argv[5], "%30d", &ms) != 1)
2927 return RESULT_SHOWUSAGE;
2930 silencestr = strchr(argv[6],'s');
2931 if ((argc > 7) && (!silencestr))
2932 silencestr = strchr(argv[7],'s');
2933 if ((argc > 8) && (!silencestr))
2934 silencestr = strchr(argv[8],'s');
2937 if (strlen(silencestr) > 2) {
2938 if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2942 silence = atoi(silencestr);
2950 rfmt = ao2_bump(ast_channel_readformat(chan));
2951 res = ast_set_read_format(chan, ast_format_slin);
2953 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2954 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2955 return RESULT_FAILURE;
2957 sildet = ast_dsp_new();
2959 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2960 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2961 return RESULT_FAILURE;