View Javadoc

1   /*
2    * Copyright  2004-2005 Stefan Reuter
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *
16   */
17  package net.sf.asterisk.fastagi;
18  
19  import net.sf.asterisk.fastagi.command.AGICommand;
20  import net.sf.asterisk.fastagi.command.AnswerCommand;
21  import net.sf.asterisk.fastagi.reply.AGIReply;
22  
23  /***
24   * The BaseAGIScript provides some convinience methods to make it easier to
25   * write custom AGIScripts.<br>
26   * Just extend it by your own AGIScripts.
27   * 
28   * @since 0.2
29   * @author srt
30   * @version $Id: BaseAGIScript.java,v 1.7 2005/11/27 17:31:05 srt Exp $
31   */
32  public abstract class BaseAGIScript implements AGIScript
33  {
34      /***
35       * Answers the channel.
36       */
37      protected void answer() throws AGIException
38      {
39          sendCommand(new AnswerCommand());
40      }
41  
42      /***
43       * Hangs the channel up.
44       */
45      protected void hangup() throws AGIException
46      {
47          getChannel().hangup();
48      }
49  
50      /***
51       * Cause the channel to automatically hangup at the given number of seconds
52       * in the future.
53       * 
54       * @param time the number of seconds before this channel is automatically
55       *            hung up.<br>
56       *            0 disables the autohangup feature.
57       */
58      protected void setAutoHangup(int time) throws AGIException
59      {
60          getChannel().setAutoHangup(time);
61      }
62  
63      /***
64       * Sets the caller id on the current channel.
65       * 
66       * @param callerId the raw caller id to set, for example "John Doe<1234>".
67       */
68      protected void setCallerId(String callerId) throws AGIException
69      {
70          getChannel().setCallerId(callerId);
71      }
72  
73      /***
74       * Plays music on hold from the default music on hold class.
75       */
76      protected void playMusicOnHold() throws AGIException
77      {
78          getChannel().playMusicOnHold();
79      }
80  
81      /***
82       * Plays music on hold from the given music on hold class.
83       * 
84       * @param musicOnHoldClass the music on hold class to play music from as
85       *            configures in Asterisk's <code><musiconhold.conf/code>.
86       */
87      protected void playMusicOnHold(String musicOnHoldClass) throws AGIException
88      {
89          getChannel().playMusicOnHold(musicOnHoldClass);
90      }
91  
92      /***
93       * Stops playing music on hold.
94       */
95      protected void stopMusicOnHold() throws AGIException
96      {
97          getChannel().stopMusicOnHold();
98      }
99  
100     /***
101      * Returns the status of the channel.<br>
102      * Return values:
103      * <ul>
104      * <li>0 Channel is down and available
105      * <li>1 Channel is down, but reserved
106      * <li>2 Channel is off hook
107      * <li>3 Digits (or equivalent) have been dialed
108      * <li>4 Line is ringing
109      * <li>5 Remote end is ringing
110      * <li>6 Line is up
111      * <li>7 Line is busy
112      * </ul>
113      * 
114      * @return the status of the channel.
115      */
116     protected int getChannelStatus() throws AGIException
117     {
118         return getChannel().getChannelStatus();
119     }
120 
121     /***
122      * Plays the given file and waits for the user to enter DTMF digits until he
123      * presses '#'. The user may interrupt the streaming by starting to enter
124      * digits.
125      * 
126      * @param file the name of the file to play
127      * @return a String containing the DTMF the user entered
128      */
129     protected String getData(String file) throws AGIException
130     {
131         return getChannel().getData(file);
132     }
133 
134     /***
135      * Plays the given file and waits for the user to enter DTMF digits until he
136      * presses '#' or the timeout occurs. The user may interrupt the streaming
137      * by starting to enter digits.
138      * 
139      * @param file the name of the file to play
140      * @param timeout the timeout in milliseconds to wait for user input.<br>
141      *            0 means standard timeout value, -1 means "ludicrous time"
142      *            (essentially never times out).
143      * @return a String containing the DTMF the user entered
144      */
145     protected String getData(String file, int timeout) throws AGIException
146     {
147         return getChannel().getData(file, timeout);
148     }
149 
150     /***
151      * Plays the given file and waits for the user to enter DTMF digits until he
152      * presses '#' or the timeout occurs or the maximum number of digits has
153      * been entered. The user may interrupt the streaming by starting to enter
154      * digits.
155      * 
156      * @param file the name of the file to play
157      * @param timeout the timeout in milliseconds to wait for user input.<br>
158      *            0 means standard timeout value, -1 means "ludicrous time"
159      *            (essentially never times out).
160      * @param maxDigits the maximum number of digits the user is allowed to
161      *            enter
162      * @return a String containing the DTMF the user entered
163      */
164     protected String getData(String file, int timeout, int maxDigits)
165             throws AGIException
166     {
167         return getChannel().getData(file, timeout, maxDigits);
168     }
169 
170     /***
171      * Plays the given file, and waits for the user to press one of the given
172      * digits. If none of the esacpe digits is pressed while streaming the file
173      * it waits for the default timeout of 5 seconds still waiting for the user
174      * to press a digit.
175      * 
176      * @param file the name of the file to stream, must not include extension.
177      * @param escapeDigits contains the digits that the user is expected to
178      *            press.
179      * @return the DTMF digit pressed or 0x0 if none was pressed.
180      */
181     protected char getOption(String file, String escapeDigits)
182             throws AGIException
183     {
184         return getChannel().getOption(file, escapeDigits);
185     }
186 
187     /***
188      * Plays the given file, and waits for the user to press one of the given
189      * digits. If none of the esacpe digits is pressed while streaming the file
190      * it waits for the specified timeout still waiting for the user to press a
191      * digit.
192      * 
193      * @param file the name of the file to stream, must not include extension.
194      * @param escapeDigits contains the digits that the user is expected to
195      *            press.
196      * @param timeout the timeout in seconds to wait if none of the defined
197      *            esacpe digits was presses while streaming.
198      * @return the DTMF digit pressed or 0x0 if none was pressed.
199      */
200     protected char getOption(String file, String escapeDigits, int timeout)
201             throws AGIException
202     {
203         return getChannel().getOption(file, escapeDigits, timeout);
204     }
205 
206     /***
207      * Executes the given command.
208      * 
209      * @param application the name of the application to execute, for example
210      *            "Dial".
211      * @return the return code of the application of -2 if the application was
212      *         not found.
213      */
214     protected int exec(String application) throws AGIException
215     {
216         return getChannel().exec(application);
217     }
218 
219     /***
220      * Executes the given command.
221      * 
222      * @param application the name of the application to execute, for example
223      *            "Dial".
224      * @param options the parameters to pass to the application, for example
225      *            "SIP/123".
226      * @return the return code of the application of -2 if the application was
227      *         not found.
228      */
229     protected int exec(String application, String options) throws AGIException
230     {
231         return getChannel().exec(application, options);
232     }
233 
234     /***
235      * Sets the context for continuation upon exiting the application.
236      * 
237      * @param context the context for continuation upon exiting the application.
238      */
239     protected void setContext(String context) throws AGIException
240     {
241         getChannel().setContext(context);
242     }
243 
244     /***
245      * Sets the extension for continuation upon exiting the application.
246      * 
247      * @param extension the extension for continuation upon exiting the
248      *            application.
249      */
250     protected void setExtension(String extension) throws AGIException
251     {
252         getChannel().setExtension(extension);
253     }
254 
255     /***
256      * Sets the priority or label for continuation upon exiting the application.
257      * 
258      * @param priority the priority or label for continuation upon exiting the
259      *            application.
260      */
261     protected void setPriority(String priority) throws AGIException
262     {
263         getChannel().setPriority(priority);
264     }
265 
266     /***
267      * Plays the given file.
268      * 
269      * @param file name of the file to play.
270      */
271     protected void streamFile(String file) throws AGIException
272     {
273         getChannel().streamFile(file);
274     }
275 
276     /***
277      * Plays the given file and allows the user to escape by pressing one of the
278      * given digit.
279      * 
280      * @param file name of the file to play.
281      * @param escapeDigits a String containing the DTMF digits that allow the
282      *            user to escape.
283      * @return the DTMF digit pressed or 0x0 if none was pressed.
284      */
285     protected char streamFile(String file, String escapeDigits)
286             throws AGIException
287     {
288         return getChannel().streamFile(file, escapeDigits);
289     }
290 
291     /***
292      * Says the given digit string.
293      * 
294      * @param digits the digit string to say.
295      */
296     protected void sayDigits(String digits) throws AGIException
297     {
298         getChannel().sayDigits(digits);
299     }
300 
301     /***
302      * Says the given number, returning early if any of the given DTMF number
303      * are received on the channel.
304      * 
305      * @param digits the digit string to say.
306      * @param escapeDigits a String containing the DTMF digits that allow the
307      *            user to escape.
308      * @return the DTMF digit pressed or 0x0 if none was pressed.
309      */
310     protected char sayDigits(String digits, String escapeDigits)
311             throws AGIException
312     {
313         return getChannel().sayDigits(digits, escapeDigits);
314     }
315 
316     /***
317      * Says the given number.
318      * 
319      * @param number the number to say.
320      */
321     protected void sayNumber(String number) throws AGIException
322     {
323         getChannel().sayNumber(number);
324     }
325 
326     /***
327      * Says the given number, returning early if any of the given DTMF number
328      * are received on the channel.
329      * 
330      * @param number the number to say.
331      * @param escapeDigits a String containing the DTMF digits that allow the
332      *            user to escape.
333      * @return the DTMF digit pressed or 0x0 if none was pressed.
334      */
335     protected char sayNumber(String number, String escapeDigits)
336             throws AGIException
337     {
338         return getChannel().sayNumber(number, escapeDigits);
339     }
340 
341     /***
342      * Says the given character string with phonetics.
343      * 
344      * @param text the text to say.
345      */
346     protected void sayPhonetic(String text) throws AGIException
347     {
348         getChannel().sayPhonetic(text);
349     }
350 
351     /***
352      * Says the given character string with phonetics, returning early if any of
353      * the given DTMF number are received on the channel.
354      * 
355      * @param text the text to say.
356      * @param escapeDigits a String containing the DTMF digits that allow the
357      *            user to escape.
358      * @return the DTMF digit pressed or 0x0 if none was pressed.
359      */
360     protected char sayPhonetic(String text, String escapeDigits)
361             throws AGIException
362     {
363         return getChannel().sayPhonetic(text, escapeDigits);
364     }
365 
366     /***
367      * Says the given character string.
368      * 
369      * @param text the text to say.
370      */
371     protected void sayAlpha(String text) throws AGIException
372     {
373         getChannel().sayAlpha(text);
374     }
375 
376     /***
377      * Says the given character string, returning early if any of the given DTMF
378      * number are received on the channel.
379      * 
380      * @param text the text to say.
381      * @param escapeDigits a String containing the DTMF digits that allow the
382      *            user to escape.
383      * @return the DTMF digit pressed or 0x0 if none was pressed.
384      */
385     protected char sayAlpha(String text, String escapeDigits)
386             throws AGIException
387     {
388         return getChannel().sayAlpha(text, escapeDigits);
389     }
390 
391     /***
392      * Says the given time.
393      * 
394      * @param time the time to say in seconds since 00:00:00 on January 1, 1970.
395      */
396     protected void sayTime(long time) throws AGIException
397     {
398         getChannel().sayTime(time);
399     }
400 
401     /***
402      * Says the given time, returning early if any of the given DTMF number are
403      * received on the channel.
404      * 
405      * @param time the time to say in seconds since 00:00:00 on January 1, 1970.
406      * @param escapeDigits a String containing the DTMF digits that allow the
407      *            user to escape.
408      * @return the DTMF digit pressed or 0x0 if none was pressed.
409      */
410     protected char sayTime(long time, String escapeDigits) throws AGIException
411     {
412         return getChannel().sayTime(time, escapeDigits);
413     }
414 
415     /***
416      * Returns the value of the given channel variable.
417      * 
418      * @param name the name of the variable to retrieve.
419      * @return the value of the given variable or <code>null</code> if not
420      *         set.
421      */
422     protected String getVariable(String name) throws AGIException
423     {
424         return getChannel().getVariable(name);
425     }
426 
427     /***
428      * Sets the value of the given channel variable to a new value.
429      * 
430      * @param name the name of the variable to retrieve.
431      * @param value the new value to set.
432      */
433     protected void setVariable(String name, String value) throws AGIException
434     {
435         getChannel().setVariable(name, value);
436     }
437 
438     /***
439      * Waits up to 'timeout' milliseconds to receive a DTMF digit.
440      * 
441      * @param timeout timeout the milliseconds to wait for the channel to
442      *            receive a DTMF digit, -1 will wait forever.
443      * @return the DTMF digit pressed or 0x0 if none was pressed.
444      */
445     protected char waitForDigit(int timeout) throws AGIException
446     {
447         return getChannel().waitForDigit(timeout);
448     }
449 
450     /***
451      * Returns the value of the current channel variable, unlike getVariable()
452      * this method understands complex variable names and builtin variables.<br>
453      * Available since Asterisk 1.2.
454      * 
455      * @param name the name of the variable to retrieve.
456      * @return the value of the given variable or <code>null</code> if not
457      *         set.
458      * @since 0.2
459      */
460     protected String getFullVariable(String name) throws AGIException
461     {
462         return getChannel().getFullVariable(name);
463     }
464 
465     /***
466      * Returns the value of the given channel variable.<br>
467      * Available since Asterisk 1.2.
468      * 
469      * @param name the name of the variable to retrieve.
470      * @param channel the name of the channel.
471      * @return the value of the given variable or <code>null</code> if not
472      *         set.
473      * @since 0.2
474      */
475     protected String getFullVariable(String name, String channel)
476             throws AGIException
477     {
478         return getChannel().getFullVariable(name, channel);
479     }
480 
481     /***
482      * Says the given time.<br>
483      * Available since Asterisk 1.2.
484      * 
485      * @param time the time to say in seconds elapsed since 00:00:00 on January
486      *            1, 1970, Coordinated Universal Time (UTC)
487      * @since 0.2
488      */
489     protected void sayDateTime(long time) throws AGIException
490     {
491         getChannel().sayDateTime(time);
492     }
493 
494     /***
495      * Says the given time and allows interruption by one of the given escape
496      * digits.<br>
497      * Available since Asterisk 1.2.
498      * 
499      * @param time the time to say in seconds elapsed since 00:00:00 on January
500      *            1, 1970, Coordinated Universal Time (UTC)
501      * @param escapeDigits the digits that allow the user to interrupt this
502      *            command or <code>null</code> for none.
503      * @return the DTMF digit pressed or 0x0 if none was pressed.
504      * @since 0.2
505      */
506     protected char sayDateTime(long time, String escapeDigits)
507             throws AGIException
508     {
509         return getChannel().sayDateTime(time, escapeDigits);
510     }
511 
512     /***
513      * Says the given time in the given format and allows interruption by one of
514      * the given escape digits.<br>
515      * Available since Asterisk 1.2.
516      * 
517      * @param time the time to say in seconds elapsed since 00:00:00 on January
518      *            1, 1970, Coordinated Universal Time (UTC)
519      * @param escapeDigits the digits that allow the user to interrupt this
520      *            command or <code>null</code> for none.
521      * @param format the format the time should be said in
522      * @return the DTMF digit pressed or 0x0 if none was pressed.
523      * @since 0.2
524      */
525     protected char sayDateTime(long time, String escapeDigits, String format)
526             throws AGIException
527     {
528         return getChannel().sayDateTime(time, escapeDigits, format);
529     }
530 
531     /***
532      * Says the given time in the given format and timezone and allows
533      * interruption by one of the given escape digits.<br>
534      * Available since Asterisk 1.2.
535      * 
536      * @param time the time to say in seconds elapsed since 00:00:00 on January
537      *            1, 1970, Coordinated Universal Time (UTC)
538      * @param escapeDigits the digits that allow the user to interrupt this
539      *            command or <code>null</code> for none.
540      * @param format the format the time should be said in
541      * @param timezone the timezone to use when saying the time, for example
542      *            "UTC" or "Europe/Berlin".
543      * @return the DTMF digit pressed or 0x0 if none was pressed.
544      * @since 0.2
545      */
546     protected char sayDateTime(long time, String escapeDigits, String format,
547             String timezone) throws AGIException
548     {
549         return getChannel().sayDateTime(time, escapeDigits, format, timezone);
550     }
551 
552     /***
553      * Sends the given command to the channel attached to the current thread.
554      * 
555      * @param command the command to send to Asterisk
556      * @return the reply received from Asterisk
557      * @throws AGIException if the command could not be processed properly
558      */
559     private AGIReply sendCommand(AGICommand command) throws AGIException
560     {
561         return getChannel().sendCommand(command);
562     }
563 
564     private AGIChannel getChannel()
565     {
566         AGIChannel channel;
567 
568         channel = AGIConnectionHandler.getChannel();
569         if (channel == null)
570         {
571             throw new RuntimeException(
572                     "Trying to send command from an invalid thread");
573         }
574 
575         return channel;
576     }
577 }