Add ControlPlayback manager action
[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 /* launch_netscript: The fastagi handler.
1543         FastAGI defaults to port 4573 */
1544 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
1545 {
1546         int s = 0, flags, res;
1547         struct pollfd pfds[1];
1548         char *host, *script;
1549         int num_addrs = 0, i = 0;
1550         struct ast_sockaddr *addrs;
1551
1552         /* agiurl is "agi://host.domain[:port][/script/name]" */
1553         host = ast_strdupa(agiurl + 6); /* Remove agi:// */
1554
1555         /* Strip off any script name */
1556         if ((script = strchr(host, '/'))) {
1557                 *script++ = '\0';
1558         } else {
1559                 script = "";
1560         }
1561
1562         if (!(num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC))) {
1563                 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
1564                 return AGI_RESULT_FAILURE;
1565         }
1566
1567         for (i = 0; i < num_addrs; i++) {
1568                 if (!ast_sockaddr_port(&addrs[i])) {
1569                         ast_sockaddr_set_port(&addrs[i], AGI_PORT);
1570                 }
1571
1572                 if ((s = socket(addrs[i].ss.ss_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
1573                         ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1574                         continue;
1575                 }
1576
1577                 if ((flags = fcntl(s, F_GETFL)) < 0) {
1578                         ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
1579                         close(s);
1580                         continue;
1581                 }
1582
1583                 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
1584                         ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
1585                         close(s);
1586                         continue;
1587                 }
1588
1589                 if (ast_connect(s, &addrs[i]) && (errno != EINPROGRESS)) {
1590                         ast_log(LOG_WARNING, "Connection to %s failed with unexpected error: %s\n",
1591                                 ast_sockaddr_stringify(&addrs[i]),
1592                                 strerror(errno));
1593                         close(s);
1594                         continue;
1595                 }
1596
1597                 break;
1598         }
1599
1600         ast_free(addrs);
1601
1602         if (i == num_addrs) {
1603                 ast_log(LOG_WARNING, "Couldn't connect to any host.  FastAGI failed.\n");
1604                 return AGI_RESULT_FAILURE;
1605         }
1606
1607         pfds[0].fd = s;
1608         pfds[0].events = POLLOUT;
1609         while ((res = ast_poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
1610                 if (errno != EINTR) {
1611                         if (!res) {
1612                                 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
1613                                         agiurl, MAX_AGI_CONNECT);
1614                         } else
1615                                 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1616                         close(s);
1617                         return AGI_RESULT_FAILURE;
1618                 }
1619         }
1620
1621         if (ast_agi_send(s, NULL, "agi_network: yes\n") < 0) {
1622                 if (errno != EINTR) {
1623                         ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
1624                         close(s);
1625                         return AGI_RESULT_FAILURE;
1626                 }
1627         }
1628
1629         /* If we have a script parameter, relay it to the fastagi server */
1630         /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */
1631         if (!ast_strlen_zero(script))
1632                 ast_agi_send(s, NULL, "agi_network_script: %s\n", script);
1633
1634         ast_debug(4, "Wow, connected!\n");
1635         fds[0] = s;
1636         fds[1] = s;
1637         return AGI_RESULT_SUCCESS_FAST;
1638 }
1639
1640 /*!
1641  * \internal
1642  * \brief The HA fastagi handler.
1643  * \param agiurl The request URL as passed to Agi() in the dial plan
1644  * \param argv The parameters after the URL passed to Agi() in the dial plan
1645  * \param fds Input/output file descriptors
1646  *
1647  * Uses SRV lookups to try to connect to a list of FastAGI servers. The hostname in
1648  * the URI is prefixed with _agi._tcp. prior to the DNS resolution. For
1649  * example, if you specify the URI \a hagi://agi.example.com/foo.agi the DNS
1650  * query would be for \a _agi._tcp.agi.example.com and you'll need to make sure
1651  * this resolves.
1652  *
1653  * This function parses the URI, resolves the SRV service name, forms new URIs
1654  * with the results of the DNS lookup, and then calls launch_netscript on the
1655  * new URIs until one succeeds.
1656  *
1657  * \return the result of the AGI operation.
1658  */
1659 static enum agi_result launch_ha_netscript(char *agiurl, char *argv[], int *fds)
1660 {
1661         char *host, *script;
1662         enum agi_result result;
1663         struct srv_context *context = NULL;
1664         int srv_ret;
1665         char service[256];
1666         char resolved_uri[1024];
1667         const char *srvhost;
1668         unsigned short srvport;
1669
1670         /* format of agiurl is "hagi://host.domain[:port][/script/name]" */
1671         if (strlen(agiurl) < 7) { /* Remove hagi:// */
1672                 ast_log(LOG_WARNING, "An error occurred parsing the AGI URI: %s", agiurl);
1673                 return AGI_RESULT_FAILURE;
1674         }
1675         host = ast_strdupa(agiurl + 7);
1676
1677         /* Strip off any script name */
1678         if ((script = strchr(host, '/'))) {
1679                 *script++ = '\0';
1680         } else {
1681                 script = "";
1682         }
1683
1684         if (strchr(host, ':')) {
1685                 ast_log(LOG_WARNING, "Specifying a port number disables SRV lookups: %s\n", agiurl);
1686                 return launch_netscript(agiurl + 1, argv, fds); /* +1 to strip off leading h from hagi:// */
1687         }
1688
1689         snprintf(service, sizeof(service), "%s%s", SRV_PREFIX, host);
1690
1691         while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
1692                 snprintf(resolved_uri, sizeof(resolved_uri), "agi://%s:%d/%s", srvhost, srvport, script);
1693                 result = launch_netscript(resolved_uri, argv, fds);
1694                 if (result == AGI_RESULT_FAILURE || result == AGI_RESULT_NOTFOUND) {
1695                         ast_log(LOG_WARNING, "AGI request failed for host '%s' (%s:%d)\n", host, srvhost, srvport);
1696                 } else {
1697                         /* The script launched so we must cleanup the context. */
1698                         ast_srv_cleanup(&context);
1699                         return result;
1700                 }
1701         }
1702         /*
1703          * The DNS SRV lookup failed or we ran out of servers to check.
1704          * ast_srv_lookup() has already cleaned up the context for us.
1705          */
1706         if (srv_ret < 0) {
1707                 ast_log(LOG_WARNING, "SRV lookup failed for %s\n", agiurl);
1708         }
1709
1710         return AGI_RESULT_FAILURE;
1711 }
1712
1713 static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
1714 {
1715         char tmp[256];
1716         int pid, toast[2], fromast[2], audio[2], res;
1717         struct stat st;
1718
1719         if (!strncasecmp(script, "agi://", 6)) {
1720                 return (efd == NULL) ? launch_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1721         }
1722         if (!strncasecmp(script, "hagi://", 7)) {
1723                 return (efd == NULL) ? launch_ha_netscript(script, argv, fds) : AGI_RESULT_FAILURE;
1724         }
1725         if (!strncasecmp(script, "agi:async", sizeof("agi:async") - 1)) {
1726                 return launch_asyncagi(chan, argv, efd);
1727         }
1728
1729         if (script[0] != '/') {
1730                 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
1731                 script = tmp;
1732         }
1733
1734         /* Before even trying let's see if the file actually exists */
1735         if (stat(script, &st)) {
1736                 ast_log(LOG_WARNING, "Failed to execute '%s': File does not exist.\n", script);
1737                 return AGI_RESULT_NOTFOUND;
1738         }
1739
1740         if (pipe(toast)) {
1741                 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
1742                 return AGI_RESULT_FAILURE;
1743         }
1744         if (pipe(fromast)) {
1745                 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
1746                 close(toast[0]);
1747                 close(toast[1]);
1748                 return AGI_RESULT_FAILURE;
1749         }
1750         if (efd) {
1751                 if (pipe(audio)) {
1752                         ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
1753                         close(fromast[0]);
1754                         close(fromast[1]);
1755                         close(toast[0]);
1756                         close(toast[1]);
1757                         return AGI_RESULT_FAILURE;
1758                 }
1759                 res = fcntl(audio[1], F_GETFL);
1760                 if (res > -1)
1761                         res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
1762                 if (res < 0) {
1763                         ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
1764                         close(fromast[0]);
1765                         close(fromast[1]);
1766                         close(toast[0]);
1767                         close(toast[1]);
1768                         close(audio[0]);
1769                         close(audio[1]);
1770                         return AGI_RESULT_FAILURE;
1771                 }
1772         }
1773
1774         if ((pid = ast_safe_fork(1)) < 0) {
1775                 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
1776                 return AGI_RESULT_FAILURE;
1777         }
1778         if (!pid) {
1779                 /* Pass paths to AGI via environmental variables */
1780                 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
1781                 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
1782                 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
1783                 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
1784                 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
1785                 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
1786                 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
1787                 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
1788                 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
1789                 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
1790                 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
1791
1792                 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
1793                 ast_set_priority(0);
1794
1795                 /* Redirect stdin and out, provide enhanced audio channel if desired */
1796                 dup2(fromast[0], STDIN_FILENO);
1797                 dup2(toast[1], STDOUT_FILENO);
1798                 if (efd)
1799                         dup2(audio[0], STDERR_FILENO + 1);
1800                 else
1801                         close(STDERR_FILENO + 1);
1802
1803                 /* Close everything but stdin/out/error */
1804                 ast_close_fds_above_n(STDERR_FILENO + 1);
1805
1806                 /* Execute script */
1807                 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
1808                 execv(script, argv);
1809                 /* Can't use ast_log since FD's are closed */
1810                 ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
1811                 /* Special case to set status of AGI to failure */
1812                 fprintf(stdout, "failure\n");
1813                 fflush(stdout);
1814                 _exit(1);
1815         }
1816         ast_verb(3, "Launched AGI Script %s\n", script);
1817         fds[0] = toast[0];
1818         fds[1] = fromast[1];
1819         if (efd)
1820                 *efd = audio[1];
1821         /* close what we're not using in the parent */
1822         close(toast[1]);
1823         close(fromast[0]);
1824
1825         if (efd)
1826                 close(audio[0]);
1827
1828         *opid = pid;
1829         return AGI_RESULT_SUCCESS;
1830 }
1831
1832 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
1833 {
1834         int count;
1835
1836         /* Print initial environment, with agi_request always being the first
1837            thing */
1838         ast_agi_send(fd, chan, "agi_request: %s\n", request);
1839         ast_agi_send(fd, chan, "agi_channel: %s\n", ast_channel_name(chan));
1840         ast_agi_send(fd, chan, "agi_language: %s\n", ast_channel_language(chan));
1841         ast_agi_send(fd, chan, "agi_type: %s\n", ast_channel_tech(chan)->type);
1842         ast_agi_send(fd, chan, "agi_uniqueid: %s\n", ast_channel_uniqueid(chan));
1843         ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
1844
1845         /* ANI/DNIS */
1846         ast_agi_send(fd, chan, "agi_callerid: %s\n",
1847                 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "unknown"));
1848         ast_agi_send(fd, chan, "agi_calleridname: %s\n",
1849                 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "unknown"));
1850         ast_agi_send(fd, chan, "agi_callingpres: %d\n",
1851                 ast_party_id_presentation(&ast_channel_caller(chan)->id));
1852         ast_agi_send(fd, chan, "agi_callingani2: %d\n", ast_channel_caller(chan)->ani2);
1853         ast_agi_send(fd, chan, "agi_callington: %d\n", ast_channel_caller(chan)->id.number.plan);
1854         ast_agi_send(fd, chan, "agi_callingtns: %d\n", ast_channel_dialed(chan)->transit_network_select);
1855         ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(ast_channel_dialed(chan)->number.str, "unknown"));
1856         ast_agi_send(fd, chan, "agi_rdnis: %s\n",
1857                 S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, "unknown"));
1858
1859         /* Context information */
1860         ast_agi_send(fd, chan, "agi_context: %s\n", ast_channel_context(chan));
1861         ast_agi_send(fd, chan, "agi_extension: %s\n", ast_channel_exten(chan));
1862         ast_agi_send(fd, chan, "agi_priority: %d\n", ast_channel_priority(chan));
1863         ast_agi_send(fd, chan, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
1864
1865         /* User information */
1866         ast_agi_send(fd, chan, "agi_accountcode: %s\n", ast_channel_accountcode(chan) ? ast_channel_accountcode(chan) : "");
1867         ast_agi_send(fd, chan, "agi_threadid: %ld\n", (long)pthread_self());
1868
1869         /* Send any parameters to the fastagi server that have been passed via the agi application */
1870         /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
1871         for(count = 1; count < argc; count++)
1872                 ast_agi_send(fd, chan, "agi_arg_%d: %s\n", count, argv[count]);
1873
1874         /* End with empty return */
1875         ast_agi_send(fd, chan, "\n");
1876 }
1877
1878 static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1879 {
1880         int res = 0;
1881
1882         /* Answer the channel */
1883         if (ast_channel_state(chan) != AST_STATE_UP)
1884                 res = ast_answer(chan);
1885
1886         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1887         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1888 }
1889
1890 static int handle_asyncagi_break(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1891 {
1892         ast_agi_send(agi->fd, chan, "200 result=0\n");
1893         return ASYNC_AGI_BREAK;
1894 }
1895
1896 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1897 {
1898         int res, to;
1899
1900         if (argc != 4)
1901                 return RESULT_SHOWUSAGE;
1902         if (sscanf(argv[3], "%30d", &to) != 1)
1903                 return RESULT_SHOWUSAGE;
1904         res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
1905         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1906         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1907 }
1908
1909 static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1910 {
1911         int res;
1912
1913         if (argc != 3)
1914                 return RESULT_SHOWUSAGE;
1915
1916         /* At the moment, the parser (perhaps broken) returns with
1917            the last argument PLUS the newline at the end of the input
1918            buffer. This probably needs to be fixed, but I wont do that
1919            because other stuff may break as a result. The right way
1920            would probably be to strip off the trailing newline before
1921            parsing, then here, add a newline at the end of the string
1922            before sending it to ast_sendtext --DUDE */
1923         res = ast_sendtext(chan, argv[2]);
1924         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1925         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
1926 }
1927
1928 static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1929 {
1930         int res;
1931
1932         if (argc != 3)
1933                 return RESULT_SHOWUSAGE;
1934
1935         res = ast_recvchar(chan,atoi(argv[2]));
1936         if (res == 0) {
1937                 ast_agi_send(agi->fd, chan, "200 result=%d (timeout)\n", res);
1938                 return RESULT_SUCCESS;
1939         }
1940         if (res > 0) {
1941                 ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
1942                 return RESULT_SUCCESS;
1943         }
1944         ast_agi_send(agi->fd, chan, "200 result=%d (hangup)\n", res);
1945         return RESULT_FAILURE;
1946 }
1947
1948 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1949 {
1950         char *buf;
1951
1952         if (argc != 3)
1953                 return RESULT_SHOWUSAGE;
1954
1955         buf = ast_recvtext(chan, atoi(argv[2]));
1956         if (buf) {
1957                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", buf);
1958                 ast_free(buf);
1959         } else {
1960                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
1961         }
1962         return RESULT_SUCCESS;
1963 }
1964
1965 static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1966 {
1967         int res, x;
1968
1969         if (argc != 3)
1970                 return RESULT_SHOWUSAGE;
1971
1972         if (!strncasecmp(argv[2],"on",2)) {
1973                 x = 1;
1974         } else  {
1975                 x = 0;
1976         }
1977         if (!strncasecmp(argv[2],"mate",4))  {
1978                 x = 2;
1979         }
1980         if (!strncasecmp(argv[2],"tdd",3)) {
1981                 x = 1;
1982         }
1983         res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
1984         if (res) {
1985                 /* Set channel option failed */
1986                 ast_agi_send(agi->fd, chan, "200 result=0\n");
1987         } else {
1988                 ast_agi_send(agi->fd, chan, "200 result=1\n");
1989         }
1990         return RESULT_SUCCESS;
1991 }
1992
1993 static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
1994 {
1995         int res;
1996
1997         if (argc != 3) {
1998                 return RESULT_SHOWUSAGE;
1999         }
2000
2001         res = ast_send_image(chan, argv[2]);
2002         if (!ast_check_hangup(chan)) {
2003                 res = 0;
2004         }
2005         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2006         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2007 }
2008
2009 static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2010 {
2011         int res = 0, skipms = 3000;
2012         const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL;       /* Default values */
2013         char stopkeybuf[2];
2014         long offsetms = 0;
2015         char offsetbuf[20];
2016
2017         if (argc < 5 || argc > 9) {
2018                 return RESULT_SHOWUSAGE;
2019         }
2020
2021         if (!ast_strlen_zero(argv[4])) {
2022                 stop = argv[4];
2023         }
2024
2025         if ((argc > 5) && (sscanf(argv[5], "%30d", &skipms) != 1)) {
2026                 return RESULT_SHOWUSAGE;
2027         }
2028
2029         if (argc > 6 && !ast_strlen_zero(argv[6])) {
2030                 fwd = argv[6];
2031         }
2032
2033         if (argc > 7 && !ast_strlen_zero(argv[7])) {
2034                 rev = argv[7];
2035         }
2036
2037         if (argc > 8 && !ast_strlen_zero(argv[8])) {
2038                 suspend = argv[8];
2039         }
2040
2041         res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
2042
2043         /* If we stopped on one of our stop keys, return 0  */
2044         if (res > 0 && stop && strchr(stop, res)) {
2045                 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
2046                 snprintf(stopkeybuf, sizeof(stopkeybuf), "%c", res);
2047                 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTOPKEY", stopkeybuf);
2048         } else if (res > 0 && res == AST_CONTROL_STREAM_STOP) {
2049                 pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "REMOTESTOPPED");
2050                 res = 0;
2051         } else {
2052                 if (res < 0) {
2053                         pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "ERROR");
2054                 } else {
2055                         pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS");
2056                 }
2057         }
2058
2059         snprintf(offsetbuf, sizeof(offsetbuf), "%ld", offsetms);
2060         pbx_builtin_setvar_helper(chan, "CPLAYBACKOFFSET", offsetbuf);
2061
2062         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2063
2064         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2065 }
2066
2067 static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2068 {
2069         int res;
2070         struct ast_filestream *fs, *vfs;
2071         long sample_offset = 0, max_length;
2072         const char *edigits = "";
2073
2074         if (argc < 4 || argc > 5) {
2075                 return RESULT_SHOWUSAGE;
2076         }
2077
2078         if (argv[3]) {
2079                 edigits = argv[3];
2080         }
2081
2082         if ((argc > 4) && (sscanf(argv[4], "%30ld", &sample_offset) != 1)) {
2083                 return RESULT_SHOWUSAGE;
2084         }
2085
2086         if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2087                 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2088                 return RESULT_SUCCESS;
2089         }
2090
2091         if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan)))) {
2092                 ast_debug(1, "Ooh, found a video stream, too\n");
2093         }
2094
2095         ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
2096
2097         ast_seekstream(fs, 0, SEEK_END);
2098         max_length = ast_tellstream(fs);
2099         ast_seekstream(fs, sample_offset, SEEK_SET);
2100         res = ast_applystream(chan, fs);
2101         if (vfs) {
2102                 ast_applystream(chan, vfs);
2103         }
2104         ast_playstream(fs);
2105         if (vfs) {
2106                 ast_playstream(vfs);
2107         }
2108
2109         res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2110         /* this is to check for if ast_waitstream closed the stream, we probably are at
2111          * the end of the stream, return that amount, else check for the amount */
2112         sample_offset = (ast_channel_stream(chan)) ? ast_tellstream(fs) : max_length;
2113         ast_stopstream(chan);
2114         if (res == 1) {
2115                 /* Stop this command, don't print a result line, as there is a new command */
2116                 return RESULT_SUCCESS;
2117         }
2118         ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2119         pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", res ? "FAILED" : "SUCCESS");
2120
2121         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2122 }
2123
2124 /*! \brief get option - really similar to the handle_streamfile, but with a timeout */
2125 static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2126 {
2127         int res;
2128         struct ast_filestream *fs, *vfs;
2129         long sample_offset = 0, max_length;
2130         int timeout = 0;
2131         const char *edigits = "";
2132
2133         if ( argc < 4 || argc > 5 )
2134                 return RESULT_SHOWUSAGE;
2135
2136         if ( argv[3] )
2137                 edigits = argv[3];
2138
2139         if ( argc == 5 )
2140                 timeout = atoi(argv[4]);
2141         else if (ast_channel_pbx(chan)->dtimeoutms) {
2142                 /* by default dtimeout is set to 5sec */
2143                 timeout = ast_channel_pbx(chan)->dtimeoutms; /* in msec */
2144         }
2145
2146         if (!(fs = ast_openstream(chan, argv[2], ast_channel_language(chan)))) {
2147                 ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", 0, sample_offset);
2148                 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
2149                 return RESULT_SUCCESS;
2150         }
2151
2152         if ((vfs = ast_openvstream(chan, argv[2], ast_channel_language(chan))))
2153                 ast_debug(1, "Ooh, found a video stream, too\n");
2154
2155         ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
2156
2157         ast_seekstream(fs, 0, SEEK_END);
2158         max_length = ast_tellstream(fs);
2159         ast_seekstream(fs, sample_offset, SEEK_SET);
2160         res = ast_applystream(chan, fs);
2161         if (vfs)
2162                 ast_applystream(chan, vfs);
2163         ast_playstream(fs);
2164         if (vfs)
2165                 ast_playstream(vfs);
2166
2167         res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
2168         /* this is to check for if ast_waitstream closed the stream, we probably are at
2169          * the end of the stream, return that amount, else check for the amount */
2170         sample_offset = (ast_channel_stream(chan))?ast_tellstream(fs):max_length;
2171         ast_stopstream(chan);
2172         if (res == 1) {
2173                 /* Stop this command, don't print a result line, as there is a new command */
2174                 return RESULT_SUCCESS;
2175         }
2176
2177         /* If the user didnt press a key, wait for digitTimeout*/
2178         if (res == 0 ) {
2179                 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
2180                 /* Make sure the new result is in the escape digits of the GET OPTION */
2181                 if ( !strchr(edigits,res) )
2182                         res=0;
2183         }
2184
2185         ast_agi_send(agi->fd, chan, "200 result=%d endpos=%ld\n", res, sample_offset);
2186         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2187 }
2188
2189
2190
2191
2192 /*! \brief Say number in various language syntaxes */
2193 /* While waiting, we're sending a NULL.  */
2194 static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2195 {
2196         int res, num;
2197
2198         if (argc < 4 || argc > 5)
2199                 return RESULT_SHOWUSAGE;
2200         if (sscanf(argv[2], "%30d", &num) != 1)
2201                 return RESULT_SHOWUSAGE;
2202         res = ast_say_number_full(chan, num, argv[3], ast_channel_language(chan), argc > 4 ? argv[4] : NULL, agi->audio, agi->ctrl);
2203         if (res == 1)
2204                 return RESULT_SUCCESS;
2205         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2206         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2207 }
2208
2209 static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2210 {
2211         int res, num;
2212
2213         if (argc != 4)
2214                 return RESULT_SHOWUSAGE;
2215         if (sscanf(argv[2], "%30d", &num) != 1)
2216                 return RESULT_SHOWUSAGE;
2217
2218         res = ast_say_digit_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2219         if (res == 1) /* New command */
2220                 return RESULT_SUCCESS;
2221         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2222         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2223 }
2224
2225 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2226 {
2227         int res;
2228
2229         if (argc != 4)
2230                 return RESULT_SHOWUSAGE;
2231
2232         res = ast_say_character_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2233         if (res == 1) /* New command */
2234                 return RESULT_SUCCESS;
2235         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2236         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2237 }
2238
2239 static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2240 {
2241         int res, num;
2242
2243         if (argc != 4)
2244                 return RESULT_SHOWUSAGE;
2245         if (sscanf(argv[2], "%30d", &num) != 1)
2246                 return RESULT_SHOWUSAGE;
2247         res = ast_say_date(chan, num, argv[3], ast_channel_language(chan));
2248         if (res == 1)
2249                 return RESULT_SUCCESS;
2250         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2251         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2252 }
2253
2254 static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2255 {
2256         int res, num;
2257
2258         if (argc != 4)
2259                 return RESULT_SHOWUSAGE;
2260         if (sscanf(argv[2], "%30d", &num) != 1)
2261                 return RESULT_SHOWUSAGE;
2262         res = ast_say_time(chan, num, argv[3], ast_channel_language(chan));
2263         if (res == 1)
2264                 return RESULT_SUCCESS;
2265         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2266         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2267 }
2268
2269 static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2270 {
2271         int res = 0;
2272         time_t unixtime;
2273         const char *format, *zone = NULL;
2274
2275         if (argc < 4)
2276                 return RESULT_SHOWUSAGE;
2277
2278         if (argc > 4) {
2279                 format = argv[4];
2280         } else {
2281                 /* XXX this doesn't belong here, but in the 'say' module */
2282                 if (!strcasecmp(ast_channel_language(chan), "de")) {
2283                         format = "A dBY HMS";
2284                 } else {
2285                         format = "ABdY 'digits/at' IMp";
2286                 }
2287         }
2288
2289         if (argc > 5 && !ast_strlen_zero(argv[5]))
2290                 zone = argv[5];
2291
2292         if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
2293                 return RESULT_SHOWUSAGE;
2294
2295         res = ast_say_date_with_format(chan, unixtime, argv[3], ast_channel_language(chan), format, zone);
2296         if (res == 1)
2297                 return RESULT_SUCCESS;
2298
2299         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2300         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2301 }
2302
2303 static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2304 {
2305         int res;
2306
2307         if (argc != 4)
2308                 return RESULT_SHOWUSAGE;
2309
2310         res = ast_say_phonetic_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
2311         if (res == 1) /* New command */
2312                 return RESULT_SUCCESS;
2313         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2314         return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
2315 }
2316
2317 static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2318 {
2319         int res, max, timeout;
2320         char data[1024];
2321
2322         if (argc < 3)
2323                 return RESULT_SHOWUSAGE;
2324         if (argc >= 4)
2325                 timeout = atoi(argv[3]);
2326         else
2327                 timeout = 0;
2328         if (argc >= 5)
2329                 max = atoi(argv[4]);
2330         else
2331                 max = 1024;
2332         res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
2333         if (res == 2)                   /* New command */
2334                 return RESULT_SUCCESS;
2335         else if (res == 1)
2336                 ast_agi_send(agi->fd, chan, "200 result=%s (timeout)\n", data);
2337         else if (res < 0 )
2338                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2339         else
2340                 ast_agi_send(agi->fd, chan, "200 result=%s\n", data);
2341         return RESULT_SUCCESS;
2342 }
2343
2344 static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2345 {
2346
2347         if (argc != 3)
2348                 return RESULT_SHOWUSAGE;
2349         ast_channel_context_set(chan, argv[2]);
2350         ast_agi_send(agi->fd, chan, "200 result=0\n");
2351         return RESULT_SUCCESS;
2352 }
2353
2354 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2355 {
2356         if (argc != 3)
2357                 return RESULT_SHOWUSAGE;
2358         ast_channel_exten_set(chan, argv[2]);
2359         ast_agi_send(agi->fd, chan, "200 result=0\n");
2360         return RESULT_SUCCESS;
2361 }
2362
2363 static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2364 {
2365         int pri;
2366
2367         if (argc != 3)
2368                 return RESULT_SHOWUSAGE;
2369
2370         if (sscanf(argv[2], "%30d", &pri) != 1) {
2371                 pri = ast_findlabel_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), argv[2],
2372                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));
2373                 if (pri < 1)
2374                         return RESULT_SHOWUSAGE;
2375         }
2376
2377         ast_explicit_goto(chan, NULL, NULL, pri);
2378         ast_agi_send(agi->fd, chan, "200 result=0\n");
2379         return RESULT_SUCCESS;
2380 }
2381
2382 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2383 {
2384         struct ast_filestream *fs;
2385         struct ast_frame *f;
2386         struct timeval start;
2387         long sample_offset = 0;
2388         int res = 0;
2389         int ms;
2390
2391         struct ast_dsp *sildet=NULL;         /* silence detector dsp */
2392         int totalsilence = 0;
2393         int dspsilence = 0;
2394         int silence = 0;                /* amount of silence to allow */
2395         int gotsilence = 0;             /* did we timeout for silence? */
2396         char *silencestr = NULL;
2397         struct ast_format rfmt;
2398         ast_format_clear(&rfmt);
2399
2400         /* XXX EAGI FIXME XXX */
2401
2402         if (argc < 6)
2403                 return RESULT_SHOWUSAGE;
2404         if (sscanf(argv[5], "%30d", &ms) != 1)
2405                 return RESULT_SHOWUSAGE;
2406
2407         if (argc > 6)
2408                 silencestr = strchr(argv[6],'s');
2409         if ((argc > 7) && (!silencestr))
2410                 silencestr = strchr(argv[7],'s');
2411         if ((argc > 8) && (!silencestr))
2412                 silencestr = strchr(argv[8],'s');
2413
2414         if (silencestr) {
2415                 if (strlen(silencestr) > 2) {
2416                         if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
2417                                 silencestr++;
2418                                 silencestr++;
2419                                 if (silencestr)
2420                                         silence = atoi(silencestr);
2421                                 if (silence > 0)
2422                                         silence *= 1000;
2423                         }
2424                 }
2425         }
2426
2427         if (silence > 0) {
2428                 ast_format_copy(&rfmt, ast_channel_readformat(chan));
2429                 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2430                 if (res < 0) {
2431                         ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2432                         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2433                         return RESULT_FAILURE;
2434                 }
2435                 sildet = ast_dsp_new();
2436                 if (!sildet) {
2437                         ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
2438                         ast_agi_send(agi->fd, chan, "200 result=-1\n");
2439                         return RESULT_FAILURE;
2440                 }
2441                 ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
2442         }
2443         
2444         /* backward compatibility, if no offset given, arg[6] would have been
2445          * caught below and taken to be a beep, else if it is a digit then it is a
2446          * offset */
2447         if ((argc >6) && (sscanf(argv[6], "%30ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
2448                 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2449
2450         if ((argc > 7) && (!strchr(argv[7], '=')))
2451                 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
2452
2453         if (!res)
2454                 res = ast_waitstream(chan, argv[4]);
2455         if (res) {
2456                 ast_agi_send(agi->fd, chan, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
2457         } else {
2458                 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE);
2459                 if (!fs) {
2460                         res = -1;
2461                         ast_agi_send(agi->fd, chan, "200 result=%d (writefile)\n", res);
2462                         if (sildet)
2463                                 ast_dsp_free(sildet);
2464                         return RESULT_FAILURE;
2465                 }
2466
2467                 /* Request a video update */
2468                 ast_indicate(chan, AST_CONTROL_VIDUPDATE);
2469
2470                 ast_channel_stream_set(chan, fs);
2471                 ast_applystream(chan,fs);
2472                 /* really should have checks */
2473                 ast_seekstream(fs, sample_offset, SEEK_SET);
2474                 ast_truncstream(fs);
2475
2476                 start = ast_tvnow();
2477                 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
2478                         res = ast_waitfor(chan, ms - ast_tvdiff_ms(ast_tvnow(), start));
2479                         if (res < 0) {
2480                                 ast_closestream(fs);
2481                                 ast_agi_send(agi->fd, chan, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
2482                                 if (sildet)
2483                                         ast_dsp_free(sildet);
2484                                 return RESULT_FAILURE;
2485                         }
2486                         f = ast_read(chan);
2487                         if (!f) {
2488                                 ast_agi_send(agi->fd, chan, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
2489                                 ast_closestream(fs);
2490                                 if (sildet)
2491                                         ast_dsp_free(sildet);
2492                                 return RESULT_FAILURE;
2493                         }
2494                         switch(f->frametype) {
2495                         case AST_FRAME_DTMF:
2496                                 if (strchr(argv[4], f->subclass.integer)) {
2497                                         /* This is an interrupting chracter, so rewind to chop off any small
2498                                            amount of DTMF that may have been recorded
2499                                         */
2500                                         ast_stream_rewind(fs, 200);
2501                                         ast_truncstream(fs);
2502                                         sample_offset = ast_tellstream(fs);
2503                                         ast_agi_send(agi->fd, chan, "200 result=%d (dtmf) endpos=%ld\n", f->subclass.integer, sample_offset);
2504                                         ast_closestream(fs);
2505                                         ast_frfree(f);
2506                                         if (sildet)
2507                                                 ast_dsp_free(sildet);
2508                                         return RESULT_SUCCESS;
2509                                 }
2510                                 break;
2511                         case AST_FRAME_VOICE:
2512                                 ast_writestream(fs, f);
2513                                 /* this is a safe place to check progress since we know that fs
2514                                  * is valid after a write, and it will then have our current
2515                                  * location */
2516                                 sample_offset = ast_tellstream(fs);
2517                                 if (silence > 0) {
2518                                         dspsilence = 0;
2519                                         ast_dsp_silence(sildet, f, &dspsilence);
2520                                         if (dspsilence) {
2521                                                 totalsilence = dspsilence;
2522                                         } else {
2523                                                 totalsilence = 0;
2524                                         }
2525                                         if (totalsilence > silence) {
2526                                                 /* Ended happily with silence */
2527                                                 gotsilence = 1;
2528                                                 break;
2529                                         }
2530                                 }
2531                                 break;
2532                         case AST_FRAME_VIDEO:
2533                                 ast_writestream(fs, f);
2534                         default:
2535                                 /* Ignore all other frames */
2536                                 break;
2537                         }
2538                         ast_frfree(f);
2539                         if (gotsilence)
2540                                 break;
2541                 }
2542
2543                 if (gotsilence) {
2544                         ast_stream_rewind(fs, silence-1000);
2545                         ast_truncstream(fs);
2546                         sample_offset = ast_tellstream(fs);
2547                 }
2548                 ast_agi_send(agi->fd, chan, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
2549                 ast_closestream(fs);
2550         }
2551
2552         if (silence > 0) {
2553                 res = ast_set_read_format(chan, &rfmt);
2554                 if (res)
2555                         ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
2556                 ast_dsp_free(sildet);
2557         }
2558
2559         return RESULT_SUCCESS;
2560 }
2561
2562 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2563 {
2564         double timeout;
2565         struct timeval whentohangup = { 0, 0 };
2566
2567         if (argc != 3)
2568                 return RESULT_SHOWUSAGE;
2569         if (sscanf(argv[2], "%30lf", &timeout) != 1)
2570                 return RESULT_SHOWUSAGE;
2571         if (timeout < 0)
2572                 timeout = 0;
2573         if (timeout) {
2574                 whentohangup.tv_sec = timeout;
2575                 whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
2576         }
2577         ast_channel_setwhentohangup_tv(chan, whentohangup);
2578         ast_agi_send(agi->fd, chan, "200 result=0\n");
2579         return RESULT_SUCCESS;
2580 }
2581
2582 static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2583 {
2584         struct ast_channel *c;
2585
2586         if (argc == 1) {
2587                 /* no argument: hangup the current channel */
2588                 ast_set_hangupsource(chan, "dialplan/agi", 0);
2589                 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
2590                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2591                 return RESULT_SUCCESS;
2592         } else if (argc == 2) {
2593                 /* one argument: look for info on the specified channel */
2594                 if ((c = ast_channel_get_by_name(argv[1]))) {
2595                         /* we have a matching channel */
2596                         ast_set_hangupsource(c, "dialplan/agi", 0);
2597                         ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
2598                         c = ast_channel_unref(c);
2599                         ast_agi_send(agi->fd, chan, "200 result=1\n");
2600                         return RESULT_SUCCESS;
2601                 }
2602                 /* if we get this far no channel name matched the argument given */
2603                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2604                 return RESULT_SUCCESS;
2605         } else {
2606                 return RESULT_SHOWUSAGE;
2607         }
2608 }
2609
2610 static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2611 {
2612         int res, workaround;
2613         struct ast_app *app_to_exec;
2614
2615         if (argc < 2)
2616                 return RESULT_SHOWUSAGE;
2617
2618         ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : "");
2619
2620         if ((app_to_exec = pbx_findapp(argv[1]))) {
2621                 if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) {
2622                         ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
2623                 }
2624                 if (ast_compat_res_agi && argc >= 3 && !ast_strlen_zero(argv[2])) {
2625                         char *compat = ast_alloca(strlen(argv[2]) * 2 + 1), *cptr;
2626                         const char *vptr;
2627                         for (cptr = compat, vptr = argv[2]; *vptr; vptr++) {
2628                                 if (*vptr == ',') {
2629                                         *cptr++ = '\\';
2630                                         *cptr++ = ',';
2631                                 } else if (*vptr == '|') {
2632                                         *cptr++ = ',';
2633                                 } else {
2634                                         *cptr++ = *vptr;
2635                                 }
2636                         }
2637                         *cptr = '\0';
2638                         res = pbx_exec(chan, app_to_exec, compat);
2639                 } else {
2640                         res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]);
2641                 }
2642                 if (!workaround) {
2643                         ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS);
2644                 }
2645         } else {
2646                 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
2647                 res = -2;
2648         }
2649         ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
2650
2651         /* Even though this is wrong, users are depending upon this result. */
2652         return res;
2653 }
2654
2655 static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2656 {
2657         char tmp[256]="";
2658         char *l = NULL, *n = NULL;
2659
2660         if (argv[2]) {
2661                 ast_copy_string(tmp, argv[2], sizeof(tmp));
2662                 ast_callerid_parse(tmp, &n, &l);
2663                 if (l)
2664                         ast_shrink_phone_number(l);
2665                 else
2666                         l = "";
2667                 if (!n)
2668                         n = "";
2669                 ast_set_callerid(chan, l, n, NULL);
2670         }
2671
2672         ast_agi_send(agi->fd, chan, "200 result=1\n");
2673         return RESULT_SUCCESS;
2674 }
2675
2676 static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2677 {
2678         struct ast_channel *c;
2679         if (argc == 2) {
2680                 /* no argument: supply info on the current channel */
2681                 ast_agi_send(agi->fd, chan, "200 result=%d\n", ast_channel_state(chan));
2682                 return RESULT_SUCCESS;
2683         } else if (argc == 3) {
2684                 /* one argument: look for info on the specified channel */
2685                 if ((c = ast_channel_get_by_name(argv[2]))) {
2686                         ast_agi_send(agi->fd, chan, "200 result=%d\n", ast_channel_state(c));
2687                         c = ast_channel_unref(c);
2688                         return RESULT_SUCCESS;
2689                 }
2690                 /* if we get this far no channel name matched the argument given */
2691                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2692                 return RESULT_SUCCESS;
2693         } else {
2694                 return RESULT_SHOWUSAGE;
2695         }
2696 }
2697
2698 static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2699 {
2700         if (argv[3])
2701                 pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
2702
2703         ast_agi_send(agi->fd, chan, "200 result=1\n");
2704         return RESULT_SUCCESS;
2705 }
2706
2707 static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2708 {
2709         char *ret;
2710         char tempstr[1024] = "";
2711
2712         if (argc != 3)
2713                 return RESULT_SHOWUSAGE;
2714
2715         /* check if we want to execute an ast_custom_function */
2716         if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
2717                 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
2718         } else {
2719                 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
2720         }
2721
2722         if (ret)
2723                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ret);
2724         else
2725                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2726
2727         return RESULT_SUCCESS;
2728 }
2729
2730 static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2731 {
2732         struct ast_channel *chan2 = NULL;
2733
2734         if (argc != 4 && argc != 5) {
2735                 return RESULT_SHOWUSAGE;
2736         }
2737
2738         if (argc == 5) {
2739                 chan2 = ast_channel_get_by_name(argv[4]);
2740         } else {
2741                 chan2 = ast_channel_ref(chan);
2742         }
2743
2744         if (chan2) {
2745                 struct ast_str *str = ast_str_create(16);
2746                 if (!str) {
2747                         ast_agi_send(agi->fd, chan, "200 result=0\n");
2748                         return RESULT_SUCCESS;
2749                 }
2750                 ast_str_substitute_variables(&str, 0, chan2, argv[3]);
2751                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str));
2752                 ast_free(str);
2753         } else {
2754                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2755         }
2756
2757         if (chan2) {
2758                 chan2 = ast_channel_unref(chan2);
2759         }
2760
2761         return RESULT_SUCCESS;
2762 }
2763
2764 static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2765 {
2766         int level = 0;
2767
2768         if (argc < 2)
2769                 return RESULT_SHOWUSAGE;
2770
2771         if (argv[2])
2772                 sscanf(argv[2], "%30d", &level);
2773
2774         ast_verb(level, "%s: %s\n", ast_channel_data(chan), argv[1]);
2775
2776         ast_agi_send(agi->fd, chan, "200 result=1\n");
2777
2778         return RESULT_SUCCESS;
2779 }
2780
2781 static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2782 {
2783         int res;
2784         struct ast_str *buf;
2785
2786         if (argc != 4)
2787                 return RESULT_SHOWUSAGE;
2788
2789         if (!(buf = ast_str_create(16))) {
2790                 ast_agi_send(agi->fd, chan, "200 result=-1\n");
2791                 return RESULT_SUCCESS;
2792         }
2793
2794         do {
2795                 res = ast_db_get(argv[2], argv[3], ast_str_buffer(buf), ast_str_size(buf));
2796                 ast_str_update(buf);
2797                 if (ast_str_strlen(buf) < ast_str_size(buf) - 1) {
2798                         break;
2799                 }
2800                 if (ast_str_make_space(&buf, ast_str_size(buf) * 2)) {
2801                         break;
2802                 }
2803         } while (1);
2804         
2805         if (res)
2806                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2807         else
2808                 ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(buf));
2809
2810         ast_free(buf);
2811         return RESULT_SUCCESS;
2812 }
2813
2814 static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2815 {
2816         int res;
2817
2818         if (argc != 5)
2819                 return RESULT_SHOWUSAGE;
2820         res = ast_db_put(argv[2], argv[3], argv[4]);
2821         ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2822         return RESULT_SUCCESS;
2823 }
2824
2825 static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2826 {
2827         int res;
2828
2829         if (argc != 4)
2830                 return RESULT_SHOWUSAGE;
2831         res = ast_db_del(argv[2], argv[3]);
2832         ast_agi_send(agi->fd, chan, "200 result=%c\n", res ? '0' : '1');
2833         return RESULT_SUCCESS;
2834 }
2835
2836 static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2837 {
2838         int num_deleted;
2839
2840         if ((argc < 3) || (argc > 4)) {
2841                 return RESULT_SHOWUSAGE;
2842         }
2843         if (argc == 4) {
2844                 num_deleted = ast_db_deltree(argv[2], argv[3]);
2845         } else {
2846                 num_deleted = ast_db_deltree(argv[2], NULL);
2847         }
2848
2849         ast_agi_send(agi->fd, chan, "200 result=%c\n", num_deleted > 0 ? '0' : '1');
2850         return RESULT_SUCCESS;
2851 }
2852
2853 static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2854 {
2855         switch (cmd) {
2856         case CLI_INIT:
2857                 e->command = "agi set debug [on|off]";
2858                 e->usage =
2859                         "Usage: agi set debug [on|off]\n"
2860                         "       Enables/disables dumping of AGI transactions for\n"
2861                         "       debugging purposes.\n";
2862                 return NULL;
2863
2864         case CLI_GENERATE:
2865                 return NULL;
2866         }
2867
2868         if (a->argc != e->args)
2869                 return CLI_SHOWUSAGE;
2870
2871         if (strncasecmp(a->argv[3], "off", 3) == 0) {
2872                 agidebug = 0;
2873         } else if (strncasecmp(a->argv[3], "on", 2) == 0) {
2874                 agidebug = 1;
2875         } else {
2876                 return CLI_SHOWUSAGE;
2877         }
2878         ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis");
2879         return CLI_SUCCESS;
2880 }
2881
2882 static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, const char * const argv[])
2883 {
2884         ast_agi_send(agi->fd, chan, "200 result=0\n");
2885         return RESULT_SUCCESS;
2886 }
2887
2888 static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2889 {
2890         if (argc < 3) {
2891                 return RESULT_SHOWUSAGE;
2892         }
2893         if (!strncasecmp(argv[2], "on", 2))
2894                 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
2895         else if (!strncasecmp(argv[2], "off", 3))
2896                 ast_moh_stop(chan);
2897         ast_agi_send(agi->fd, chan, "200 result=0\n");
2898         return RESULT_SUCCESS;
2899 }
2900
2901 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2902 {
2903         struct ast_format_cap *cap;
2904         struct ast_format tmpfmt;
2905
2906         /* If a structure already exists, return an error */
2907         if (agi->speech) {
2908                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2909                 return RESULT_SUCCESS;
2910         }
2911
2912         if (!(cap = ast_format_cap_alloc_nolock())) {
2913                 return RESULT_FAILURE;
2914         }
2915         ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
2916         if ((agi->speech = ast_speech_new(argv[2], cap))) {
2917                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2918         } else {
2919                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2920         }
2921         cap = ast_format_cap_destroy(cap);
2922
2923         return RESULT_SUCCESS;
2924 }
2925
2926 static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2927 {
2928         /* Check for minimum arguments */
2929         if (argc != 4)
2930                 return RESULT_SHOWUSAGE;
2931
2932         /* Check to make sure speech structure exists */
2933         if (!agi->speech) {
2934                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2935                 return RESULT_SUCCESS;
2936         }
2937
2938         ast_speech_change(agi->speech, argv[2], argv[3]);
2939         ast_agi_send(agi->fd, chan, "200 result=1\n");
2940
2941         return RESULT_SUCCESS;
2942 }
2943
2944 static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2945 {
2946         if (agi->speech) {
2947                 ast_speech_destroy(agi->speech);
2948                 agi->speech = NULL;
2949                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2950         } else {
2951                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2952         }
2953
2954         return RESULT_SUCCESS;
2955 }
2956
2957 static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2958 {
2959         if (argc != 5)
2960                 return RESULT_SHOWUSAGE;
2961
2962         if (!agi->speech) {
2963                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2964                 return RESULT_SUCCESS;
2965         }
2966
2967         if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
2968                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2969         else
2970                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2971
2972         return RESULT_SUCCESS;
2973 }
2974
2975 static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2976 {
2977         if (argc != 4)
2978                 return RESULT_SHOWUSAGE;
2979
2980         if (!agi->speech) {
2981                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2982                 return RESULT_SUCCESS;
2983         }
2984
2985         if (ast_speech_grammar_unload(agi->speech, argv[3]))
2986                 ast_agi_send(agi->fd, chan, "200 result=0\n");
2987         else
2988                 ast_agi_send(agi->fd, chan, "200 result=1\n");
2989
2990         return RESULT_SUCCESS;
2991 }
2992
2993 static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
2994 {
2995         if (argc != 4)
2996                 return RESULT_SHOWUSAGE;
2997
2998         if (!agi->speech) {
2999                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3000                 return RESULT_SUCCESS;
3001         }
3002
3003         if (ast_speech_grammar_activate(agi->speech, argv[3]))
3004                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3005         else
3006                 ast_agi_send(agi->fd, chan, "200 result=1\n");
3007
3008         return RESULT_SUCCESS;
3009 }
3010
3011 static int handle_speechdeactivategrammar(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
3012 {
3013         if (argc != 4)
3014                 return RESULT_SHOWUSAGE;
3015
3016         if (!agi->speech) {
3017                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3018                 return RESULT_SUCCESS;
3019         }
3020
3021         if (ast_speech_grammar_deactivate(agi->speech, argv[3]))
3022                 ast_agi_send(agi->fd, chan, "200 result=0\n");
3023         else
3024                 ast_agi_send(agi->fd, chan, "200 result=1\n");
3025
3026         return RESULT_SUCCESS;
3027 }
3028
3029 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang, int offset)
3030 {
3031         struct ast_filestream *fs = NULL;
3032
3033         if (!(fs = ast_openstream(chan, filename, preflang)))
3034                 return -1;
3035
3036         if (offset)
3037                 ast_seekstream(fs, offset, SEEK_SET);
3038
3039         if (ast_applystream(chan, fs))
3040                 return -1;
3041
3042         if (ast_playstream(fs))
3043                 return -1;
3044
3045         return 0;
3046 }
3047
3048 static int handle_speechrecognize(struct ast_channel *cha