Fix FastAGI To Properly Check For A Connection
[asterisk/asterisk.git] / res / res_agi.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
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.
13  *
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.
17  */
18
19 /*! \file
20  *
21  * \brief AGI - the Asterisk Gateway Interface
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \todo Convert the rest of the AGI commands over to XML documentation
26  */
27
28 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <math.h>
37 #include <signal.h>
38 #include <sys/time.h>
39 #include <sys/wait.h>
40 #include <sys/stat.h>
41 #include <pthread.h>
42
43 #include "asterisk/paths.h"     /* use many ast_config_AST_*_DIR */
44 #include "asterisk/network.h"
45 #include "asterisk/file.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/pbx.h"
48 #include "asterisk/module.h"
49 #include "asterisk/astdb.h"
50 #include "asterisk/callerid.h"
51 #include "asterisk/cli.h"
52 #include "asterisk/image.h"
53 #include "asterisk/say.h"
54 #include "asterisk/app.h"
55 #include "asterisk/dsp.h"
56 #include "asterisk/musiconhold.h"
57 #include "asterisk/utils.h"
58 #include "asterisk/lock.h"
59 #include "asterisk/strings.h"
60 #include "asterisk/manager.h"
61 #include "asterisk/ast_version.h"
62 #include "asterisk/speech.h"
63 #include "asterisk/manager.h"
64 #include "asterisk/term.h"
65 #include "asterisk/xmldoc.h"
66 #include "asterisk/srv.h"
67 #include "asterisk/test.h"
68 #include "asterisk/netsock2.h"
69
70 #define AST_API_MODULE
71 #include "asterisk/agi.h"
72
73 /*** DOCUMENTATION
74         <agi name="answer" language="en_US">
75                 <synopsis>
76                         Answer channel
77                 </synopsis>
78                 <syntax />
79                 <description>
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>
82                 </description>
83                 <see-also>
84                         <ref type="agi">hangup</ref>
85                 </see-also>
86         </agi>
87         <agi name="asyncagi break" language="en_US">
88                 <synopsis>
89                         Interrupts Async AGI
90                 </synopsis>
91                 <syntax />
92                 <description>
93                         <para>Interrupts expected flow of Async AGI commands and returns control to previous source
94                         (typically, the PBX dialplan).</para>
95                 </description>
96                 <see-also>
97                         <ref type="agi">hangup</ref>
98                 </see-also>
99         </agi>
100         <agi name="channel status" language="en_US">
101                 <synopsis>
102                         Returns status of the connected channel.
103                 </synopsis>
104                 <syntax>
105                         <parameter name="channelname" />
106                 </syntax>
107                 <description>
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>
111                         <enumlist>
112                                 <enum name="0">
113                                         <para>Channel is down and available.</para>
114                                 </enum>
115                                 <enum name="1">
116                                         <para>Channel is down, but reserved.</para>
117                                 </enum>
118                                 <enum name="2">
119                                         <para>Channel is off hook.</para>
120                                 </enum>
121                                 <enum name="3">
122                                         <para>Digits (or equivalent) have been dialed.</para>
123                                 </enum>
124                                 <enum name="4">
125                                         <para>Line is ringing.</para>
126                                 </enum>
127                                 <enum name="5">
128                                         <para>Remote end is ringing.</para>
129                                 </enum>
130                                 <enum name="6">
131                                         <para>Line is up.</para>
132                                 </enum>
133                                 <enum name="7">
134                                         <para>Line is busy.</para>
135                                 </enum>
136                         </enumlist>
137                 </description>
138         </agi>
139         <agi name="control stream file" language="en_US">
140                 <synopsis>
141                         Sends audio file on channel and allows the listener to control the stream.
142                 </synopsis>
143                 <syntax>
144                         <parameter name="filename" required="true">
145                                 <para>The file extension must not be included in the filename.</para>
146                         </parameter>
147                         <parameter name="escape_digits" required="true" />
148                         <parameter name="skipms" />
149                         <parameter name="ffchar">
150                                 <para>Defaults to <literal>*</literal></para>
151                         </parameter>
152                         <parameter name="rewchr">
153                                 <para>Defaults to <literal>#</literal></para>
154                         </parameter>
155                         <parameter name="pausechr" />
156                 </syntax>
157                 <description>
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>
163                         <para>It sets the following channel variables upon completion:</para>
164                         <variablelist>
165                                 <variable name="CPLAYBACKSTATUS">
166                                         <para>Contains the status of the attempt as a text string</para>
167                                         <value name="SUCCESS" />
168                                         <value name="USERSTOPPED" />
169                                         <value name="REMOTESTOPPED" />
170                                         <value name="ERROR" />
171                                 </variable>
172                                 <variable name="CPLAYBACKOFFSET">
173                                         <para>Contains the offset in ms into the file where playback
174                                         was at when it stopped. <literal>-1</literal> is end of file.</para>
175                                 </variable>
176                                 <variable name="CPLAYBACKSTOPKEY">
177                                         <para>If the playback is stopped by the user this variable contains
178                                         the key that was pressed.</para>
179                                 </variable>
180                         </variablelist>
181                 </description>
182         </agi>
183         <agi name="database del" language="en_US">
184                 <synopsis>
185                         Removes database key/value
186                 </synopsis>
187                 <syntax>
188                         <parameter name="family" required="true" />
189                         <parameter name="key" required="true" />
190                 </syntax>
191                 <description>
192                         <para>Deletes an entry in the Asterisk database for a given
193                         <replaceable>family</replaceable> and <replaceable>key</replaceable>.</para>
194                         <para>Returns <literal>1</literal> if successful, <literal>0</literal>
195                         otherwise.</para>
196                 </description>
197         </agi>
198         <agi name="database deltree" language="en_US">
199                 <synopsis>
200                         Removes database keytree/value
201                 </synopsis>
202                 <syntax>
203                         <parameter name="family" required="true" />
204                         <parameter name="keytree" />
205                 </syntax>
206                 <description>
207                         <para>Deletes a <replaceable>family</replaceable> or specific <replaceable>keytree</replaceable>
208                         within a <replaceable>family</replaceable> in the Asterisk database.</para>
209                         <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
210                 </description>
211         </agi>
212         <agi name="database get" language="en_US">
213                 <synopsis>
214                         Gets database value
215                 </synopsis>
216                 <syntax>
217                         <parameter name="family" required="true" />
218                         <parameter name="key" required="true" />
219                 </syntax>
220                 <description>
221                         <para>Retrieves an entry in the Asterisk database for a given <replaceable>family</replaceable>
222                         and <replaceable>key</replaceable>.</para>
223                         <para>Returns <literal>0</literal> if <replaceable>key</replaceable> is not set.
224                         Returns <literal>1</literal> if <replaceable>key</replaceable> is set and returns the variable
225                         in parenthesis.</para>
226                         <para>Example return code: 200 result=1 (testvariable)</para>
227                 </description>
228         </agi>
229         <agi name="database put" language="en_US">
230                 <synopsis>
231                         Adds/updates database value
232                 </synopsis>
233                 <syntax>
234                         <parameter name="family" required="true" />
235                         <parameter name="key" required="true" />
236                         <parameter name="value" required="true" />
237                 </syntax>
238                 <description>
239                         <para>Adds or updates an entry in the Asterisk database for a given
240                         <replaceable>family</replaceable>, <replaceable>key</replaceable>, and
241                         <replaceable>value</replaceable>.</para>
242                         <para>Returns <literal>1</literal> if successful, <literal>0</literal> otherwise.</para>
243                 </description>
244         </agi>
245         <agi name="exec" language="en_US">
246                 <synopsis>
247                         Executes a given Application
248                 </synopsis>
249                 <syntax>
250                         <parameter name="application" required="true" />
251                         <parameter name="options" required="true" />
252                 </syntax>
253                 <description>
254                         <para>Executes <replaceable>application</replaceable> with given
255                         <replaceable>options</replaceable>.</para>
256                         <para>Returns whatever the <replaceable>application</replaceable> returns, or
257                         <literal>-2</literal> on failure to find <replaceable>application</replaceable>.</para>
258                 </description>
259         </agi>
260         <agi name="get data" language="en_US">
261                 <synopsis>
262                         Prompts for DTMF on a channel
263                 </synopsis>
264                 <syntax>
265                         <parameter name="file" required="true" />
266                         <parameter name="timeout" />
267                         <parameter name="maxdigits" />
268                 </syntax>
269                 <description>
270                         <para>Stream the given <replaceable>file</replaceable>, and receive DTMF data.</para>
271                         <para>Returns the digits received from the channel at the other end.</para>
272                 </description>
273         </agi>
274         <agi name="get full variable" language="en_US">
275                 <synopsis>
276                         Evaluates a channel expression
277                 </synopsis>
278                 <syntax>
279                         <parameter name="variablename" required="true" />
280                         <parameter name="channel name" />
281                 </syntax>
282                 <description>
283                         <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set
284                         or channel does not exist. Returns <literal>1</literal> if <replaceable>variablename</replaceable>
285                         is set and returns the variable in parenthesis. Understands complex variable names and builtin
286                         variables, unlike GET VARIABLE.</para>
287                         <para>Example return code: 200 result=1 (testvariable)</para>
288                 </description>
289         </agi>
290         <agi name="get option" language="en_US">
291                 <synopsis>
292                         Stream file, prompt for DTMF, with timeout.
293                 </synopsis>
294                 <syntax>
295                         <parameter name="filename" required="true" />
296                         <parameter name="escape_digits" required="true" />
297                         <parameter name="timeout" />
298                 </syntax>
299                 <description>
300                         <para>Behaves similar to STREAM FILE but used with a timeout option.</para>
301                 </description>
302                 <see-also>
303                         <ref type="agi">stream file</ref>
304                 </see-also>
305         </agi>
306         <agi name="get variable" language="en_US">
307                 <synopsis>
308                         Gets a channel variable.
309                 </synopsis>
310                 <syntax>
311                         <parameter name="variablename" required="true" />
312                 </syntax>
313                 <description>
314                         <para>Returns <literal>0</literal> if <replaceable>variablename</replaceable> is not set.
315                         Returns <literal>1</literal> if <replaceable>variablename</replaceable> is set and returns
316                         the variable in parentheses.</para>
317                         <para>Example return code: 200 result=1 (testvariable)</para>
318                 </description>
319         </agi>
320         <agi name="hangup" language="en_US">
321                 <synopsis>
322                         Hangup a channel.
323                 </synopsis>
324                 <syntax>
325                         <parameter name="channelname" />
326                 </syntax>
327                 <description>
328                         <para>Hangs up the specified channel. If no channel name is given, hangs
329                         up the current channel</para>
330                 </description>
331         </agi>
332         <agi name="noop" language="en_US">
333                 <synopsis>
334                         Does nothing.
335                 </synopsis>
336                 <syntax />
337                 <description>
338                         <para>Does nothing.</para>
339                 </description>
340         </agi>
341         <agi name="receive char" language="en_US">
342                 <synopsis>
343                         Receives one character from channels supporting it.
344                 </synopsis>
345                 <syntax>
346                         <parameter name="timeout" required="true">
347                                 <para>The maximum time to wait for input in milliseconds, or <literal>0</literal>
348                                 for infinite. Most channels</para>
349                         </parameter>
350                 </syntax>
351                 <description>
352                         <para>Receives a character of text on a channel. Most channels do not support
353                         the reception of text. Returns the decimal value of the character
354                         if one is received, or <literal>0</literal> if the channel does not support
355                         text reception. Returns <literal>-1</literal> only on error/hangup.</para>
356                 </description>
357         </agi>
358         <agi name="receive text" language="en_US">
359                 <synopsis>
360                         Receives text from channels supporting it.
361                 </synopsis>
362                 <syntax>
363                         <parameter name="timeout" required="true">
364                                 <para>The timeout to be the maximum time to wait for input in
365                                 milliseconds, or <literal>0</literal> for infinite.</para>
366                         </parameter>
367                 </syntax>
368                 <description>
369                         <para>Receives a string of text on a channel. Most channels 
370                         do not support the reception of text. Returns <literal>-1</literal> for failure
371                         or <literal>1</literal> for success, and the string in parenthesis.</para> 
372                 </description>
373         </agi>
374         <agi name="record file" language="en_US">
375                 <synopsis>
376                         Records to a given file.
377                 </synopsis>
378                 <syntax>
379                         <parameter name="filename" required="true" />
380                         <parameter name="format" required="true" />
381                         <parameter name="escape_digits" required="true" />
382                         <parameter name="timeout" required="true" />
383                         <parameter name="offset samples" />
384                         <parameter name="BEEP" />
385                         <parameter name="s=silence" />
386                 </syntax>
387                 <description>
388                         <para>Record to a file until a given dtmf digit in the sequence is received.
389                         Returns <literal>-1</literal> on hangup or error.  The format will specify what kind of file
390                         will be recorded. The <replaceable>timeout</replaceable> is the maximum record time in
391                         milliseconds, or <literal>-1</literal> for no <replaceable>timeout</replaceable>.
392                         <replaceable>offset samples</replaceable> is optional, and, if provided, will seek
393                         to the offset without exceeding the end of the file. <replaceable>silence</replaceable> is
394                         the number of seconds of silence allowed before the function returns despite the
395                         lack of dtmf digits or reaching <replaceable>timeout</replaceable>. <replaceable>silence</replaceable>
396                         value must be preceded by <literal>s=</literal> and is also optional.</para>
397                 </description>
398         </agi>
399         <agi name="say alpha" language="en_US">
400                 <synopsis>
401                         Says a given character string.
402                 </synopsis>
403                 <syntax>
404                         <parameter name="number" required="true" />
405                         <parameter name="escape_digits" required="true" />
406                 </syntax>
407                 <description>
408                         <para>Say a given character string, returning early if any of the given DTMF digits
409                         are received on the channel. Returns <literal>0</literal> if playback completes
410                         without a digit being pressed, or the ASCII numerical value of the digit if one
411                         was pressed or <literal>-1</literal> on error/hangup.</para>
412                 </description>
413         </agi>
414         <agi name="say digits" language="en_US">
415                 <synopsis>
416                         Says a given digit string.
417                 </synopsis>
418                 <syntax>
419                         <parameter name="number" required="true" />
420                         <parameter name="escape_digits" required="true" />
421                 </syntax>
422                 <description>
423                         <para>Say a given digit string, returning early if any of the given DTMF digits
424                         are received on the channel. Returns <literal>0</literal> if playback completes
425                         without a digit being pressed, or the ASCII numerical value of the digit if one
426                         was pressed or <literal>-1</literal> on error/hangup.</para>
427                 </description>
428         </agi>
429         <agi name="say number" language="en_US">
430                 <synopsis>
431                         Says a given number.
432                 </synopsis>
433                 <syntax>
434                         <parameter name="number" required="true" />
435                         <parameter name="escape_digits" required="true" />
436                         <parameter name="gender" />
437                 </syntax>
438                 <description>
439                         <para>Say a given number, returning early if any of the given DTMF digits
440                         are received on the channel.  Returns <literal>0</literal> if playback
441                         completes without a digit being pressed, or the ASCII numerical value of
442                         the digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
443                 </description>
444         </agi>
445         <agi name="say phonetic" language="en_US">
446                 <synopsis>
447                         Says a given character string with phonetics.
448                 </synopsis>
449                 <syntax>
450                         <parameter name="string" required="true" />
451                         <parameter name="escape_digits" required="true" />
452                 </syntax>
453                 <description>
454                         <para>Say a given character string with phonetics, returning early if any of the
455                         given DTMF digits are received on the channel. Returns <literal>0</literal> if
456                         playback completes without a digit pressed, the ASCII numerical value of the digit
457                         if one was pressed, or <literal>-1</literal> on error/hangup.</para>
458                 </description>
459         </agi>
460         <agi name="say date" language="en_US">
461                 <synopsis>
462                         Says a given date.
463                 </synopsis>
464                 <syntax>
465                         <parameter name="date" required="true">
466                                 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
467                                 Coordinated Universal Time (UTC).</para>
468                         </parameter>
469                         <parameter name="escape_digits" required="true" />
470                 </syntax>
471                 <description>
472                         <para>Say a given date, returning early if any of the given DTMF digits are
473                         received on the channel. Returns <literal>0</literal> if playback
474                         completes without a digit being pressed, or the ASCII numerical value of the
475                         digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
476                 </description>
477         </agi>
478         <agi name="say time" language="en_US">
479                 <synopsis>
480                         Says a given time.
481                 </synopsis>
482                 <syntax>
483                         <parameter name="time" required="true">
484                                 <para>Is number of seconds elapsed since 00:00:00 on January 1, 1970.
485                                 Coordinated Universal Time (UTC).</para>
486                         </parameter>
487                         <parameter name="escape_digits" required="true" />
488                 </syntax>
489                 <description>
490                         <para>Say a given time, returning early if any of the given DTMF digits are
491                         received on the channel. Returns <literal>0</literal> if playback completes
492                         without a digit being pressed, or the ASCII numerical value of the digit if
493                         one was pressed or <literal>-1</literal> on error/hangup.</para>
494                 </description>
495         </agi>
496         <agi name="say datetime" language="en_US">
497                 <synopsis>
498                         Says a given time as specified by the format given.
499                 </synopsis>
500                 <syntax>
501                         <parameter name="time" required="true">
502                                 <para>Is number of seconds elapsed since 00:00:00
503                                 on January 1, 1970, Coordinated Universal Time (UTC)</para>
504                         </parameter>
505                         <parameter name="escape_digits" required="true" />
506                         <parameter name="format">
507                                 <para>Is the format the time should be said in. See
508                                 <filename>voicemail.conf</filename> (defaults to <literal>ABdY
509                                 'digits/at' IMp</literal>).</para>
510                         </parameter>
511                         <parameter name="timezone">
512                                 <para>Acceptable values can be found in <filename>/usr/share/zoneinfo</filename>
513                                 Defaults to machine default.</para>
514                         </parameter>
515                 </syntax>
516                 <description>
517                         <para>Say a given time, returning early if any of the given DTMF digits are
518                         received on the channel. Returns <literal>0</literal> if playback
519                         completes without a digit being pressed, or the ASCII numerical value of the
520                         digit if one was pressed or <literal>-1</literal> on error/hangup.</para>
521                 </description>
522         </agi>
523         <agi name="send image" language="en_US">
524                 <synopsis>
525                         Sends images to channels supporting it.
526                 </synopsis>
527                 <syntax>
528                         <parameter name="image" required="true" />
529                 </syntax>
530                 <description>
531                         <para>Sends the given image on a channel. Most channels do not support the
532                         transmission of images. Returns <literal>0</literal> if image is sent, or if
533                         the channel does not support image transmission.  Returns <literal>-1</literal>
534                         only on error/hangup. Image names should not include extensions.</para>
535                 </description>
536         </agi>
537         <agi name="send text" language="en_US">
538                 <synopsis>
539                         Sends text to channels supporting it.
540                 </synopsis>
541                 <syntax>
542                         <parameter name="text to send" required="true">
543                                 <para>Text consisting of greater than one word should be placed
544                                 in quotes since the command only accepts a single argument.</para>
545                         </parameter>
546                 </syntax>
547                 <description>
548                         <para>Sends the given text on a channel. Most channels do not support the
549                         transmission of text. Returns <literal>0</literal> if text is sent, or if the
550                         channel does not support text transmission. Returns <literal>-1</literal> only
551                         on error/hangup.</para>
552                 </description>
553         </agi>
554         <agi name="set autohangup" language="en_US">
555                 <synopsis>
556                         Autohangup channel in some time.
557                 </synopsis>
558                 <syntax>
559                         <parameter name="time" required="true" />
560                 </syntax>
561                 <description>
562                         <para>Cause the channel to automatically hangup at <replaceable>time</replaceable>
563                         seconds in the future. Of course it can be hungup before then as well. Setting to
564                         <literal>0</literal> will cause the autohangup feature to be disabled on this channel.</para>
565                 </description>
566         </agi>
567         <agi name="set callerid" language="en_US">
568                 <synopsis>
569                         Sets callerid for the current channel.
570                 </synopsis>
571                 <syntax>
572                         <parameter name="number" required="true" />
573                 </syntax>
574                 <description>
575                         <para>Changes the callerid of the current channel.</para>
576                 </description>
577         </agi>
578         <agi name="set context" language="en_US">
579                 <synopsis>
580                         Sets channel context.
581                 </synopsis>
582                 <syntax>
583                         <parameter name="desired context" required="true" />
584                 </syntax>
585                 <description>
586                         <para>Sets the context for continuation upon exiting the application.</para>
587                 </description>
588         </agi>
589         <agi name="set extension" language="en_US">
590                 <synopsis>
591                         Changes channel extension.
592                 </synopsis>
593                 <syntax>
594                         <parameter name="new extension" required="true" />
595                 </syntax>
596                 <description>
597                         <para>Changes the extension for continuation upon exiting the application.</para>
598                 </description>
599         </agi>
600         <agi name="set music" language="en_US">
601                 <synopsis>
602                         Enable/Disable Music on hold generator
603                 </synopsis>
604                 <syntax>
605                         <parameter required="true">
606                                 <enumlist>
607                                         <enum>
608                                                 <parameter name="on" literal="true" required="true" />
609                                         </enum>
610                                         <enum>
611                                                 <parameter name="off" literal="true" required="true" />
612                                         </enum>
613                                 </enumlist>
614                         </parameter>
615                         <parameter name="class" required="true" />
616                 </syntax>
617                 <description>
618                         <para>Enables/Disables the music on hold generator. If <replaceable>class</replaceable>
619                         is not specified, then the <literal>default</literal> music on hold class will be
620                         used. This generator will be stopped automatically when playing a file.</para>
621                         <para>Always returns <literal>0</literal>.</para>
622                 </description>
623         </agi>
624         <agi name="set priority" language="en_US">
625                 <synopsis>
626                         Set channel dialplan priority.
627                 </synopsis>
628                 <syntax>
629                         <parameter name="priority" required="true" />
630                 </syntax>
631                 <description>
632                         <para>Changes the priority for continuation upon exiting the application.
633                         The priority must be a valid priority or label.</para>
634                 </description>
635         </agi>
636         <agi name="set variable" language="en_US">
637                 <synopsis>
638                         Sets a channel variable.
639                 </synopsis>
640                 <syntax>
641                         <parameter name="variablename" required="true" />
642                         <parameter name="value" required="true" />
643                 </syntax>
644                 <description>
645                         <para>Sets a variable to the current channel.</para>
646                 </description>
647         </agi>
648         <agi name="stream file" language="en_US">
649                 <synopsis>
650                         Sends audio file on channel.
651                 </synopsis>
652                 <syntax>
653                         <parameter name="filename" required="true">
654                                 <para>File name to play. The file extension must not be
655                                 included in the <replaceable>filename</replaceable>.</para>
656                         </parameter>
657                         <parameter name="escape_digits" required="true">
658                                 <para>Use double quotes for the digits if you wish none to be
659                                 permitted.</para>
660                         </parameter>
661                         <parameter name="sample offset">
662                                 <para>If sample offset is provided then the audio will seek to sample
663                                 offset before play starts.</para>
664                         </parameter>
665                 </syntax>
666                 <description>
667                         <para>Send the given file, allowing playback to be interrupted by the given
668                         digits, if any. Returns <literal>0</literal> if playback completes without a digit
669                         being pressed, or the ASCII numerical value of the digit if one was pressed,
670                         or <literal>-1</literal> on error or if the channel was disconnected. If
671                         musiconhold is playing before calling stream file it will be automatically
672                         stopped and will not be restarted after completion.</para>
673                         <para>It sets the following channel variables upon completion:</para>
674                         <variablelist>
675                                 <variable name="PLAYBACKSTATUS">
676                                         <para>The status of the playback attempt as a text string.</para>
677                                         <value name="SUCCESS"/>
678                                         <value name="FAILED"/>
679                                 </variable>
680                         </variablelist>
681                 </description>
682                 <see-also>
683                         <ref type="agi">control stream file</ref>
684                 </see-also>
685         </agi>
686         <agi name="tdd mode" language="en_US">
687                 <synopsis>
688                         Toggles TDD mode (for the deaf).
689                 </synopsis>
690                 <syntax>
691                         <parameter name="boolean" required="true">
692                                 <enumlist>
693                                         <enum name="on" />
694                                         <enum name="off" />
695                                 </enumlist>
696                         </parameter>
697                 </syntax>
698                 <description>
699                         <para>Enable/Disable TDD transmission/reception on a channel. Returns <literal>1</literal> if
700                         successful, or <literal>0</literal> if channel is not TDD-capable.</para>
701                 </description>
702         </agi>
703         <agi name="verbose" language="en_US">
704                 <synopsis>
705                         Logs a message to the asterisk verbose log.
706                 </synopsis>
707                 <syntax>
708                         <parameter name="message" required="true" />
709                         <parameter name="level" required="true" />
710                 </syntax>
711                 <description>
712                         <para>Sends <replaceable>message</replaceable> to the console via verbose
713                         message system. <replaceable>level</replaceable> is the verbose level (1-4).
714                         Always returns <literal>1</literal></para>
715                 </description>
716         </agi>
717         <agi name="wait for digit" language="en_US">
718                 <synopsis>
719                         Waits for a digit to be pressed.
720                 </synopsis>
721                 <syntax>
722                         <parameter name="timeout" required="true" />
723                 </syntax>
724                 <description>
725                         <para>Waits up to <replaceable>timeout</replaceable> milliseconds for channel to
726                         receive a DTMF digit. Returns <literal>-1</literal> on channel failure, <literal>0</literal>
727                         if no digit is received in the timeout, or the numerical value of the ascii of the digit if
728                         one is received. Use <literal>-1</literal> for the <replaceable>timeout</replaceable> value if
729                         you desire the call to block indefinitely.</para>
730                 </description>
731         </agi>
732         <agi name="speech create" language="en_US">
733                 <synopsis>
734                         Creates a speech object.
735                 </synopsis>
736                 <syntax>
737                         <parameter name="engine" required="true" />
738                 </syntax>
739                 <description>
740                         <para>Create a speech object to be used by the other Speech AGI commands.</para>
741                 </description>
742         </agi>
743         <agi name="speech set" language="en_US">
744                 <synopsis>
745                         Sets a speech engine setting.
746                 </synopsis>
747                 <syntax>
748                         <parameter name="name" required="true" />
749                         <parameter name="value" required="true" />
750                 </syntax>
751                 <description>
752                         <para>Set an engine-specific setting.</para>
753                 </description>
754         </agi>
755         <agi name="speech destroy" language="en_US">
756                 <synopsis>
757                         Destroys a speech object.
758                 </synopsis>
759                 <syntax>
760                 </syntax>
761                 <description>
762                         <para>Destroy the speech object created by <literal>SPEECH CREATE</literal>.</para>
763                 </description>
764                 <see-also>
765                         <ref type="agi">speech create</ref>
766                 </see-also>
767         </agi>
768         <agi name="speech load grammar" language="en_US">
769                 <synopsis>
770                         Loads a grammar.
771                 </synopsis>
772                 <syntax>
773                         <parameter name="grammar name" required="true" />
774                         <parameter name="path to grammar" required="true" />
775                 </syntax>
776                 <description>
777                         <para>Loads the specified grammar as the specified name.</para>
778                 </description>
779         </agi>
780         <agi name="speech unload grammar" language="en_US">
781                 <synopsis>
782                         Unloads a grammar.
783                 </synopsis>
784                 <syntax>
785                         <parameter name="grammar name" required="true" />
786                 </syntax>
787                 <description>
788                         <para>Unloads the specified grammar.</para>
789                 </description>
790         </agi>
791         <agi name="speech activate grammar" language="en_US">
792                 <synopsis>
793                         Activates a grammar.
794                 </synopsis>
795                 <syntax>
796                         <parameter name="grammar name" required="true" />
797                 </syntax>
798                 <description>
799                         <para>Activates the specified grammar on the speech object.</para>
800                 </description>
801         </agi>
802         <agi name="speech deactivate grammar" language="en_US">
803                 <synopsis>
804                         Deactivates a grammar.
805                 </synopsis>
806                 <syntax>
807                         <parameter name="grammar name" required="true" />
808                 </syntax>
809                 <description>
810                         <para>Deactivates the specified grammar on the speech object.</para>
811                 </description>
812         </agi>
813         <agi name="speech recognize" language="en_US">
814                 <synopsis>
815                         Recognizes speech.
816                 </synopsis>
817                 <syntax>
818                         <parameter name="prompt" required="true" />
819                         <parameter name="timeout" required="true" />
820                         <parameter name="offset" />
821                 </syntax>
822                 <description>
823                         <para>Plays back given <replaceable>prompt</replaceable> while listening for
824                         speech and dtmf.</para>
825                 </description>
826         </agi>
827         <application name="AGI" language="en_US">
828                 <synopsis>
829                         Executes an AGI compliant application.
830                 </synopsis>
831                 <syntax>
832                         <parameter name="command" required="true" />
833                         <parameter name="args">
834                                 <argument name="arg1" required="true" />
835                                 <argument name="arg2" multiple="yes" />
836                         </parameter>
837                 </syntax>
838                 <description>
839                         <para>Executes an Asterisk Gateway Interface compliant
840                         program on a channel. AGI allows Asterisk to launch external programs written
841                         in any language to control a telephony channel, play audio, read DTMF digits,
842                         etc. by communicating with the AGI protocol on <emphasis>stdin</emphasis> and
843                         <emphasis>stdout</emphasis>. As of <literal>1.6.0</literal>, this channel will
844                         not stop dialplan execution on hangup inside of this application. Dialplan
845                         execution will continue normally, even upon hangup until the AGI application
846                         signals a desire to stop (either by exiting or, in the case of a net script, by
847                         closing the connection). A locally executed AGI script will receive SIGHUP on
848                         hangup from the channel except when using DeadAGI. A fast AGI server will
849                         correspondingly receive a HANGUP inline with the command dialog. Both of theses
850                         signals may be disabled by setting the <variable>AGISIGHUP</variable> channel
851                         variable to <literal>no</literal> before executing the AGI application.
852                         Alternatively, if you would like the AGI application to exit immediately
853                         after a channel hangup is detected, set the <variable>AGIEXITONHANGUP</variable>
854                         variable to <literal>yes</literal>.</para>
855                         <para>Use the CLI command <literal>agi show commands</literal> to list available agi
856                         commands.</para>
857                         <para>This application sets the following channel variable upon completion:</para>
858                         <variablelist>
859                                 <variable name="AGISTATUS">
860                                         <para>The status of the attempt to the run the AGI script
861                                         text string, one of:</para>
862                                         <value name="SUCCESS" />
863                                         <value name="FAILURE" />
864                                         <value name="NOTFOUND" />
865                                         <value name="HANGUP" />
866                                 </variable>
867                         </variablelist>
868                 </description>
869                 <see-also>
870                         <ref type="application">EAGI</ref>
871                         <ref type="application">DeadAGI</ref>
872                 </see-also>
873         </application>
874         <application name="EAGI" language="en_US">
875                 <synopsis>
876                         Executes an EAGI compliant application.
877                 </synopsis>
878                 <syntax>
879                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
880                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
881                 </syntax>
882                 <description>
883                         <para>Using 'EAGI' provides enhanced AGI, with incoming audio available out of band
884                         on file descriptor 3.</para>
885                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
886                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
887                 </description>
888                 <see-also>
889                         <ref type="application">AGI</ref>
890                         <ref type="application">DeadAGI</ref>
891                 </see-also>
892         </application>
893         <application name="DeadAGI" language="en_US">
894                 <synopsis>
895                         Executes AGI on a hungup channel.
896                 </synopsis>
897                 <syntax>
898                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='command'])" />
899                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/syntax/parameter[@name='args'])" />
900                 </syntax>
901                 <description>
902                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/para)" />
903                         <xi:include xpointer="xpointer(/docs/application[@name='AGI']/description/variablelist)" />
904                 </description>
905                 <see-also>
906                         <ref type="application">AGI</ref>
907                         <ref type="application">EAGI</ref>
908                 </see-also>
909         </application>
910         <manager name="AGI" language="en_US">
911                 <synopsis>
912                         Add an AGI command to execute by Async AGI.
913                 </synopsis>
914                 <syntax>
915                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
916                         <parameter name="Channel" required="true">
917                                 <para>Channel that is currently in Async AGI.</para>
918                         </parameter>
919                         <parameter name="Command" required="true">
920                                 <para>Application to execute.</para>
921                         </parameter>
922                         <parameter name="CommandID">
923                                 <para>This will be sent back in CommandID header of AsyncAGI exec
924                                 event notification.</para>
925                         </parameter>
926                 </syntax>
927                 <description>
928                         <para>Add an AGI command to the execute queue of the channel in Async AGI.</para>
929                 </description>
930         </manager>
931  ***/
932
933 #define MAX_ARGS 128
934 #define MAX_CMD_LEN 80
935 #define AGI_NANDFS_RETRY 3
936 #define AGI_BUF_LEN 2048
937 #define SRV_PREFIX "_agi._tcp."
938
939 static char *app = "AGI";
940
941 static char *eapp = "EAGI";
942
943 static char *deadapp = "DeadAGI";
944
945 static int agidebug = 0;
946
947 #define TONE_BLOCK_SIZE 200
948
949 /* Max time to connect to an AGI remote host */
950 #define MAX_AGI_CONNECT 2000
951
952 #define AGI_PORT 4573
953
954 /*! Special return code for "asyncagi break" command. */
955 #define ASYNC_AGI_BREAK 3
956
957 enum agi_result {
958         AGI_RESULT_FAILURE = -1,
959         AGI_RESULT_SUCCESS,
960         AGI_RESULT_SUCCESS_FAST,
961         AGI_RESULT_SUCCESS_ASYNC,
962         AGI_RESULT_NOTFOUND,
963         AGI_RESULT_HANGUP,
964 };
965
966 static agi_command *find_command(const char * const cmds[], int exact);
967
968 AST_THREADSTORAGE(agi_buf);
969 #define AGI_BUF_INITSIZE 256
970
971 int AST_OPTIONAL_API_NAME(ast_agi_send)(int fd, struct ast_channel *chan, char *fmt, ...)
972 {
973         int res = 0;
974         va_list ap;
975         struct ast_str *buf;
976
977         if (!(buf = ast_str_thread_get(&agi_buf, AGI_BUF_INITSIZE)))
978                 return -1;
979
980         va_start(ap, fmt);
981         res = ast_str_set_va(&buf, 0, fmt, ap);
982         va_end(ap);
983
984         if (res == -1) {
985                 ast_log(LOG_ERROR, "Out of memory\n");
986                 return -1;
987         }
988
989         if (agidebug) {
990                 if (chan) {
991                         ast_verbose("<%s>AGI Tx >> %s", ast_channel_name(chan), ast_str_buffer(buf));
992                 } else {
993                         ast_verbose("AGI Tx >> %s", ast_str_buffer(buf));
994                 }
995         }
996
997         return ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
998 }
999
1000 /* linked list of AGI commands ready to be executed by Async AGI */
1001 struct agi_cmd {
1002         char *cmd_buffer;
1003         char *cmd_id;
1004         AST_LIST_ENTRY(agi_cmd) entry;
1005 };
1006
1007 static void free_agi_cmd(struct agi_cmd *cmd)
1008 {
1009         ast_free(cmd->cmd_buffer);
1010         ast_free(cmd->cmd_id);
1011         ast_free(cmd);
1012 }
1013
1014 /* AGI datastore destructor */
1015 static void agi_destroy_commands_cb(void *data)
1016 {
1017         struct agi_cmd *cmd;
1018         AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
1019         AST_LIST_LOCK(chan_cmds);
1020         while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
1021                 free_agi_cmd(cmd);
1022         }
1023         AST_LIST_UNLOCK(chan_cmds);
1024         AST_LIST_HEAD_DESTROY(chan_cmds);
1025         ast_free(chan_cmds);
1026 }
1027
1028 /* channel datastore to keep the queue of AGI commands in the channel */
1029 static const struct ast_datastore_info agi_commands_datastore_info = {
1030         .type = "AsyncAGI",
1031         .destroy = agi_destroy_commands_cb
1032 };
1033
1034 /*!
1035  * \brief Retrieve the list head to the requested channel's AGI datastore
1036  * \param chan Channel datastore is requested for
1037  * \param cmd Pointer to the struct pointer which will reference the head of the agi command list.
1038  *
1039  * \retval 0 if the datastore was valid and the list head was retrieved appropriately (even if it's
1040  *           NULL and the list is empty)
1041  * \retval -1 if the datastore could not be retrieved causing an error
1042 */
1043 static int get_agi_cmd(struct ast_channel *chan, struct agi_cmd **cmd)
1044 {
1045         struct ast_datastore *store;
1046         AST_LIST_HEAD(, agi_cmd) *agi_commands;
1047
1048         ast_channel_lock(chan);
1049         store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1050         ast_channel_unlock(chan);
1051         if (!store) {
1052                 ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
1053                         ast_channel_name(chan));
1054                 *cmd = NULL;
1055                 return -1;
1056         }
1057         agi_commands = store->data;
1058         AST_LIST_LOCK(agi_commands);
1059         *cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
1060         AST_LIST_UNLOCK(agi_commands);
1061         return 0;
1062 }
1063
1064 /* channel is locked when calling this one either from the CLI or manager thread */
1065 static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
1066 {
1067         struct ast_datastore *store;
1068         struct agi_cmd *cmd;
1069         AST_LIST_HEAD(, agi_cmd) *agi_commands;
1070
1071         store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1072         if (!store) {
1073                 ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", ast_channel_name(chan));
1074                 return -1;
1075         }
1076         agi_commands = store->data;
1077         cmd = ast_calloc(1, sizeof(*cmd));
1078         if (!cmd) {
1079                 return -1;
1080         }
1081         cmd->cmd_buffer = ast_strdup(cmd_buff);
1082         if (!cmd->cmd_buffer) {
1083                 ast_free(cmd);
1084                 return -1;
1085         }
1086         cmd->cmd_id = ast_strdup(cmd_id);
1087         if (!cmd->cmd_id) {
1088                 ast_free(cmd->cmd_buffer);
1089                 ast_free(cmd);
1090                 return -1;
1091         }
1092         AST_LIST_LOCK(agi_commands);
1093         AST_LIST_INSERT_TAIL(agi_commands, cmd, entry);
1094         AST_LIST_UNLOCK(agi_commands);
1095         return 0;
1096 }
1097
1098 static int add_to_agi(struct ast_channel *chan)
1099 {
1100         struct ast_datastore *datastore;
1101         AST_LIST_HEAD(, agi_cmd) *agi_cmds_list;
1102
1103         /* check if already on AGI */
1104         ast_channel_lock(chan);
1105         datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
1106         ast_channel_unlock(chan);
1107         if (datastore) {
1108                 /* we already have an AGI datastore, let's just
1109                    return success */
1110                 return 0;
1111         }
1112
1113         /* the channel has never been on Async AGI,
1114            let's allocate it's datastore */
1115         datastore = ast_datastore_alloc(&agi_commands_datastore_info, "AGI");
1116         if (!datastore) {
1117                 return -1;
1118         }
1119         agi_cmds_list = ast_calloc(1, sizeof(*agi_cmds_list));
1120         if (!agi_cmds_list) {
1121                 ast_log(LOG_ERROR, "Unable to allocate Async AGI commands list.\n");
1122                 ast_datastore_free(datastore);
1123                 return -1;
1124         }
1125         datastore->data = agi_cmds_list;
1126         AST_LIST_HEAD_INIT(agi_cmds_list);
1127         ast_channel_lock(chan);
1128         ast_channel_datastore_add(chan, datastore);
1129         ast_channel_unlock(chan);
1130         return 0;
1131 }
1132
1133 /*!
1134  * \brief CLI command to add applications to execute in Async AGI
1135  * \param e
1136  * \param cmd
1137  * \param a
1138  *
1139  * \retval CLI_SUCCESS on success
1140  * \retval NULL when init or tab completion is used
1141 */
1142 static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1143 {
1144         struct ast_channel *chan;
1145         switch (cmd) {
1146         case CLI_INIT:
1147                 e->command = "agi exec";
1148                 e->usage = "Usage: agi exec <channel name> <app and arguments> [id]\n"
1149                            "       Add AGI command to the execute queue of the specified channel in Async AGI\n";
1150                 return NULL;
1151         case CLI_GENERATE:
1152                 if (a->pos == 2)
1153                         return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
1154                 return NULL;
1155         }
1156
1157         if (a->argc < 4) {
1158                 return CLI_SHOWUSAGE;
1159         }
1160
1161         if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
1162                 ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
1163                 return CLI_FAILURE;
1164         }
1165
1166         ast_channel_lock(chan);
1167
1168         if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
1169                 ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", ast_channel_name(chan));
1170                 ast_channel_unlock(chan);
1171                 chan = ast_channel_unref(chan);
1172                 return CLI_FAILURE;
1173         }
1174
1175         ast_debug(1, "Added AGI command to channel %s queue\n", ast_channel_name(chan));
1176
1177         ast_channel_unlock(chan);
1178         chan = ast_channel_unref(chan);
1179
1180         return CLI_SUCCESS;
1181 }
1182
1183 /*!
1184  * \brief Add a new command to execute by the Async AGI application
1185  * \param s
1186  * \param m
1187  *
1188  * It will append the application to the specified channel's queue
1189  * if the channel is not inside Async AGI application it will return an error
1190  * \retval 0 on success or incorrect use
1191  * \retval 1 on failure to add the command ( most likely because the channel
1192  * is not in Async AGI loop )
1193 */
1194 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
1195 {
1196         const char *channel = astman_get_header(m, "Channel");
1197         const char *cmdbuff = astman_get_header(m, "Command");
1198         const char *cmdid   = astman_get_header(m, "CommandID");
1199         struct ast_channel *chan;
1200         char buf[256];
1201
1202         if (ast_strlen_zero(channel) || ast_strlen_zero(cmdbuff)) {
1203                 astman_send_error(s, m, "Both, Channel and Command are *required*");
1204                 return 0;
1205         }
1206
1207         if (!(chan = ast_channel_get_by_name(channel))) {
1208                 snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
1209                 astman_send_error(s, m, buf);
1210                 return 0;
1211         }
1212
1213         ast_channel_lock(chan);
1214
1215         if (add_agi_cmd(chan, cmdbuff, cmdid)) {
1216                 snprintf(buf, sizeof(buf), "Failed to add AGI command to channel %s queue", ast_channel_name(chan));
1217                 astman_send_error(s, m, buf);
1218                 ast_channel_unlock(chan);
1219                 chan = ast_channel_unref(chan);
1220                 return 0;
1221         }
1222
1223         ast_channel_unlock(chan);
1224         chan = ast_channel_unref(chan);
1225
1226         astman_send_ack(s, m, "Added AGI command to queue");
1227
1228         return 0;
1229 }
1230
1231 static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
1232 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
1233
1234 /*!
1235  * \internal
1236  * \brief Read and handle a channel frame for Async AGI.
1237  *
1238  * \param chan Channel to read a frame from.
1239  *
1240  * \retval AGI_RESULT_SUCCESS on success.
1241  * \retval AGI_RESULT_HANGUP on hangup.
1242  * \retval AGI_RESULT_FAILURE on error.
1243  */
1244 static enum agi_result async_agi_read_frame(struct ast_channel *chan)
1245 {
1246         struct ast_frame *f;
1247
1248         f = ast_read(chan);
1249         if (!f) {
1250                 ast_debug(3, "No frame read on channel %s, going out ...\n", ast_channel_name(chan));
1251                 return AGI_RESULT_HANGUP;
1252         }
1253         if (f->frametype == AST_FRAME_CONTROL) {
1254                 /*
1255                  * Is there any other frame we should care about besides
1256                  * AST_CONTROL_HANGUP?
1257                  */
1258                 switch (f->subclass.integer) {
1259                 case AST_CONTROL_HANGUP:
1260                         ast_debug(3, "Got HANGUP frame on channel %s, going out ...\n", ast_channel_name(chan));
1261                         ast_frfree(f);
1262                         return AGI_RESULT_HANGUP;
1263                 default:
1264                         break;
1265                 }
1266         }
1267         ast_frfree(f);
1268
1269         return AGI_RESULT_SUCCESS;
1270 }
1271
1272 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
1273 {
1274 /* This buffer sizes might cause truncation if the AGI command writes more data
1275    than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
1276    that writes a response larger than 1024 bytes?, I don't think so, most of
1277    them are just result=blah stuff. However probably if GET VARIABLE is called
1278    and the variable has large amount of data, that could be a problem. We could
1279    make this buffers dynamic, but let's leave that as a second step.
1280
1281    AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
1282    number. Some characters of AGI buf will be url encoded to be sent to manager
1283    clients.  An URL encoded character will take 3 bytes, but again, to cause
1284    truncation more than about 70% of the AGI buffer should be URL encoded for
1285    that to happen.  Not likely at all.
1286
1287    On the other hand. I wonder if read() could eventually return less data than
1288    the amount already available in the pipe? If so, how to deal with that?
1289    So far, my tests on Linux have not had any problems.
1290  */
1291 #define AGI_BUF_SIZE 1024
1292 #define AMI_BUF_SIZE 2048
1293         enum agi_result cmd_status;
1294         struct agi_cmd *cmd;
1295         int res;
1296         int fds[2];
1297         int hungup;
1298         int timeout = 100;
1299         char agi_buffer[AGI_BUF_SIZE + 1];
1300         char ami_buffer[AMI_BUF_SIZE];
1301         enum agi_result returnstatus = AGI_RESULT_SUCCESS;
1302         AGI async_agi;
1303
1304         if (efd) {
1305                 ast_log(LOG_WARNING, "Async AGI does not support Enhanced AGI yet\n");
1306                 return AGI_RESULT_FAILURE;
1307         }
1308
1309         /* add AsyncAGI datastore to the channel */
1310         if (add_to_agi(chan)) {
1311                 ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", ast_channel_name(chan));
1312                 return AGI_RESULT_FAILURE;
1313         }
1314
1315         /* this pipe allows us to create a "fake" AGI struct to use
1316            the AGI commands */
1317         res = pipe(fds);
1318         if (res) {
1319                 ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
1320                 /*
1321                  * Intentionally do not remove the datastore added with
1322                  * add_to_agi() the from channel.  It will be removed when the
1323                  * channel is hung up anyway.
1324                  */
1325                 return AGI_RESULT_FAILURE;
1326         }
1327
1328         /* handlers will get the pipe write fd and we read the AGI responses
1329            from the pipe read fd */
1330         async_agi.fd = fds[1];
1331         async_agi.ctrl = fds[1];
1332         async_agi.audio = -1; /* no audio support */
1333         async_agi.fast = 0;
1334         async_agi.speech = NULL;
1335
1336         /* notify possible manager users of a new channel ready to
1337            receive commands */
1338         setup_env(chan, "async", fds[1], 0, 0, NULL);
1339         /* read the environment */
1340         res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1341         if (res <= 0) {
1342                 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s: %s\n",
1343                                 ast_channel_name(chan), res < 0 ? strerror(errno) : "EOF");
1344                 returnstatus = AGI_RESULT_FAILURE;
1345                 goto async_agi_abort;
1346         }
1347         agi_buffer[res] = '\0';
1348         /* encode it and send it thru the manager so whoever is going to take
1349            care of AGI commands on this channel can decide which AGI commands
1350            to execute based on the setup info */
1351         ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1352         /*** DOCUMENTATION
1353                 <managerEventInstance>
1354                         <synopsis>Raised when a channel starts AsyncAGI command processing.</synopsis>
1355                         <syntax>
1356                                 <parameter name="SubEvent">
1357                                         <para>A sub event type, specifying the channel AsyncAGI processing status.</para>
1358                                         <enumlist>
1359                                                 <enum name="Start"/>
1360                                                 <enum name="Exec"/>
1361                                                 <enum name="End"/>
1362                                         </enumlist>
1363                                 </parameter>
1364                                 <parameter name="Env">
1365                                         <para>URL encoded string read from the AsyncAGI server.</para>
1366                                 </parameter>
1367                         </syntax>
1368                 </managerEventInstance>
1369         ***/
1370         manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1371                 "SubEvent: Start\r\n"
1372                 "Channel: %s\r\n"
1373                 "Uniqueid: %s\r\n"
1374                 "Env: %s\r\n",
1375                 ast_channel_name(chan),
1376                 ast_channel_uniqueid(chan),
1377                 ami_buffer);
1378         hungup = ast_check_hangup(chan);
1379         for (;;) {
1380                 /*
1381                  * Process as many commands as we can.  Commands are added via
1382                  * the manager or the cli threads.
1383                  */
1384                 while (!hungup) {
1385                         res = get_agi_cmd(chan, &cmd);
1386
1387                         if (res) {
1388                                 returnstatus = AGI_RESULT_FAILURE;
1389                                 goto async_agi_done;
1390                         } else if (!cmd) {
1391                                 break;
1392                         }
1393
1394                         /* OK, we have a command, let's call the command handler. */
1395                         cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
1396
1397                         /*
1398                          * The command handler must have written to our fake AGI struct
1399                          * fd (the pipe), let's read the response.
1400                          */
1401                         res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
1402                         if (res <= 0) {
1403                                 ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s: %s\n",
1404                                         ast_channel_name(chan), res < 0 ? strerror(errno) : "EOF");
1405                                 free_agi_cmd(cmd);
1406                                 returnstatus = AGI_RESULT_FAILURE;
1407                                 goto async_agi_done;
1408                         }
1409                         /*
1410                          * We have a response, let's send the response thru the manager.
1411                          * Include the CommandID if it was specified when the command
1412                          * was added.
1413                          */
1414                         agi_buffer[res] = '\0';
1415                         ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
1416                         if (ast_strlen_zero(cmd->cmd_id)) {
1417                                 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1418                                         "SubEvent: Exec\r\n"
1419                                         "Channel: %s\r\n"
1420                                         "Uniqueid: %s\r\n"
1421                                         "Result: %s\r\n",
1422                                         ast_channel_name(chan),
1423                                         ast_channel_uniqueid(chan),
1424                                         ami_buffer);
1425                         } else {
1426                                 /*** DOCUMENTATION
1427                                         <managerEventInstance>
1428                                                 <synopsis>Raised when AsyncAGI completes an AGI command.</synopsis>
1429                                                 <syntax>
1430                                                         <parameter name="CommandID" required="false">
1431                                                                 <para>Optional command ID sent by the AsyncAGI server to identify the command.</para>
1432                                                         </parameter>
1433                                                         <parameter name="Result">
1434                                                                 <para>URL encoded result string from the executed AGI command.</para>
1435                                                         </parameter>
1436                                                 </syntax>
1437                                         </managerEventInstance>
1438                                 ***/
1439                                 manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1440                                         "SubEvent: Exec\r\n"
1441                                         "Channel: %s\r\n"
1442                                         "Uniqueid: %s\r\n"
1443                                         "CommandID: %s\r\n"
1444                                         "Result: %s\r\n",
1445                                         ast_channel_name(chan),
1446                                         ast_channel_uniqueid(chan),
1447                                         cmd->cmd_id,
1448                                         ami_buffer);
1449                         }
1450                         free_agi_cmd(cmd);
1451
1452                         /*
1453                          * Check the command status to determine if we should continue
1454                          * executing more commands.
1455                          */
1456                         hungup = ast_check_hangup(chan);
1457                         switch (cmd_status) {
1458                         case AGI_RESULT_FAILURE:
1459                                 if (!hungup) {
1460                                         /* The failure was not because of a hangup. */
1461                                         returnstatus = AGI_RESULT_FAILURE;
1462                                         goto async_agi_done;
1463                                 }
1464                                 break;
1465                         case AGI_RESULT_SUCCESS_ASYNC:
1466                                 /* Only the "asyncagi break" command does this. */
1467                                 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1468                                 goto async_agi_done;
1469                         default:
1470                                 break;
1471                         }
1472                 }
1473
1474                 if (!hungup) {
1475                         /* Wait a bit for a frame to read or to poll for a new command. */
1476                         res = ast_waitfor(chan, timeout);
1477                         if (res < 0) {
1478                                 ast_debug(1, "ast_waitfor returned <= 0 on chan %s\n", ast_channel_name(chan));
1479                                 returnstatus = AGI_RESULT_FAILURE;
1480                                 break;
1481                         }
1482                 } else {
1483                         /*
1484                          * Read the channel control queue until it is dry so we can
1485                          * quit.
1486                          */
1487                         res = 1;
1488                 }
1489                 if (0 < res) {
1490                         do {
1491                                 cmd_status = async_agi_read_frame(chan);
1492                                 if (cmd_status != AGI_RESULT_SUCCESS) {
1493                                         returnstatus = cmd_status;
1494                                         goto async_agi_done;
1495                                 }
1496                                 hungup = ast_check_hangup(chan);
1497                         } while (hungup);
1498                 } else {
1499                         hungup = ast_check_hangup(chan);
1500                 }
1501         }
1502 async_agi_done:
1503
1504         if (async_agi.speech) {
1505                 ast_speech_destroy(async_agi.speech);
1506         }
1507         /* notify manager users this channel cannot be controlled anymore by Async AGI */
1508         /*** DOCUMENTATION
1509                 <managerEventInstance>
1510                         <synopsis>Raised when a channel stops AsyncAGI command processing.</synopsis>
1511                 </managerEventInstance>
1512         ***/
1513         manager_event(EVENT_FLAG_AGI, "AsyncAGI",
1514                 "SubEvent: End\r\n"
1515                 "Channel: %s\r\n"
1516                 "Uniqueid: %s\r\n",
1517                 ast_channel_name(chan),
1518                 ast_channel_uniqueid(chan));
1519
1520 async_agi_abort:
1521         /* close the pipe */
1522         close(fds[0]);
1523         close(fds[1]);
1524
1525         /*
1526          * Intentionally do not remove the datastore added with
1527          * add_to_agi() the from channel.  There might be commands still
1528          * in the queue or in-flight to us and AsyncAGI may get called
1529          * again.  The datastore destructor will be called on channel
1530          * destruction anyway.
1531          */
1532
1533         if (returnstatus == AGI_RESULT_SUCCESS) {
1534                 returnstatus = AGI_RESULT_SUCCESS_ASYNC;
1535         }
1536         return returnstatus;
1537
1538 #undef AGI_BUF_SIZE
1539 #undef AMI_BUF_SIZE
1540 }
1541
1542 /*!
1543  * \internal
1544  * \brief Handle the connection that was started by launch_netscript.
1545  *
1546  * \param agiurl Url that we are trying to connect to.
1547  * \param addr Address that host was resolved to.
1548  * \param netsockfd File descriptor of socket.
1549  *
1550  * \retval 0 when connection is succesful.
1551  * \retval 1 when there is an error.
1552  */
1553 static int handle_connection(const char *agiurl, const struct ast_sockaddr addr, const int netsockfd)
1554 {
1555         struct pollfd pfds[1];
1556         int res, conresult;
1557         socklen_t reslen;
1558
1559         reslen = sizeof(conresult);
1560
1561         pfds[0].fd = netsockfd;
1562         pfds[0].events = POLLOUT;
1563
1564         while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
1565                 if (errno != EINTR) {
1566                         if (!res) {
1567                                 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
1568                                         agiurl, MAX_AGI_CONNECT);
1569                         } else {
1570                                 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1571                         }
1572
1573                         return 1;
1574                 }
1575         }
1576
1577         if (getsockopt(pfds[0].fd, SOL_SOCKET, SO_ERROR, &conresult, &reslen) < 0) {
1578                 ast_log(LOG_WARNING, "Connection to %s failed with error: %s\n",
1579                         ast_sockaddr_stringify(&addr), strerror(errno));
1580                 return 1;
1581         }
1582
1583         if (conresult) {
1584                 ast_log(LOG_WARNING, "Connecting to '%s' failed for url '%s': %s\n",
1585                         ast_sockaddr_stringify(&addr), agiurl, strerror(conresult));
1586                 return 1;
1587         }
1588
1589         return 0;
1590 }
1591
1592 /* launch_netscript: The fastagi handler.
1593         FastAGI defaults to port 4573 */
1594 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
1595 {
1596         int s = 0, flags;
1597         char *host, *script;
1598         int num_addrs = 0, i = 0;
1599         struct ast_sockaddr *addrs;
1600
1601         /* agiurl is "agi://host.domain[:port][/script/name]" */
1602         host = ast_strdupa(agiurl + 6); /* Remove agi:// */
1603
1604         /* Strip off any script name */
1605         if ((script = strchr(host, '/'))) {
1606                 *script++ = '\0';
1607         } else {
1608                 script = "";
1609         }
1610
1611         if (!(num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC))) {
1612                 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
1613                 return AGI_RESULT_FAILURE;
1614         }
1615
1616         for (i = 0; i < num_addrs; i++) {
1617                 if (!ast_sockaddr_port(&addrs[i])) {
1618                         ast_sockaddr_set_port(&addrs[i], AGI_PORT);
1619                 }
1620
1621                 if ((s = socket(addrs[i].ss.ss_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
1622                         ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1623                         continue;
1624                 }
1625
1626                 if ((flags = fcntl(s, F_GETFL)) < 0) {
1627                         ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
1628                         close(s);
1629                         continue;
1630                 }
1631
1632                 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
1633                         ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
1634                         close(s);
1635                         continue;
1636                 }
1637
1638                 if (ast_connect(s, &addrs[i]) && errno == EINPROGRESS) {
1639
1640                         if (handle_connection(agiurl, addrs[i], s)) {
1641                                 close(s);
1642                                 continue;
1643                         }
1644
1645                 } else {
1646                         ast_log(LOG_WARNING, "Connection to %s failed with unexpected error: %s\n",
1647                         ast_sockaddr_stringify(&addrs[i]), strerror(errno));
1648                 }
1649
1650                 break;
1651         }
1652
1653         ast_free(addrs);
1654
1655         if (i == num_addrs) {
1656                 ast_log(LOG_WARNING, "Couldn't connect to any host.  FastAGI failed.\n");
1657                 return AGI_RESULT_FAILURE;
1658         }
1659
1660         if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
1661                 if (errno != EINTR) {
1662                         ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1663                         close(s);
1664                         return AGI_RESULT_FAILURE;
1665                 }
1666         }
1667
1668         /* If we have a script parameter, relay it to the fastagi server */
1669         /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
1670         if (!ast_strlen_zero(script)) {
1671                 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
1672         }
1673
1674         ast_debug(4, "Wow, connected!\n");
1675         fds[0] = s;
1676         fds[1] = s;
1677         return AGI_RESULT_SUCCESS_FAST;
1678 }
1679
1680 /*!
1681  * \internal
1682  * \brief The HA fastagi handler.
1683  * \param agiurl The request URL as passed to Agi() in the dial plan
1684  * \param argv The parameters after the URL passed to Agi() in the dial plan
1685  * \param fds Input/output file descriptors
1686  *
1687  * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
1688  * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
1689  * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
1690  * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
1691  * this resolves.
1692  *
1693  * This function parses the URI, resolves the SRV service name, forms new URIs
1694  * with the results of the DNS lookup, and then calls launch_netscript on the
1695  * new URIs until one succeeds.
1696  *
1697  * \return the result of the AGI operation.
1698  */
1699 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
1700 {
1701         char *host, *script;
1702         enum agi_result result;
1703         struct srv_context *context = NULL;
1704         int srv_ret;
1705         char service[256];
1706         char resolved_uri[1024];
1707         const char *srvhost;
1708         unsigned short srvport;
1709
1710         /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
1711         if (strlen(agiurl) < 7) { /* Remove hagi:// */
1712                 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
1713                 return AGI_RESULT_FAILURE;
1714         }
1715         host = ast_strdupa(agiurl + 7);
1716
1717         /* Strip off any script name */
1718         if ((script = strchr(host, '/'))) {
1719                 *script++ = '\0';
1720         } else {
1721                 script = "";
1722         }
1723
1724         if (strchr(host, ':')) {
1725                 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
1726                 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
1727         }
1728
1729         snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
1730
1731         while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
1732                 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
1733                 result = launch_netscript(resolved_uri, argv, fds);
1734                 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
1735                         ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
1736                 } else {
1737                         /* The script launched so we must cleanup the context. */
1738                         ast_srv_cleanup(&context);
1739                         return result;
1740                 }
1741         }
1742         /*
1743          * The DNS SRV lookup failed or we ran out of servers to check.
1744          * ast_srv_lookup() has already cleaned up the context for us.
1745          */
1746         if (srv_ret < 0) {
1747                 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
1748         }
1749
1750         return AGI_RESULT_FAILURE;
1751 }
1752
1753 static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
1754 {
1755         char tmp[256];
1756         int pid, toast[2], fromast[2], audio[2], res;
1757         struct stat st;
1758
1759         if (!strncasecmp(script, "agi://", 6)) {
1760                 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1761         }
1762         if (!strncasecmp(script, "hagi://", 7)) {
1763                 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1764         }
1765         if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
1766                 return launch_asyncagi(chan, argv, efd);
1767         }
1768
1769         if (script[0] != '/') {
1770                 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
1771                 script = tmp;
1772         }
1773
1774         /* Before even trying let's see if the file actually exists */
1775         if (stat(script, &st)) {
1776                 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
1777                 return AGI_RESULT_NOTFOUND;
1778         }
1779
1780         if (pipe(toast)) {
1781                 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
1782                 return AGI_RESULT_FAILURE;
1783         }
1784         if (pipe(fromast)) {
1785                 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
1786                 close(toast[0]);
1787                 close(toast[1]);
1788                 return AGI_RESULT_FAILURE;
1789         }
1790         if (efd) {
1791                 if (pipe(audio)) {
1792                         ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
1793                         close(fromast[0]);
1794                         close(fromast[1]);
1795                         close(toast[0]);
1796                         close(toast[1]);
1797                         return AGI_RESULT_FAILURE;
1798                 }
1799                 res = fcntl(audio[1], F_GETFL);
1800                 if (res > -1)
1801                         res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
1802                 if (res < 0) {
1803                         ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
1804                         close(fromast[0]);
1805                         close(fromast[1]);
1806                         close(toast[0]);
1807                         close(toast[1]);
1808                         close(audio[0]);
1809                         close(audio[1]);
1810                         return AGI_RESULT_FAILURE;
1811                 }
1812         }
1813
1814         if ((pid = ast_safe_fork(1)) < 0) {
1815                 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
1816                 return AGI_RESULT_FAILURE;
1817         }
1818         if (!pid) {
1819                 /* Pass paths to AGI via environmental variables */
1820                 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
1821                 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
1822                 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
1823                 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
1824                 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
1825                 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
1826                 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
1827                 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
1828                 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
1829                 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
1830                 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
1831
1832                 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
1833                 ast_set_priority(0);
1834
1835                 /* Redirect stdin and out, provide enhanced audio channel if desired */
1836                 dup2(fromast[0], STDIN_FILENO);
1837                 dup2(toast[1], STDOUT_FILENO);
1838                 if (efd)
1839                         dup2(audio[0], STDERR_FILENO + 1);
1840                 else
1841                         close(STDERR_FILENO + 1);
1842
1843                 /* Close everything but stdin/out/error */
1844                 ast_close_fds_above_n(STDERR_FILENO + 1);
1845
1846                 /* Execute script */
1847                 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
1848                 execv(script, argv);
1849                 /* Can't use ast_log since FD's are closed */
1850                 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
1851                 /* Special case to set status of AGI to failure */
1852                 fprintf(stdout, "failure\n");
1853                 fflush(stdout);
1854                 _exit(1);
1855         }
1856         ast_verb(3, "Launched AGI Script %s\n", script);
1857         fds[0] = toast[0];
1858         fds[1] = fromast[1];
1859         if (efd)
1860                 *efd = audio[1];
1861         /* close what we're not using in the parent */
1862         close(toast[1]);
1863         close(fromast[0]);
1864
1865         if (efd)
1866                 close(audio[0]);
1867
1868         *opid = pid;
1869         return AGI_RESULT_SUCCESS;
1870 }
1871
1872 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
1873 {
1874         int count;
1875
1876         /* Print initial environment, with agi_request always being the first
1877            thing */
1878         ast_agi_send(fd, chan, "agi_request: %s\n", request);
1879         ast_agi_send(fd, chan, "agi_channel: %s\n", ast_channel_name(chan));
1880         ast_agi_send(fd, chan, "agi_language: %s\n", ast_channel_language(chan));
1881         ast_agi_send(fd, chan, "agi_type: %s\n", ast_channel_tech(chan)->type);
1882         ast_agi_send(fd, chan, "agi_uniqueid: %s\n", ast_channel_uniqueid(chan));
1883         ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
1884
1885         /* ANI/DNIS */
1886         ast_agi_send(fd, chan, "agi_callerid: %s\n",
1887                 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "unknown"));
1888         ast_agi_send(fd, chan, "agi_calleridname: %s\n",
1889                 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "unknown"));
1890         ast_agi_send(fd, chan, "agi_callingpres: %d\n",
1891                 ast_party_id_presentation(&ast_channel_caller(chan)->id));
1892         ast_agi_send(fd, chan, "agi_callingani2: %d\n", ast_channel_caller(chan)->ani2);
1893         ast_agi_send(fd, chan, "agi_callington: %d\n", ast_channel_caller(chan)->id.number.plan);
1894         ast_agi_send(fd, chan, "agi_callingtns: %d\n", ast_channel_dialed(chan)->transit_network_select);
1895         ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(ast_channel_dialed(chan)->number.str, "unknown"));
1896         ast_agi_send(fd, chan, "agi_rdnis: %s\n",
1897                 S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, "unknown"));
1898
1899         /* Context information */
1900         ast_agi_send(fd, chan, "agi_context: %s\n", ast_channel_context(chan));
1901         ast_agi_send(fd, chan, "agi_extension: %s\n", ast_channel_exten(chan));
1902         ast_agi_send(fd, chan, "agi_priority: %d\n", ast_channel_priority(chan));
1903         ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
1904
1905         /* User information */
1906         ast_agi_send(fd, chan, "agi_accountcode: %s\n", ast_channel_accountcode(chan) ? ast_channel_accountcode(chan) : "");
1907         ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
1908
1909         /* Send any parameters to the fastagi server that have been passed via the agi application */
1910         /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
1911         for(count = 1; count < argc; count++)
1912                 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
1913
1914         /* End with empty return */
1915         ast_agi_send(fd, chan, "\n");
1916 }
1917
1918 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1919 {
1920         int res = 0;
1921
1922         /* Answer the channel */
1923         if (ast_channel_state(chan) != AST_STATE_UP)
1924                 res = ast_answer(chan);
1925
1926         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1927         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1928 }
1929
1930 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1931 {
1932         ast_agi_send(agi->fd, chan, "200 result=0\n");
1933         return ASYNC_AGI_BREAK;
1934 }
1935
1936 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1937 {
1938         int res, to;
1939
1940         if (argc != 4)
1941                 return RESULT_SHOWUSAGE;
1942         if (sscanf(argv[3], "%30d", &to) != 1)
1943                 return RESULT_SHOWUSAGE;
1944         res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
1945         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1946         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1947 }
1948
1949 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1950 {
1951         int res;
1952
1953         if (argc != 3)
1954                 return RESULT_SHOWUSAGE;
1955
1956         /* At the moment, the parser (perhaps broken) returns with
1957            the last argument PLUS the newline at the end of the input
1958            buffer. This probably needs to be fixed, but I wont do that
1959            because other stuff may break as a result. The right way
1960            would probably be to strip off the trailing newline before
1961            parsing, then here, add a newline at the end of the string
1962            before sending it to ast_sendtext --DUDE */
1963         res = ast_sendtext(chan, argv[2]);
1964         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1965         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1966 }
1967
1968 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1969 {
1970         int res;
1971
1972         if (argc != 3)
1973                 return RESULT_SHOWUSAGE;
1974
1975         res = ast_recvchar(chan,atoi(argv[2]));
1976         if (res == 0) {
1977                 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
1978                 return RESULT_SUCCESS;
1979         }
1980         if (res > 0) {
1981                 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1982                 return RESULT_SUCCESS;
1983         }
1984         ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
1985         return RESULT_FAILURE;
1986 }
1987
1988 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1989 {
1990         char *buf;
1991
1992         if (argc != 3)
1993                 return RESULT_SHOWUSAGE;
1994
1995         buf = ast_recvtext(chan, atoi(argv[2]));
1996         if (buf) {
1997                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
1998                 ast_free(buf);
1999         } else {
2000                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2001         }
2002         return RESULT_SUCCESS;
2003 }
2004
2005 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2006 {
2007         int res, x;
2008
2009         if (argc != 3)
2010                 return RESULT_SHOWUSAGE;
2011
2012         if (!strncasecmp(argv[2],"on",2)) {
2013                 x = 1;
2014         } else  {
2015                 x = 0;
2016         }
2017         if (!strncasecmp(argv[2],"mate",4))  {
2018                 x = 2;
2019         }
2020         if (!strncasecmp(argv[2],"tdd",3)) {
2021                 x = 1;
2022         }
2023         res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
2024         if (res) {
2025                 /* Set channel option failed */
2026                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2027         } else {
2028                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2029         }
2030         return RESULT_SUCCESS;
2031 }
2032
2033 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2034 {
2035         int res;
2036
2037         if (argc != 3) {
2038                 return RESULT_SHOWUSAGE;
2039         }
2040
2041         res = ast_send_image(chan, argv[2]);
2042         if (!ast_check_hangup(chan)) {
2043                 res = 0;
2044         }
2045         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2046         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2047 }
2048
2049 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2050 {
2051         int res = 0, skipms = 3000;
2052         const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL;       /* Default values */
2053         char stopkeybuf[2];
2054         long offsetms = 0;
2055         char offsetbuf[20];
2056
2057         if (argc < 5 || argc > 9) {
2058                 return RESULT_SHOWUSAGE;
2059         }
2060
2061         if (!ast_strlen_zero(argv[4])) {
2062                 stop = argv[4];
2063         }
2064
2065         if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
2066                 return RESULT_SHOWUSAGE;
2067         }
2068
2069         if (argc > 6 && !ast_strlen_zero(argv[6])) {
2070                 fwd = argv[6];
2071         }
2072
2073         if (argc > 7 && !ast_strlen_zero(argv[7])) {
2074                 rev = argv[7];
2075         }
2076
2077         if (argc > 8 && !ast_strlen_zero(argv[8])) {
2078                 suspend = argv[8];
2079         }
2080
2081         res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
2082
2083         /* If we stopped on one of our stop keys, return 0  */
2084         if (res > 0 && stop && strchr(stop, res)) {
2085                 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
2086                 snprintf(stopkeybuf, sizeof(stopkeybuf), "%c", res);
2087                 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTOPKEY", stopkeybuf);
2088         } else if (res > 0 && res == AST_CONTROL_STREAM_STOP) {
2089                 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "REMOTESTOPPED");
2090                 res = 0;
2091         } else {
2092                 if (res < 0) {
2093                         pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "ERROR");
2094                 } else {
2095                         pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS");
2096                 }
2097         }
2098
2099         snprintf(offsetbuf, sizeof(offsetbuf), "%ld", offsetms);
2100         pbx_builtin_setvar_helper(chan, "CPLAYBACKOFFSET", offsetbuf);
2101
2102         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2103
2104         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2105 }
2106
2107 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2108 {
2109         int res;
2110         struct ast_filestream *fs, *vfs;
2111         long sample_offset = 0, max_length;
2112         const char *edigits = "";
2113
2114         if (argc < 4 || argc > 5) {
2115                 return RESULT_SHOWUSAGE;
2116         }
2117
2118         if (argv[3]) {
2119                 edigits = argv[3];
2120         }
2121
2122         if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1)) {
2123                 return RESULT_SHOWUSAGE;
2124         }
2125
2126         if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2127                 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2128                 return RESULT_SUCCESS;
2129         }
2130
2131         if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan)))) {
2132                 ast_debug(1, "Ooh, found a video stream, too\n");
2133         }
2134
2135         ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
2136
2137         ast_seekstream(fs, 0, SEEK_END);
2138         max_length = ast_tellstream(fs);
2139         ast_seekstream(fs, sample_offset, SEEK_SET);
2140         res = ast_applystream(chan, fs);
2141         if (vfs) {
2142                 ast_applystream(chan, vfs);
2143         }
2144         ast_playstream(fs);
2145         if (vfs) {
2146                 ast_playstream(vfs);
2147         }
2148
2149         res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2150         /* this is to check for if ast_waitstream closed the stream, we probably are at
2151          * the end of the stream, return that amount, else check for the amount */
2152         sample_offset = (ast_channel_stream(chan)) ? ast_tellstream(fs) : max_length;
2153         ast_stopstream(chan);
2154         if (res == 1) {
2155                 /* Stop this command, don't print a result line, as there is a new command */
2156                 return RESULT_SUCCESS;
2157         }
2158         ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2159         pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", res ? "FAILED" : "SUCCESS");
2160
2161         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2162 }
2163
2164 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
2165 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2166 {
2167         int res;
2168         struct ast_filestream *fs, *vfs;
2169         long sample_offset = 0, max_length;
2170         int timeout = 0;
2171         const char *edigits = "";
2172
2173         if ( argc < 4 || argc > 5 )
2174                 return RESULT_SHOWUSAGE;
2175
2176         if ( argv[3] )
2177                 edigits = argv[3];
2178
2179         if ( argc == 5 )
2180                 timeout = atoi(argv[4]);
2181         else if (ast_channel_pbx(chan)->dtimeoutms) {
2182                 /* by default dtimeout is set to 5sec */
2183                 timeout = ast_channel_pbx(chan)->dtimeoutms; /* in msec */
2184         }
2185
2186         if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2187                 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2188                 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2189                 return RESULT_SUCCESS;
2190         }
2191
2192         if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan))))
2193                 ast_debug(1, "Ooh, found a video stream, too\n");
2194
2195         ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2196
2197         ast_seekstream(fs, 0, SEEK_END);
2198         max_length = ast_tellstream(fs);
2199         ast_seekstream(fs, sample_offset, SEEK_SET);
2200         res = ast_applystream(chan, fs);
2201         if (vfs)
2202                 ast_applystream(chan, vfs);
2203         ast_playstream(fs);
2204         if (vfs)
2205                 ast_playstream(vfs);
2206
2207         res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2208         /* this is to check for if ast_waitstream closed the stream, we probably are at
2209          * the end of the stream, return that amount, else check for the amount */
2210         sample_offset = (ast_channel_stream(chan))?ast_tellstream(fs):max_length;
2211         ast_stopstream(chan);
2212         if (res == 1) {
2213                 /* Stop this command, don't print a result line, as there is a new command */
2214                 return RESULT_SUCCESS;
2215         }
2216
2217         /* If the user didnt press a key, wait for digitTimeout*/
2218         if (res == 0 ) {
2219                 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2220                 /* Make sure the new result is in the escape digits of the GET OPTION */
2221                 if ( !strchr(edigits,res) )
2222                         res=0;
2223         }
2224
2225         ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2226         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2227 }
2228
2229
2230
2231
2232 /*! \brief Say number in various language syntaxes */
2233 /* While waiting, we're sending a NULL.  */
2234 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2235 {
2236         int res, num;
2237
2238         if (argc < 4 || argc > 5)
2239                 return RESULT_SHOWUSAGE;
2240         if (sscanf(argv[2], "%30d", &num) != 1)
2241                 return RESULT_SHOWUSAGE;
2242         res = ast_say_number_full(chan, num, argv[3], ast_channel_language(chan), argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2243         if (res == 1)
2244                 return RESULT_SUCCESS;
2245         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2246         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2247 }
2248
2249 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2250 {
2251         int res, num;
2252
2253         if (argc != 4)
2254                 return RESULT_SHOWUSAGE;
2255         if (sscanf(argv[2], "%30d", &num) != 1)
2256                 return RESULT_SHOWUSAGE;
2257
2258         res = ast_say_digit_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2259         if (res == 1) /* New command */
2260                 return RESULT_SUCCESS;
2261         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2262         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2263 }
2264
2265 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2266 {
2267         int res;
2268
2269         if (argc != 4)
2270                 return RESULT_SHOWUSAGE;
2271
2272         res = ast_say_character_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2273         if (res == 1) /* New command */
2274                 return RESULT_SUCCESS;
2275         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2276         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2277 }
2278
2279 static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2280 {
2281         int res, num;
2282
2283         if (argc != 4)
2284                 return RESULT_SHOWUSAGE;
2285         if (sscanf(argv[2], "%30d", &num) != 1)
2286                 return RESULT_SHOWUSAGE;
2287         res = ast_say_date(chan, num, argv[3], ast_channel_language(chan));
2288         if (res == 1)
2289                 return RESULT_SUCCESS;
2290         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2291         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2292 }
2293
2294 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2295 {
2296         int res, num;
2297
2298         if (argc != 4)
2299                 return RESULT_SHOWUSAGE;
2300         if (sscanf(argv[2], "%30d", &num) != 1)
2301                 return RESULT_SHOWUSAGE;
2302         res = ast_say_time(chan, num, argv[3], ast_channel_language(chan));
2303         if (res == 1)
2304                 return RESULT_SUCCESS;
2305         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2306         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2307 }
2308
2309 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2310 {
2311         int res = 0;
2312         time_t unixtime;
2313         const char *format, *zone = NULL;
2314
2315         if (argc < 4)
2316                 return RESULT_SHOWUSAGE;
2317
2318         if (argc > 4) {
2319                 format = argv[4];
2320         } else {
2321                 /* XXX this doesn't belong here, but in the 'say' module */
2322                 if (!strcasecmp(ast_channel_language(chan), "de")) {
2323                         format = "A dBY HMS";
2324                 } else {
2325                         format = "ABdY 'digits/at' IMp";
2326                 }
2327         }
2328
2329         if (argc > 5 && !ast_strlen_zero(argv[5]))
2330                 zone = argv[5];
2331
2332         if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2333                 return RESULT_SHOWUSAGE;
2334
2335         res = ast_say_date_with_format(chan, unixtime, argv[3], ast_channel_language(chan), format, zone);
2336         if (res == 1)
2337                 return RESULT_SUCCESS;
2338
2339         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2340         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2341 }
2342
2343 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2344 {
2345         int res;
2346
2347         if (argc != 4)
2348                 return RESULT_SHOWUSAGE;
2349
2350         res = ast_say_phonetic_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2351         if (res == 1) /* New command */
2352                 return RESULT_SUCCESS;
2353         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2354         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2355 }
2356
2357 static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2358 {
2359         int res, max, timeout;
2360         char data[1024];
2361
2362         if (argc < 3)
2363                 return RESULT_SHOWUSAGE;
2364         if (argc >= 4)
2365                 timeout = atoi(argv[3]);
2366         else
2367                 timeout = 0;
2368         if (argc >= 5)
2369                 max = atoi(argv[4]);
2370         else
2371                 max = 1024;
2372         res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2373         if (res == 2)                   /* New command */
2374                 return RESULT_SUCCESS;
2375         else if (res == 1)
2376                 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2377         else if (res < 0 )
2378                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2379         else
2380                 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2381         return RESULT_SUCCESS;
2382 }
2383
2384 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2385 {
2386
2387         if (argc != 3)
2388                 return RESULT_SHOWUSAGE;
2389         ast_channel_context_set(chan, argv[2]);
2390         ast_agi_send(agi->fd, chan, "200 result=0\n");
2391         return RESULT_SUCCESS;
2392 }
2393
2394 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2395 {
2396         if (argc != 3)
2397                 return RESULT_SHOWUSAGE;
2398         ast_channel_exten_set(chan, argv[2]);
2399         ast_agi_send(agi->fd, chan, "200 result=0\n");
2400         return RESULT_SUCCESS;
2401 }
2402
2403 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2404 {
2405         int pri;
2406
2407         if (argc != 3)
2408                 return RESULT_SHOWUSAGE;
2409
2410         if (sscanf(argv[2], "%30d", &pri) != 1) {
2411                 pri = ast_findlabel_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), argv[2],
2412                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));
2413                 if (pri < 1)
2414                         return RESULT_SHOWUSAGE;
2415         }
2416
2417         ast_explicit_goto(chan, NULL, NULL, pri);
2418         ast_agi_send(agi->fd, chan, "200 result=0\n");
2419         return RESULT_SUCCESS;
2420 }
2421
2422 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2423 {
2424         struct ast_filestream *fs;
2425         struct ast_frame *f;
2426         struct timeval start;
2427         long sample_offset = 0;
2428         int res = 0;
2429         int ms;
2430
2431         struct ast_dsp *sildet=NULL;         /* silence detector dsp */
2432         int totalsilence = 0;
2433         int dspsilence = 0;
2434         int silence = 0;                /* amount of silence to allow */
2435         int gotsilence = 0;             /* did we timeout for silence? */
2436         char *silencestr = NULL;
2437         struct ast_format rfmt;
2438         ast_format_clear(&rfmt);
2439
2440         /* XXX EAGI FIXME XXX */
2441
2442         if (argc < 6)
2443                 return RESULT_SHOWUSAGE;
2444         if (sscanf(argv[5], "%30d", &ms) != 1)
2445                 return RESULT_SHOWUSAGE;
2446
2447         if (argc > 6)
2448                 silencestr = strchr(argv[6],'s');
2449         if ((argc > 7) && (!silencestr))
2450                 silencestr = strchr(argv[7],'s');
2451         if ((argc > 8) && (!silencestr))
2452                 silencestr = strchr(argv[8],'s');
2453
2454         if (silencestr) {
2455                 if (strlen(silencestr) > 2) {
2456                         if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2457                                 silencestr++;
2458                                 silencestr++;
2459                                 if (silencestr)
2460                                         silence = atoi(silencestr);
2461                                 if (silence > 0)
2462                                         silence *= 1000;
2463                         }
2464                 }
2465         }
2466
2467         if (silence > 0) {
2468                 ast_format_copy(&rfmt, ast_channel_readformat(chan));
2469                 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2470                 if (res < 0) {
2471                         ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2472                         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2473                         return RESULT_FAILURE;
2474                 }
2475                 sildet = ast_dsp_new();
2476                 if (!sildet) {
2477                         ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2478                         ast_agi_send(agi->fd, chan, "200 result=-1\n");
2479                         return RESULT_FAILURE;
2480                 }
2481                 ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
2482         }
2483         
2484         /* backward compatibility, if no offset given, arg[6] would have been
2485          * caught below and taken to be a beep, else if it is a digit then it is a
2486          * offset */
2487         if ((argc >6) && (sscanf(argv[6], "%30ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
2488                 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2489
2490         if ((argc > 7) && (!strchr(argv[7], '=')))
2491                 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2492
2493         if (!res)
2494                 res = ast_waitstream(chan, argv[4]);
2495         if (res) {
2496                 ast_agi_send(agi->fd, chan, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
2497         } else {
2498                 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE);
2499                 if (!fs) {
2500                         res = -1;
2501                         ast_agi_send(agi->fd, chan, "200 result=%d (writefile)\n", res);
2502                         if (sildet)
2503                                 ast_dsp_free(sildet);
2504                         return RESULT_FAILURE;
2505                 }
2506
2507                 /* Request a video update */
2508                 ast_indicate(chan, AST_CONTROL_VIDUPDATE);
2509
2510                 ast_channel_stream_set(chan, fs);
2511                 ast_applystream(chan,fs);
2512                 /* really should have checks */
2513                 ast_seekstream(fs, sample_offset, SEEK_SET);
2514                 ast_truncstream(fs);
2515
2516                 start = ast_tvnow();
2517                 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
2518                         res = ast_waitfor(chan, ms - ast_tvdiff_ms(ast_tvnow(), start));
2519                         if (res < 0) {
2520                                 ast_closestream(fs);
2521                                 ast_agi_send(agi->fd, chan, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
2522                                 if (sildet)
2523                                         ast_dsp_free(sildet);
2524                                 return RESULT_FAILURE;
2525                         }
2526                         f = ast_read(chan);
2527                         if (!f) {
2528                                 ast_agi_send(agi->fd, chan, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
2529                                 ast_closestream(fs);
2530                                 if (sildet)
2531                                         ast_dsp_free(sildet);
2532                                 return RESULT_FAILURE;
2533                         }
2534                         switch(f->frametype) {
2535                         case AST_FRAME_DTMF:
2536                                 if (strchr(argv[4], f->subclass.integer)) {
2537                                         /* This is an interrupting chracter, so rewind to chop off any small
2538                                            amount of DTMF that may have been recorded
2539                                         */
2540                                         ast_stream_rewind(fs, 200);
2541                                         ast_truncstream(fs);
2542                                         sample_offset = ast_tellstream(fs);
2543                                         ast_agi_send(agi->fd, chan, "200 result=%d (dtmf) endpos=%ld\n", f->subclass.integer, sample_offset);
2544                                         ast_closestream(fs);
2545                                         ast_frfree(f);
2546                                         if (sildet)
2547                                                 ast_dsp_free(sildet);
2548                                         return RESULT_SUCCESS;
2549                                 }
2550                                 break;
2551                         case AST_FRAME_VOICE:
2552                                 ast_writestream(fs, f);
2553                                 /* this is a safe place to check progress since we know that fs
2554                                  * is valid after a write, and it will then have our current
2555                                  * location */
2556                                 sample_offset = ast_tellstream(fs);
2557                                 if (silence > 0) {
2558                                         dspsilence = 0;
2559                                         ast_dsp_silence(sildet, f, &dspsilence);
2560                                         if (dspsilence) {
2561                                                 totalsilence = dspsilence;
2562                                         } else {
2563                                                 totalsilence = 0;
2564                                         }
2565                                         if (totalsilence > silence) {
2566                                                 /* Ended happily with silence */
2567                                                 gotsilence = 1;
2568                                                 break;
2569                                         }
2570                                 }
2571                                 break;
2572                         case AST_FRAME_VIDEO:
2573                                 ast_writestream(fs, f);
2574                         default:
2575                                 /* Ignore all other frames */
2576                                 break;
2577                         }
2578                         ast_frfree(f);
2579                         if (gotsilence)
2580                                 break;
2581                 }
2582
2583                 if (gotsilence) {
2584                         ast_stream_rewind(fs, silence-1000);
2585                         ast_truncstream(fs);
2586                         sample_offset = ast_tellstream(fs);
2587                 }
2588                 ast_agi_send(agi->fd, chan, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
2589                 ast_closestream(fs);
2590         }
2591
2592         if (silence > 0) {
2593                 res = ast_set_read_format(chan, &rfmt);
2594                 if (res)
2595                         ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
2596                 ast_dsp_free(sildet);
2597         }
2598
2599         return RESULT_SUCCESS;
2600 }
2601
2602 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2603 {
2604         double timeout;
2605         struct timeval whentohangup = { 0, 0 };
2606
2607         if (argc != 3)
2608                 return RESULT_SHOWUSAGE;
2609         if (sscanf(argv[2], "%30lf", &timeout) != 1)
2610                 return RESULT_SHOWUSAGE;
2611         if (timeout < 0)
2612                 timeout = 0;
2613         if (timeout) {
2614                 whentohangup.tv_sec = timeout;
2615                 whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
2616         }
2617         ast_channel_setwhentohangup_tv(chan, whentohangup);
2618         ast_agi_send(agi->fd, chan, "200 result=0\n");
2619         return RESULT_SUCCESS;
2620 }
2621
2622 static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2623 {
2624         struct ast_channel *c;
2625
2626         if (argc == 1) {
2627                 /* no argument: hangup the current channel */
2628                 ast_set_hangupsource(chan, "dialplan/agi", 0);
2629                 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
2630                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2631                 return RESULT_SUCCESS;
2632         } else if (argc == 2) {
2633                 /* one argument: look for info on the specified channel */
2634                 if ((c = ast_channel_get_by_name(argv[1]))) {
2635                         /* we have a matching channel */
2636                         ast_set_hangupsource(c, "dialplan/agi", 0);
2637                         ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
2638                         c = ast_channel_unref(c);
2639                         ast_agi_send(agi->fd, chan, "200 result=1\n");
2640                         return RESULT_SUCCESS;
2641                 }
2642                 /* if we get this far no channel name matched the argument given */
2643                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2644                 return RESULT_SUCCESS;
2645         } else {
2646                 return RESULT_SHOWUSAGE;
2647         }
2648 }
2649
2650 static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2651 {
2652         int res, workaround;
2653         struct ast_app *app_to_exec;
2654
2655         if (argc < 2)
2656                 return RESULT_SHOWUSAGE;
2657
2658         ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
2659
2660         if ((app_to_exec = pbx_findapp(argv[1]))) {
2661                 if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) {
2662                         ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
2663                 }
2664                 if (ast_compat_res_agi && argc >= 3 && !ast_strlen_zero(argv[2])) {
2665                         char *compat = ast_alloca(strlen(argv[2]) * 2 + 1), *cptr;
2666                         const char *vptr;
2667                         for (cptr = compat, vptr = argv[2]; *vptr; vptr++) {
2668                                 if (*vptr == ',') {
2669                                         *cptr++ = '\\';
2670                                         *cptr++ = ',';
2671                                 } else if (*vptr == '|') {
2672                                         *cptr++ = ',';
2673                                 } else {
2674                                         *cptr++ = *vptr;
2675                                 }
2676                         }
2677                         *cptr = '\0';
2678                         res = pbx_exec(chan, app_to_exec, compat);
2679                 } else {
2680                         res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
2681                 }
2682                 if (!workaround) {
2683                         ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
2684                 }
2685         } else {
2686                 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
2687                 res = -2;
2688         }
2689         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2690
2691         /* Even though this is wrong, users are depending upon this result. */
2692         return res;
2693 }
2694
2695 static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2696 {
2697         char tmp[256]="";
2698         char *l = NULL, *n = NULL;
2699
2700         if (argv[2]) {
2701                 ast_copy_string(tmp, argv[2], sizeof(tmp));
2702                 ast_callerid_parse(tmp, &n, &l);
2703                 if (l)
2704                         ast_shrink_phone_number(l);
2705                 else
2706                         l = "";
2707                 if (!n)
2708                         n = "";
2709                 ast_set_callerid(chan, l, n, NULL);
2710         }
2711
2712         ast_agi_send(agi->fd, chan, "200 result=1\n");
2713         return RESULT_SUCCESS;
2714 }
2715
2716 static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2717 {
2718         struct ast_channel *c;
2719         if (argc == 2) {
2720                 /* no argument: supply info on the current channel */
2721                 ast_agi_send(agi->fd, chan, "200 result=%d\n", ast_channel_state(chan));
2722                 return RESULT_SUCCESS;
2723         } else if (argc == 3) {
2724                 /* one argument: look for info on the specified channel */
2725                 if ((c = ast_channel_get_by_name(argv[2]))) {
2726                         ast_agi_send(agi->fd, chan, "200 result=%d\n", ast_channel_state(c));
2727                         c = ast_channel_unref(c);
2728                         return RESULT_SUCCESS;
2729                 }
2730                 /* if we get this far no channel name matched the argument given */
2731                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2732                 return RESULT_SUCCESS;
2733         } else {
2734                 return RESULT_SHOWUSAGE;
2735         }
2736 }
2737
2738 static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2739 {
2740         if (argv[3])
2741                 pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
2742
2743         ast_agi_send(agi->fd, chan, "200 result=1\n");
2744         return RESULT_SUCCESS;
2745 }
2746
2747 static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2748 {
2749         char *ret;
2750         char tempstr[1024] = "";
2751
2752         if (argc != 3)
2753                 return RESULT_SHOWUSAGE;
2754
2755         /* check if we want to execute an ast_custom_function */
2756         if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
2757                 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
2758         } else {
2759                 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
2760         }
2761
2762         if (ret)
2763                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ret);
2764         else
2765                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2766
2767         return RESULT_SUCCESS;
2768 }
2769
2770 static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2771 {
2772         struct ast_channel *chan2 = NULL;
2773
2774         if (argc != 4 && argc != 5) {
2775                 return RESULT_SHOWUSAGE;
2776         }
2777
2778         if (argc == 5) {
2779                 chan2 = ast_channel_get_by_name(argv[4]);
2780         } else {
2781                 chan2 = ast_channel_ref(chan);
2782         }
2783
2784         if (chan2) {
2785                 struct ast_str *str = ast_str_create(16);
2786                 if (!str) {
2787                         ast_agi_send(agi->fd, chan, "200 result=0\n");
2788                         return RESULT_SUCCESS;
2789                 }
2790                 ast_str_substitute_variables(&str, 0, chan2, argv[3]);
2791                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str));
2792                 ast_free(str);
2793         } else {
2794                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2795         }
2796
2797         if (chan2) {
2798                 chan2 = ast_channel_unref(chan2);
2799         }
2800
2801         return RESULT_SUCCESS;
2802 }
2803
2804 static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2805 {
2806         int level = 0;
2807
2808         if (argc < 2)
2809                 return RESULT_SHOWUSAGE;
2810
2811         if (argv[2])
2812                 sscanf(argv[2], "%30d", &level);
2813
2814         ast_verb(level, "%s: %s\n", ast_channel_data(chan), argv[1]);
2815
2816         ast_agi_send(agi->fd, chan, "200 result=1\n");
2817
2818         return RESULT_SUCCESS;
2819 }
2820
2821 static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2822 {
2823         int res;
2824         struct ast_str *buf;
2825
2826         if (argc != 4)
2827                 return RESULT_SHOWUSAGE;
2828
2829         if (!(buf = ast_str_create(16))) {
2830                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2831                 return RESULT_SUCCESS;
2832         }
2833
2834         do {
2835                 res = ast_db_get(argv[2], argv[3], ast_str_buffer(buf), ast_str_size(buf));
2836                 ast_str_update(buf);
2837                 if (ast_str_strlen(buf) < ast_str_size(buf) - 1) {
2838                         break;
2839                 }
2840                 if (ast_str_make_space(&buf, ast_str_size(buf) * 2)) {
2841                         break;
2842                 }
2843         } while (1);
2844         
2845         if (res)
2846                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2847         else
2848                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(buf));
2849
2850         ast_free(buf);
2851         return RESULT_SUCCESS;
2852 }
2853
2854 static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2855 {
2856         int res;
2857
2858         if (argc != 5)
2859                 return RESULT_SHOWUSAGE;
2860         res = ast_db_put(argv[2], argv[3], argv[4]);
2861         ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2862         return RESULT_SUCCESS;
2863 }
2864
2865 static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2866 {
2867         int res;
2868
2869         if (argc != 4)
2870                 return RESULT_SHOWUSAGE;
2871         res = ast_db_del(argv[2], argv[3]);
2872         ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2873         return RESULT_SUCCESS;
2874 }
2875
2876 static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2877 {
2878         int num_deleted;
2879
2880         if ((argc < 3) || (argc > 4)) {
2881                 return RESULT_SHOWUSAGE;
2882         }
2883         if (argc == 4) {
2884                 num_deleted = ast_db_deltree(argv[2], argv[3]);
2885         } else {
2886                 num_deleted = ast_db_deltree(argv[2], NULL);
2887         }
2888
2889         ast_agi_send(agi->fd, chan, "200 result=%c\n", num_deleted > 0 ? '0' : '1');
2890         return RESULT_SUCCESS;
2891 }
2892
2893 static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2894 {
2895         switch (cmd) {
2896         case CLI_INIT:
2897                 e->command = "agi set debug [on|off]";
2898                 e->usage =
2899                         "Usage: agi set debug [on|off]\n"
2900                         "       Enables/disables dumping of AGI transactions for\n"
2901                         "       debugging purposes.\n";
2902                 return NULL;
2903
2904         case CLI_GENERATE:
2905                 return NULL;
2906         }
2907
2908         if (a->argc != e->args)
2909                 return CLI_SHOWUSAGE;
2910
2911         if (strncasecmp(a->argv[3], "off", 3) == 0) {
2912                 agidebug = 0;
2913         } else if (strncasecmp(a->argv[3], "on", 2) == 0) {
2914                 agidebug = 1;
2915         } else {
2916                 return CLI_SHOWUSAGE;
2917         }
2918         ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis");
2919         return CLI_SUCCESS;
2920 }
2921
2922 static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, const char * const argv[])
2923 {
2924         ast_agi_send(agi->fd, chan, "200 result=0\n");
2925         return RESULT_SUCCESS;
2926 }
2927
2928 static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2929 {
2930         if (argc < 3) {
2931                 return RESULT_SHOWUSAGE;
2932         }
2933         if (!strncasecmp(argv[2], "on", 2))
2934                 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
2935         else if (!strncasecmp(argv[2], "off", 3))
2936                 ast_moh_stop(chan);
2937         ast_agi_send(agi->fd, chan, "200 result=0\n");
2938         return RESULT_SUCCESS;
2939 }
2940
2941 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2942 {
2943         struct ast_format_cap *cap;
2944         struct ast_format tmpfmt;
2945
2946         /* If a structure already exists, return an error */
2947         if (agi->speech) {
2948                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2949                 return RESULT_SUCCESS;
2950         }
2951
2952         if (!(cap = ast_format_cap_alloc_nolock())) {
2953                 return RESULT_FAILURE;
2954         }
2955         ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
2956         if ((agi->speech = ast_speech_new(argv[2], cap))) {
2957                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2958         } else {
2959                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2960         }
2961         cap = ast_format_cap_destroy(cap);
2962
2963         return RESULT_SUCCESS;
2964 }
2965
2966 static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2967 {
2968         /* Check for minimum arguments */
2969         if (argc != 4)
2970                 return RESULT_SHOWUSAGE;
2971
2972         /* Check to make sure speech structure exists */
2973         if (!agi->speech) {
2974                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2975                 return RESULT_SUCCESS;
2976         }
2977
2978         ast_speech_change(agi->speech, argv[2], argv[3]);
2979         ast_agi_send(agi->fd, chan, "200 result=1\n");
2980
2981         return RESULT_SUCCESS;
2982 }
2983
2984 static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2985 {
2986         if (agi->speech) {
2987                 ast_speech_destroy(agi->speech);
2988                 agi->speech = NULL;
2989                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2990         } else {
2991                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2992         }
2993
2994         return RESULT_SUCCESS;
2995 }
2996
2997 static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2998 {
2999         if (argc != 5)
3000                 return RESULT_SHOWUSAGE;
3001
3002         if (!agi->speech) {
3003                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3004                 return RESULT_SUCCESS;
3005         }
3006
3007         if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
3008                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3009         else
3010                 ast_agi_send(agi->fd, chan, "200 result=1\n");
3011
3012         return RESULT_SUCCESS;
3013 }
3014
3015 static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
3016 {
3017         if (argc != 4)
3018                 return RESULT_SHOWUSAGE;
3019
3020         if (!agi->speech) {
3021                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3022                 return RESULT_SUCCESS;
3023         }
3024
3025         if (ast_speech_grammar_unload(agi->speech, argv[3]))
3026                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3027         else
3028                 ast_agi_send(agi->fd, chan, "200 result=1\n");
3029
3030         return RESULT_SUCCESS;
3031 }
3032
3033 static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
3034 {
3035         if (argc != 4)
3036                 return RESULT_SHOWUSAGE;
3037
3038         if (!agi->speech) {
3039                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3040                 return RESULT_SUCCESS;
3041         }
3042
3043         if (ast_speech_grammar_activate(agi->speech, argv[3]))
3044                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3045         else
3046                 ast_agi_send(agi->fd, chan, "200 result=1\n");
3047