/// <summary> /// Returns the status of the channel.<br/> /// Return values: /// <ul> /// <li>0 Channel is down and available</li> /// <li>1 Channel is down, but reserved</li> /// <li>2 Channel is off hook</li> /// <li>3 Digits (or equivalent) have been dialed</li> /// <li>4 Line is ringing</li> /// <li>5 Remote end is ringing</li> /// <li>6 Line is up</li> /// <li>7 Line is busy</li> /// </ul> /// </summary> /// <returns> the status of the channel. /// </returns> protected internal int GetChannelStatus() { AGIChannel channel = this.Channel; channel.SendCommand(new Command.ChannelStatusCommand()); return(channel.LastReply.ResultCode); }
/// <summary> /// Record to a file until a given dtmf digit in the sequence is received.<br/> /// Returns -1 on hangup or error.<br/> /// The format will specify what kind of file will be recorded. The timeout is /// the maximum record time in milliseconds, or -1 for no timeout. Offset samples /// is optional, and if provided will seek to the offset without exceeding the /// end of the file. "maxSilence" is the number of seconds of maxSilence allowed /// before the function returns despite the lack of dtmf digits or reaching /// timeout. /// </summary> /// <param name="file">the name of the file to stream, must not include extension.</param> /// <param name="format">the format of the file to be recorded, for example "wav".</param> /// <param name="escapeDigits">contains the digits that allow the user to end recording.</param> /// <param name="timeout">the maximum record time in milliseconds, or -1 for no timeout.</param> /// <param name="offset">the offset samples to skip.</param> /// <param name="beep">true if a beep should be played before recording.</param> /// <param name="maxSilence">The amount of silence (in seconds) to allow before returning despite the lack of dtmf digits or reaching timeout.</param> /// <returns>result code</returns> protected internal int RecordFile(string file, string format, string escapeDigits, int timeout, int offset, bool beep, int maxSilence) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.RecordFileCommand(file, format, escapeDigits, timeout, offset, beep, maxSilence)); return(channel.LastReply.ResultCode); }
/// <summary> /// Says the given number, returning early if any of the given DTMF number /// are received on the channel. /// </summary> /// <param name="digits">the digit string to say.</param> /// <param name="escapeDigits">a String containing the DTMF digits that allow the user to escape.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char SayDigits(string digits, string escapeDigits) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.SayDigitsCommand(digits, escapeDigits)); return(lastReply.ResultCodeAsChar); }
/// <summary> /// Plays the given file and allows the user to escape by pressing one of the given digit. /// </summary> /// <param name="file">name of the file to play.</param> /// <param name="escapeDigits">a String containing the DTMF digits that allow the user to escape.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char StreamFile(string file, string escapeDigits) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.StreamFileCommand(file, escapeDigits)); return(lastReply.ResultCodeAsChar); }
/// <summary> /// Says the given character string with phonetics, returning early if any of /// the given DTMF number are received on the channel. /// </summary> /// <param name="text">the text to say.</param> /// <param name="escapeDigits">a String containing the DTMF digits that allow the user to escape.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char SayPhonetic(string text, string escapeDigits) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.SayPhoneticCommand(text, escapeDigits)); return(lastReply.ResultCodeAsChar); }
/// <summary> /// Executes the given command. /// </summary> /// <param name="application">the name of the application to execute, for example "Dial".</param> /// <returns> the return code of the application of -2 if the application was not found.</returns> protected internal int Exec(string application) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.ExecCommand(application)); return(lastReply.ResultCode); }
/// <summary> /// Plays the given file, allowing playback to be interrupted by the given /// digits, if any, and allows the listner to control the stream.<br/> /// If offset is provided then the audio will seek to sample offset before play /// starts.<br/> /// Returns 0 if playback completes without a digit being pressed, or the ASCII /// numerical value of the digit if one was pressed, or -1 on error or if the /// channel was disconnected. <br/> /// Remember, the file extension must not be included in the filename.<br/> /// Available since Asterisk 1.2 /// </summary> /// <seealso cref="Command.ControlStreamFileCommand"/> /// <param name="file">the name of the file to stream, must not include extension.</param> /// <param name="escapeDigits">contains the digits that allow the user to interrupt this command.</param> /// <returns>result code</returns> protected internal int ControlStreamFile(string file, string escapeDigits) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.ControlStreamFileCommand(file, escapeDigits)); return(channel.LastReply.ResultCode); }
/// <summary> /// Plays the given file and waits for the user to enter DTMF digits until he /// presses '#'. The user may interrupt the streaming by starting to enter /// digits. /// </summary> /// <param name="file">the name of the file to play</param> /// <returns> a String containing the DTMF the user entered</returns> protected internal string GetData(string file) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.GetDataCommand(file)); return(channel.LastReply.GetResult()); }
/// <summary> /// Says the given character string, returning early if any of the given DTMF /// number are received on the channel. /// </summary> /// <param name="text">the text to say.</param> /// <param name="escapeDigits">a String containing the DTMF digits that allow the user to escape.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char SayAlpha(string text, string escapeDigits) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.SayAlphaCommand(text, escapeDigits)); return(channel.LastReply.ResultCodeAsChar); }
/// <summary> /// Says the given time in the given format and timezone and allows interruption by one of the given escape digits.<br/> /// Available since Asterisk 1.2. /// </summary> /// <param name="time">the time to say in seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC)</param> /// <param name="escapeDigits">the digits that allow the user to interrupt this command or null for none.</param> /// <param name="format">the format the time should be said in</param> /// <param name="timezone">the timezone to use when saying the time, for example "UTC" or "Europe/Berlin".</param> /// <returns>the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char SayDateTime(long time, string escapeDigits, string format, string timezone) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.SayDateTimeCommand(time, escapeDigits, format, timezone)); return(channel.LastReply.ResultCodeAsChar); }
/// <summary> /// Waits up to 'timeout' milliseconds to receive a DTMF digit. /// </summary> /// <param name="timeout">timeout the milliseconds to wait for the channel to receive a DTMF digit, -1 will wait forever.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char WaitForDigit(int timeout) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.WaitForDigitCommand(timeout)); return(channel.LastReply.ResultCodeAsChar); }
/// <summary> /// Executes the given command. /// </summary> /// <param name="application">the name of the application to execute, for example "Dial".</param> /// <param name="options">the parameters to pass to the application, for example "SIP/123".</param> /// <returns> the return code of the application of -2 if the application was not found.</returns> protected internal int Exec(string application, string options) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.ExecCommand(application, options)); return(channel.LastReply.ResultCode); }
/// <summary> /// Says the given number, returning early if any of the given DTMF number /// are received on the channel. /// </summary> /// <param name="number">the number to say.</param> /// <param name="escapeDigits">a String containing the DTMF digits that allow the user to escape.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char SayNumber(string number, string escapeDigits) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.SayNumberCommand(number, escapeDigits)); return(channel.LastReply.ResultCodeAsChar); }
/// <summary> /// Plays the given file and waits for the user to enter DTMF digits until he /// presses '#' or the timeout occurs or the maximum number of digits has /// been entered. The user may interrupt the streaming by starting to enter /// digits. /// </summary> /// <param name="file">the name of the file to play</param> /// <param name="timeout">the timeout in milliseconds to wait for user input.<br/> /// 0 means standard timeout value, -1 means "ludicrous time" /// (essentially never times out).</param> /// <param name="maxDigits">the maximum number of digits the user is allowed to enter</param> /// <returns> a String containing the DTMF the user entered</returns> protected internal string GetData(string file, long timeout, int maxDigits) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.GetDataCommand(file, timeout, maxDigits)); return(channel.LastReply.GetResult()); }
/// <summary> /// Plays the given file, and waits for the user to press one of the given /// digits. If none of the esacpe digits is pressed while streaming the file /// it waits for the specified timeout still waiting for the user to press a /// digit. /// </summary> /// <param name="file">the name of the file to stream, must not include extension.</param> /// <param name="escapeDigits">contains the digits that the user is expected to press.</param> /// <param name="timeout">the timeout in seconds to wait if none of the defined esacpe digits was presses while streaming.</param> /// <returns> the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char GetOption(string file, string escapeDigits, int timeout) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.GetOptionCommand(file, escapeDigits, timeout)); return(channel.LastReply.ResultCodeAsChar); }
/// <summary> /// Record to a file until a given dtmf digit in the sequence is received.<br/> /// Returns -1 on hangup or error.<br/> /// The format will specify what kind of file will be recorded. The timeout is /// the maximum record time in milliseconds, or -1 for no timeout. Offset samples /// is optional, and if provided will seek to the offset without exceeding the /// end of the file. "maxSilence" is the number of seconds of maxSilence allowed /// before the function returns despite the lack of dtmf digits or reaching /// timeout. /// </summary> /// <param name="file">the name of the file to stream, must not include extension.</param> /// <param name="format">the format of the file to be recorded, for example "wav".</param> /// <param name="escapeDigits">contains the digits that allow the user to end recording.</param> /// <param name="timeout">the maximum record time in milliseconds, or -1 for no timeout.</param> /// <returns>result code</returns> protected internal int RecordFile(string file, string format, string escapeDigits, int timeout) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.RecordFileCommand(file, format, escapeDigits, timeout)); return(channel.LastReply.ResultCode); }
/// <summary> /// Plays the given file and waits for the user to enter DTMF digits until he /// presses '#' or the timeout occurs. The user may interrupt the streaming /// by starting to enter digits. /// </summary> /// <param name="file">the name of the file to play</param> /// <param name="timeout">the timeout in milliseconds to wait for user input.<br/> /// 0 means standard timeout value, -1 means "ludicrous time" /// (essentially never times out).</param> /// <returns> a String containing the DTMF the user entered</returns> protected internal string GetData(string file, long timeout) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.GetDataCommand(file, timeout)); return(lastReply.GetResult()); }
/// <summary> /// Plays the given file, allowing playback to be interrupted by the given /// digits, if any, and allows the listner to control the stream.<br/> /// If offset is provided then the audio will seek to sample offset before play /// starts.<br/> /// Returns 0 if playback completes without a digit being pressed, or the ASCII /// numerical value of the digit if one was pressed, or -1 on error or if the /// channel was disconnected. <br/> /// Remember, the file extension must not be included in the filename.<br/> /// Available since Asterisk 1.2 /// </summary> /// <seealso cref="Command.ControlStreamFileCommand"/> /// <param name="file">the name of the file to stream, must not include extension.</param> /// <param name="escapeDigits">contains the digits that allow the user to interrupt this command.</param> /// <param name="offset">the offset samples to skip before streaming.</param> /// <param name="forwardDigit">the digit for fast forward.</param> /// <param name="rewindDigit">the digit for rewind.</param> /// <param name="pauseDigit">the digit for pause and unpause.</param> /// <returns>result code</returns> protected internal int ControlStreamFile(string file, string escapeDigits, int offset, string forwardDigit, string rewindDigit, string pauseDigit) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.ControlStreamFileCommand(file, escapeDigits, offset, forwardDigit, rewindDigit, pauseDigit)); return(lastReply.ResultCode); }
/// <summary> /// Plays the given file, allowing playback to be interrupted by the given /// digits, if any, and allows the listner to control the stream.<br/> /// If offset is provided then the audio will seek to sample offset before play /// starts.<br/> /// Returns 0 if playback completes without a digit being pressed, or the ASCII /// numerical value of the digit if one was pressed, or -1 on error or if the /// channel was disconnected. <br/> /// Remember, the file extension must not be included in the filename.<br/> /// Available since Asterisk 1.2 /// </summary> /// <seealso cref="Command.ControlStreamFileCommand"/> /// <param name="file">the name of the file to stream, must not include extension.</param> /// <returns>result code</returns> protected internal int ControlStreamFile(string file) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.ControlStreamFileCommand(file)); return(lastReply.ResultCode); }
/// <summary> /// Says the given time and allows interruption by one of the given escape digits.<br/> /// Available since Asterisk 1.2. /// </summary> /// <param name="time">the time to say in seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC)</param> /// <param name="escapeDigits">the digits that allow the user to interrupt this command or null for none.</param> /// <returns>the DTMF digit pressed or 0x0 if none was pressed.</returns> protected internal char SayDateTime(long time, string escapeDigits) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.SayDateTimeCommand(time, escapeDigits)); return(lastReply.ResultCodeAsChar); }
/// <summary> /// Retrieves an entry in the Asterisk database for a given family and key. /// </summary> /// <param name="family">the family of the entry to retrieve.</param> /// <param name="key">key the key of the entry to retrieve.</param> /// <return>the value of the given family and key or null if there is no such value.</return> protected internal string DatabaseGet(string family, string key) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.DatabaseGetCommand(family, key)); if (channel.LastReply.ResultCode != 1) { return(null); } return(channel.LastReply.Extra); }
/// <summary> /// Returns the value of the given channel variable.<br/> /// Available since Asterisk 1.2. /// </summary> /// <param name="name">the name of the variable to retrieve.</param> /// <param name="channel">the name of the channel.</param> /// <returns>the value of the given variable or null if not set.</returns> protected internal string GetFullVariable(string name, string channelName) { AGIChannel channel = this.Channel; channel.SendCommand(new Command.GetFullVariableCommand(name, channelName)); if (channel.LastReply.ResultCode != 1) { return(null); } return(channel.LastReply.Extra); }
/// <summary> /// Returns the value of the given channel variable. /// </summary> /// <param name="name">the name of the variable to retrieve.</param> /// <returns> the value of the given variable or null if not set.</returns> protected internal string GetVariable(string name) { AGIChannel channel = this.Channel; AGIReply lastReply = channel.SendCommand(new Command.GetVariableCommand(name)); if (lastReply.ResultCode != 1) { return(null); } return(lastReply.Extra); }
public void Run() { try { var reader = new AGIReader(socket); var writer = new AGIWriter(socket); AGIRequest request; using (var enlarger = new SocketConnectionTimeoutEnlarger(socket, 500)) request = reader.ReadRequest(); //Added check for when the request is empty //eg. telnet to the service if (request.Request.Count > 0) { var channel = new AGIChannel(writer, reader, _SC511_CAUSES_EXCEPTION, _SCHANGUP_CAUSES_EXCEPTION); AGIScript script = mappingStrategy.DetermineScript(request); Thread.SetData(_channel, channel); if (script != null) { #if LOGGER logger.Info("Begin AGIScript " + script.GetType().FullName + " on " + Thread.CurrentThread.Name); #endif script.Service(request, channel); #if LOGGER logger.Info("End AGIScript " + script.GetType().FullName + " on " + Thread.CurrentThread.Name); #endif } else { var error = "No script configured for URL '" + request.RequestURL + "' (script '" + request.Script + "')"; channel.SendCommand(new VerboseCommand(error, 1)); #if LOGGER logger.Error(error); #endif } } else { var error = "A connection was made with no requests"; #if LOGGER logger.Error(error); #endif } } catch (AGIHangupException) { } catch (IOException) { } catch (AGIException ex) { #if LOGGER logger.Error("AGIException while handling request", ex); #else throw ex; #endif } catch (Exception ex) { #if LOGGER logger.Error("Unexpected Exception while handling request", ex); #else throw ex; #endif } Thread.SetData(_channel, null); try { socket.Close(); } #if LOGGER catch (IOException ex) { logger.Error("Error on close socket", ex); } #else catch { } #endif }
public void Run() { try { var reader = new AGIReader(socket); var writer = new AGIWriter(socket); AGIRequest request = reader.ReadRequest(); var channel = new AGIChannel(writer, reader, _SC511_CAUSES_EXCEPTION, _SCHANGUP_CAUSES_EXCEPTION); AGIScript script = mappingStrategy.DetermineScript(request); Thread.SetData(_channel, channel); if (script != null) { #if LOGGER logger.Info("Begin AGIScript " + script.GetType().FullName + " on " + Thread.CurrentThread.Name); #endif script.Service(request, channel); #if LOGGER logger.Info("End AGIScript " + script.GetType().FullName + " on " + Thread.CurrentThread.Name); #endif } else { var error = "No script configured for URL '" + request.RequestURL + "' (script '" + request.Script + "')"; channel.SendCommand(new VerboseCommand(error, 1)); #if LOGGER logger.Error(error); #endif } } catch (AGIHangupException) { } catch (IOException) { } catch (AGIException ex) { #if LOGGER logger.Error("AGIException while handling request", ex); #else throw ex; #endif } catch (Exception ex) { #if LOGGER logger.Error("Unexpected Exception while handling request", ex); #else throw ex; #endif } Thread.SetData(_channel, null); try { socket.Close(); } #if LOGGER catch (IOException ex) { logger.Error("Error on close socket", ex); } #else catch { } #endif }
/* * Call -> play "wellcome" -> wait digit 5 seconds -> press 1 -> play "press-1" -> wait digit -> press * ----------------------------\ * ^ ^ ^ -> press 4 -> play "press-4" -------\ | * | | | -> press any -> play "bad" "digit" -+ | * | | \-----------------------------------------/ | * | | -> press # or timeout -\ | * | | | | * | | -> press # or timeout -> play "goodbye" -> Hangup | | * | | ^ | | * | | \-----------------------------------+ | * | | | | * | | | | * | | -> press 2 -> play "press-1" -> wait digit -> press # or timeout -/ | * | | ^ -> press * ----------------------------+ * | | | -> press 4 -> play "press-4" -------\ | * | | | -> press any -> play "bad" "digit" -+ | * | | \-----------------------------------------/ | * | | | * | | -> press other -> play "bad" "digit" -\ | * | \--------------------------------------------------/ | * \-------------------------------------------------------------------------------------------------------------------/ */ public override void Service(AGIRequest request, AGIChannel channel) { Answer(); int submenu = 0; char key = '\0'; bool welcome = true; while (true) { if (welcome) { key = StreamFile("welcome", escapeKeys); welcome = false; submenu = 0; } if (key == '\0') { key = WaitForDigit(5000); if (key == '\0' || key == '#') { StreamFile("goodbye"); break; } } char newKey = '\0'; switch (submenu) { case 0: switch (key) { case '1': newKey = StreamFile("press-1", escapeKeys); submenu = 1; break; case '2': newKey = StreamFile("press-2", escapeKeys); submenu = 2; break; case '3': newKey = StreamFile("press-3", escapeKeys); break; default: newKey = StreamFile("bad", escapeKeys); if(newKey == '\0') newKey = StreamFile("digit", escapeKeys); break; } break; case 1: switch (key) { case '*': welcome = true; break; case '4': newKey = StreamFile("press-4", escapeKeys); break; default: newKey = StreamFile("bad", escapeKeys); if (newKey == '\0') newKey = StreamFile("digit", escapeKeys); break; } break; case 2: switch (key) { case '*': welcome = true; break; case '5': newKey = StreamFile("press-5", escapeKeys); break; default: newKey = StreamFile("bad", escapeKeys); if (newKey == '\0') newKey = StreamFile("digit", escapeKeys); break; } break; } key = newKey; } Hangup(); }
public abstract void Service(AGIRequest param1, AGIChannel param2);