00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00031 #ifndef ASTXX_AGI_H
00032 #define ASTXX_AGI_H
00033
00034 #include <map>
00035 #include <string>
00036 #include <astxx/exception.h>
00037
00038 namespace astxx {
00039
00070 class agi {
00071 public:
00072
00077 class error : public astxx::exception {
00078 public:
00079 error() throw() : astxx::exception("astxx AGI Exception") { }
00081 explicit error(const std::string& desc) throw() : astxx::exception(desc) { }
00082 };
00083
00086 class unknown_error : public error {
00087 public:
00089 explicit unknown_error(int error_code, const std::string& desc) throw() : error(desc), code(error_code) { }
00090
00094 int error_code() const { return code; }
00095
00096 private:
00097 int code;
00098
00099 };
00100
00103 class usage_error : public error {
00104 public:
00106 explicit usage_error(const std::string& desc) throw() : error(desc) { }
00107 };
00108
00111 class invalid_command : public error {
00112 public:
00113 invalid_command() throw() : error("Invalid or unknown command. This could be a bug in astxx, or your Asterisk installation may be too old.") { }
00115 explicit invalid_command(const std::string& desc) throw() : error(desc) { }
00116
00117 };
00118
00121 class io_error : public error {
00122 public:
00123 io_error() throw() : error("There was a error communicating with the Asterisk server") { }
00125 explicit io_error(const std::string& desc) throw() : error(desc) { }
00126
00127 };
00128
00131 class application_error : public error {
00132 public:
00133 application_error() throw() : error("Error during application execution, possibly a hangup") { }
00135 explicit application_error(const std::string& desc) throw() : error(desc) { }
00136
00137 };
00138
00144 class hangup : public application_error {
00145 public:
00146 hangup() throw() : application_error("Channel hungup during execution") { }
00148 explicit hangup(const std::string& desc) throw() : application_error(desc) { }
00149
00150 };
00151
00157 class hangup_signal : public hangup {
00158 public:
00159 hangup_signal() throw() : hangup("Received SIGHUP from Asterisk, indicating a hangup") { }
00160 };
00161
00167 class hangup_result : public hangup {
00168 public:
00169 hangup_result() throw() : hangup("Received \"hangup\" as the result of an AGI command") { }
00170 };
00171
00173 class timeout : public application_error {
00174 public:
00175 timeout() throw() : application_error("Operation timed out") { }
00177 explicit timeout(const std::string& desc) throw() : application_error(desc) { }
00178
00179 };
00180
00182 class database_error : public application_error {
00183 public:
00184 database_error() : application_error("An Asterisk database operation failed") { }
00186 explicit database_error(const std::string& desc) : application_error(desc) { }
00187
00188 };
00189
00191 class no_channel : public application_error {
00192 public:
00193 no_channel() throw() : application_error("The requested channel could not be found") { }
00195 explicit no_channel(const std::string& channel) throw() : application_error("Channel '" + channel + "' was not found"), channel(channel) { }
00196 virtual ~no_channel() throw () { }
00197
00198 private:
00199 std::string channel;
00200
00201 };
00202
00209 struct result {
00211 int code;
00213 std::string message;
00215 int result;
00217 std::string result_string;
00219 std::string data;
00221 long endpos;
00222 };
00223
00224
00225 public:
00226 std::map<std::string, std::string> env;
00227 result execute(const std::string& command) const;
00228 std::string quote(const std::string item) const { return ("\"" + item + "\""); }
00229 std::string quote(char item) const { return ("\"" + (item ? std::string(1, item) : "") + "\""); }
00230
00231 protected:
00232 agi();
00233 agi(const agi&);
00234 agi& operator = (const agi&);
00235 void read_env();
00236 void send_command(const std::string& command) const;
00237 result get_result() const;
00238
00239 private:
00240 static volatile bool got_sighup;
00241 static void handle_sighup(int);
00242 static volatile bool got_sigpipe;
00243 static void handle_sigpipe(int);
00244
00245 static const int control_stream_file_skip_time = 3000;
00246 static const int get_data_max_digits = 1024;
00247
00248 public:
00249 static agi& instance();
00250 std::string operator [] (const std::string& key);
00251 std::map<std::string, std::string>::const_iterator begin() const;
00252 std::map<std::string, std::string>::const_iterator end() const;
00253
00254 void test_hangup() const;
00255 void clear();
00256
00257
00258 agi& answer();
00259 int channel_status(const std::string& channel = "") const;
00260 char control_stream_file(const std::string& filename, const std::string& escape_digits = "", int skip_time = control_stream_file_skip_time, char fastforward = 0, char rewind = 0, char pause = 0) const;
00261 agi& database_del(const std::string& family, const std::string& key);
00262 agi& database_deltree(const std::string& family, const std::string& keytree = "");
00263 std::string database_get(const std::string& family, const std::string& key) const;
00264 agi& database_put(const std::string& family, const std::string& key, const std::string& value);
00265 int exec(const std::string& app, const std::string& options = "") const;
00266 std::string get_data(const std::string& file, int timeout = 0, int max_digits = get_data_max_digits) const;
00267 std::string get_full_variable(const std::string& variable, const std::string& channel = "") const;
00268 char get_option(const std::string& file, const std::string& escape_digits = "", int timeout = 0) const;
00269 std::string get_variable(const std::string& variable) const;
00270 agi& hangup(const std::string& channel = "");
00271 agi& noop();
00272 char receive_char(int timeout = 0) const;
00273 std::string receive_text(int timeout = 0) const;
00274 char record_file(const std::string& filename, const std::string& format, const std::string& escape_digits = "", int timeout = -1, int silence = 0, bool beep = true, long offset = 0) const;
00275 char say_alpha(const std::string& alphanum, const std::string& escape_digits = "") const;
00276 char say_alpha(int number, const std::string& escape_digits = "") const;
00277 char say_date(time_t date, const std::string& escape_digits = "") const;
00278 char say_datetime(time_t date, const std::string& escape_digits = "", const std::string& format = "", const std::string& timezone = "") const;
00279 char say_digits(int digits, const std::string& escape_digits = "") const;
00280 char say_number(int number, const std::string& escape_digits = "") const;
00281 char say_phonetic(const std::string& characters, const std::string& escape_digits = "") const;
00282 char say_time(time_t time, const std::string& escape_digits = "") const;
00283 agi& send_image(const std::string& image);
00284 agi& send_text(const std::string& text);
00285 agi& set_autohangup(int delay);
00286 agi& set_callerid(int number);
00287 agi& set_callerid(const std::string& cid);
00288 agi& set_context(const std::string& context);
00289 agi& set_extension(int extension);
00290 agi& set_extension(const std::string& extension);
00291 agi& set_music(bool enable, const std::string& music_class = "");
00292 agi& set_priority(int priority);
00293 agi& set_priority(const std::string& priority);
00294 agi& set_variable(const std::string& variable, const std::string& value);
00295 char stream_file(const std::string& filename, const std::string& escape_digits = "", long offset = 0) const;
00296 agi& tdd_mode(bool enable);
00297 agi& tdd_mode(const std::string& mode);
00298 agi& verbose(const std::string& text, int level = 1);
00299 char wait_for_digit(long timeout = -1) const;
00300 };
00301
00302 }
00303
00304 #endif