2003-02-19 08:19:51 +00:00
|
|
|
/* @file capisuite.cpp
|
|
|
|
@brief Contains CapiSuite - Main application class, implements ApplicationInterface
|
|
|
|
|
|
|
|
@author Gernot Hillier <gernot@hillier.de>
|
2004-02-20 14:33:08 +00:00
|
|
|
$Revision: 1.8 $
|
2003-02-19 08:19:51 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2004-02-20 14:33:08 +00:00
|
|
|
#include <Python.h>
|
|
|
|
#include <cStringIO.h>
|
|
|
|
|
2003-02-19 08:19:51 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../../config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <getopt.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "../backend/capi.h"
|
|
|
|
#include "../backend/connection.h"
|
|
|
|
#include "incomingscript.h"
|
|
|
|
#include "idlescript.h"
|
|
|
|
#include "capisuite.h"
|
|
|
|
|
|
|
|
/** @brief Global Pointer to current CapiSuite instance
|
|
|
|
*/
|
|
|
|
CapiSuite* capisuiteInstance=NULL;
|
|
|
|
|
|
|
|
void exit_handler(int)
|
|
|
|
{
|
|
|
|
if (capisuiteInstance)
|
|
|
|
capisuiteInstance->finish();
|
|
|
|
}
|
|
|
|
|
|
|
|
void hup_handler(int)
|
|
|
|
{
|
|
|
|
if (capisuiteInstance)
|
|
|
|
capisuiteInstance->reload();
|
|
|
|
signal(SIGHUP,hup_handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
CapiSuite::CapiSuite(int argc,char **argv)
|
2003-02-25 13:22:42 +00:00
|
|
|
:capi(NULL),waiting(),config(),idle(NULL),py_state(NULL),debug(NULL),error(NULL),finish_flag(false),custom_configfile(),daemonmode(false)
|
2003-02-19 08:19:51 +00:00
|
|
|
{
|
|
|
|
if (capisuiteInstance!=NULL) {
|
2003-03-06 09:34:44 +00:00
|
|
|
cerr << "FATAL error: More than one instances of CapiSuite created" << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
capisuiteInstance=this;
|
|
|
|
|
|
|
|
readCommandline(argc,argv);
|
|
|
|
readConfiguration();
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (daemonmode)
|
|
|
|
// set daemon mode
|
|
|
|
if (daemon(0,0)!=0) {
|
|
|
|
(*error) << prefix() << "FATAL error: Can't fork off daemon" << endl;
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_level=atoi(config["log_level"].c_str());
|
|
|
|
|
|
|
|
(*debug) << prefix() << "CapiSuite " << VERSION << " started." << endl;
|
2003-04-03 21:09:46 +00:00
|
|
|
(*error) << prefix() << "CapiSuite " << VERSION << " started." << endl;
|
|
|
|
|
2004-01-10 14:16:40 +00:00
|
|
|
string DDIStopListS=config["DDI_stop_numbers"];
|
|
|
|
vector<string> DDIStopList;
|
|
|
|
DDIStopList.push_back("");
|
|
|
|
|
|
|
|
int j=0;
|
|
|
|
for (int i=0;i<DDIStopListS.length();i++) {
|
|
|
|
if (DDIStopListS[i]==',') {
|
|
|
|
DDIStopList.push_back("");
|
|
|
|
j++;
|
|
|
|
} else {
|
|
|
|
DDIStopList[j]+=DDIStopListS[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-03 21:09:46 +00:00
|
|
|
// backend init
|
2004-01-10 14:16:40 +00:00
|
|
|
capi=new Capi(*debug,debug_level,*error,atoi(config["DDI_length"].c_str()),atoi(config["DDI_base_length"].c_str()),DDIStopList);
|
2003-04-03 21:09:46 +00:00
|
|
|
capi->registerApplicationInterface(this);
|
|
|
|
|
2003-02-19 08:19:51 +00:00
|
|
|
string info;
|
|
|
|
if (debug_level>=2)
|
2003-04-03 21:09:46 +00:00
|
|
|
info=capi->getInfo(true);
|
2003-02-19 08:19:51 +00:00
|
|
|
else
|
2003-04-03 21:09:46 +00:00
|
|
|
info=capi->getInfo(false);
|
2003-02-19 08:19:51 +00:00
|
|
|
(*debug) << prefix();
|
|
|
|
for (int i=0;i<info.size();i++) {
|
|
|
|
(*debug) << info[i];
|
|
|
|
if (i!=info.size()-1 && info[i]=='\n')
|
|
|
|
(*debug) << prefix();
|
|
|
|
}
|
|
|
|
|
|
|
|
capi->setListenTelephony(0); // TODO: 0 = all, evtl. einstellbar?
|
|
|
|
capi->setListenFaxG3(0); // TODO: 0 = all, evtl. einstellbar?
|
|
|
|
|
|
|
|
// initialization of the Python interpreter to be thread safe (taken out of PyApache 4.26)
|
|
|
|
Py_Initialize();
|
|
|
|
PycString_IMPORT; // initialize cStringIO module
|
|
|
|
if (!(save_cStringIO=PycStringIO)) { // save it as it will be overwritten by each #include<cStringIO.h> with NULL (sic)
|
2003-03-06 09:34:44 +00:00
|
|
|
(*error) << prefix() << "FATAL error: error during Python interpreter initialization (cString)" << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
PyEval_InitThreads(); // init and acquire lock
|
|
|
|
py_state=PyEval_SaveThread(); // release lock, save thread context
|
|
|
|
if (!py_state) {
|
2003-03-06 09:34:44 +00:00
|
|
|
(*error) << prefix() << "FATAL error: can't release python lock" << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// idle script object
|
|
|
|
int interval=atoi(config["idle_script_interval"].c_str());
|
|
|
|
if (interval && config["idle_script"]!="")
|
|
|
|
idle=new IdleScript(*debug,debug_level,*error,capi,config["idle_script"],interval,py_state,save_cStringIO);
|
|
|
|
|
|
|
|
// signal handling
|
|
|
|
signal(SIGTERM,exit_handler);
|
|
|
|
signal(SIGINT,exit_handler); // this must be located after pyhton initialization
|
|
|
|
signal(SIGHUP,hup_handler);
|
|
|
|
}
|
|
|
|
catch (CapiError e) {
|
|
|
|
capisuiteInstance=NULL;
|
|
|
|
if (idle) {
|
|
|
|
idle->requestTerminate();
|
|
|
|
}
|
|
|
|
if (py_state) {
|
|
|
|
PyEval_RestoreThread(py_state); // switch to right thread context, acquire lock
|
|
|
|
py_state=NULL;
|
|
|
|
Py_Finalize();
|
|
|
|
}
|
|
|
|
if (capi)
|
|
|
|
delete capi;
|
|
|
|
(*error) << prefix() << "Can't start Capi abstraction. The given error message was: " << e << endl << endl;
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
catch (ApplicationError e) {
|
|
|
|
capisuiteInstance=NULL;
|
|
|
|
if (idle) {
|
|
|
|
idle->requestTerminate();
|
|
|
|
}
|
|
|
|
if (py_state) {
|
|
|
|
PyEval_RestoreThread(py_state); // switch to right thread context, acquire lock
|
|
|
|
py_state=NULL;
|
|
|
|
Py_Finalize();
|
|
|
|
}
|
|
|
|
if (capi)
|
|
|
|
delete capi;
|
|
|
|
(*error) << prefix() << "Can't start application. The given error message was: " << e << endl;
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CapiSuite::~CapiSuite()
|
|
|
|
{
|
|
|
|
if (idle)
|
|
|
|
idle->requestTerminate(); // will self-delete!
|
|
|
|
|
|
|
|
// thread-safe shutdown of the Python interpreter (taken out of PyApache 4.26)
|
|
|
|
if (py_state) {
|
|
|
|
PyEval_RestoreThread(py_state); // switch to right thread context, acquire lock
|
|
|
|
py_state=NULL;
|
|
|
|
Py_Finalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
delete capi;
|
|
|
|
|
|
|
|
(*debug) << prefix() << "CapiSuite finished." << endl;
|
|
|
|
(*error) << prefix() << "CapiSuite finished." << endl;
|
|
|
|
|
|
|
|
capisuiteInstance=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::finish()
|
|
|
|
{
|
|
|
|
if (debug_level >= 2)
|
|
|
|
(*debug) << prefix() << "requested finish" << endl;
|
|
|
|
finish_flag=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CapiSuite::reload()
|
|
|
|
{
|
|
|
|
if (debug_level >= 2)
|
|
|
|
(*debug) << prefix() << "requested reload" << endl;
|
|
|
|
if (idle)
|
|
|
|
idle->activate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::callWaiting (Connection *conn)
|
|
|
|
{
|
|
|
|
waiting.push(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::mainLoop()
|
|
|
|
{
|
|
|
|
timespec delay_time;
|
|
|
|
delay_time.tv_sec=0; delay_time.tv_nsec=100000000; // 100 msec
|
|
|
|
int count,errorcount=0;
|
|
|
|
while (!finish_flag) {
|
|
|
|
nanosleep(&delay_time,NULL);
|
|
|
|
count++;
|
|
|
|
while (waiting.size()) {
|
|
|
|
Connection* conn=waiting.front();
|
|
|
|
waiting.pop();
|
|
|
|
|
|
|
|
IncomingScript *instance;
|
|
|
|
try {
|
|
|
|
instance=new IncomingScript(*debug,debug_level,*error,conn,config["incoming_script"],save_cStringIO);
|
|
|
|
}
|
|
|
|
catch (ApplicationError e)
|
|
|
|
{
|
2003-02-25 13:22:42 +00:00
|
|
|
(*error) << prefix() << "ERROR: can't start IncomingScript thread, message was: " << e << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
delete instance;
|
|
|
|
}
|
|
|
|
// otherwise it will self-delete!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
string
|
|
|
|
CapiSuite::prefix()
|
|
|
|
{
|
|
|
|
time_t t=time(NULL);
|
|
|
|
char* ct=ctime(&t);
|
|
|
|
ct[24]='\0';
|
|
|
|
stringstream s;
|
|
|
|
s << ct << " CapiSuite " << hex << this << ": ";
|
|
|
|
return (s.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::parseConfigFile(ifstream &configfile)
|
|
|
|
{
|
|
|
|
while (!configfile.eof()) {
|
|
|
|
string l;
|
|
|
|
getline(configfile,l);
|
|
|
|
if (l.size() && l[0]!='#') {
|
|
|
|
int pos=l.find("=");
|
|
|
|
if (pos>0) {
|
|
|
|
int key_f=l.find_first_not_of("\" \t"); // strip blanks and " chars...
|
|
|
|
int key_l=l.find_last_not_of("\" \t",pos-1);
|
|
|
|
int value_f=l.find_first_not_of("\" \t",pos+1);
|
|
|
|
int value_l=l.find_last_not_of("\" \t");
|
|
|
|
string key,value;
|
|
|
|
if (key_f>=0 && key_f<=key_l) { // if we have a valid key
|
|
|
|
key=l.substr(key_f,key_l-key_f+1);
|
|
|
|
if (value_f>0 && value_f<=value_l)
|
|
|
|
value=l.substr(value_f,value_l-value_f+1);
|
|
|
|
else
|
|
|
|
value="";
|
|
|
|
config[key]=value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::checkOption(string key, string value)
|
|
|
|
{
|
|
|
|
if (!config.count(key)) {
|
2004-01-10 14:16:40 +00:00
|
|
|
cerr << "Warning: Can't find " << key << " variable. Using default (\"" << value << "\")." << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
config[key]=value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::logMessage(string message, int level)
|
|
|
|
{
|
|
|
|
if (debug_level >= level)
|
|
|
|
(*debug) << prefix() << message << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::errorMessage(string message)
|
|
|
|
{
|
|
|
|
(*error) << prefix() << message << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::readConfiguration()
|
|
|
|
{
|
|
|
|
ifstream configf;
|
|
|
|
|
|
|
|
if (custom_configfile.size()) {
|
|
|
|
configf.open(custom_configfile.c_str());
|
|
|
|
if (configf)
|
|
|
|
parseConfigFile(configf);
|
|
|
|
else
|
|
|
|
cerr << "Warning: Can't open custom file " << custom_configfile << "."<< endl;
|
|
|
|
configf.close();
|
|
|
|
} else {
|
|
|
|
configf.open((string(PKGSYSCONFDIR)+"/capisuite.conf").c_str());
|
|
|
|
if (configf)
|
|
|
|
parseConfigFile(configf);
|
|
|
|
else
|
|
|
|
cerr << "Warning: Can't open " << PKGSYSCONFDIR <<"/capisuite.conf." << endl;
|
|
|
|
configf.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
checkOption("incoming_script",string(PKGLIBDIR)+"/incoming.py");
|
|
|
|
checkOption("idle_script",string(PKGLIBDIR)+"idle.py");
|
|
|
|
checkOption("idle_script_interval","60");
|
|
|
|
checkOption("log_file",string(LOCALSTATEDIR)+"/log/capisuite.log");
|
|
|
|
checkOption("log_level","2");
|
|
|
|
checkOption("log_error",string(LOCALSTATEDIR)+"/log/capisuite.error");
|
2004-01-10 14:16:40 +00:00
|
|
|
checkOption("DDI_length","0");
|
|
|
|
checkOption("DDI_base_length","0");
|
|
|
|
checkOption("DDI_stop_numbers","");
|
2003-02-19 08:19:51 +00:00
|
|
|
|
|
|
|
string t(config["idle_script_interval"]);
|
|
|
|
for (int i=0;i<t.size();i++)
|
|
|
|
if (t[i]<'0' || t[i]>'9')
|
2004-01-10 14:16:40 +00:00
|
|
|
throw ApplicationError("Invalid idle_script_interval given.","readConfiguration()");
|
2003-02-19 08:19:51 +00:00
|
|
|
|
2003-02-21 23:21:44 +00:00
|
|
|
if (config["log_file"]!="" && config["log_file"]!="-") {
|
2003-02-19 08:19:51 +00:00
|
|
|
debug = new ofstream(config["log_file"].c_str(),ios::app);
|
|
|
|
if (! (*debug)) {
|
|
|
|
cerr << "Can't open log file. Writing to stdout." << endl;
|
|
|
|
delete debug;
|
|
|
|
debug = &cout;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
debug=&cout;
|
|
|
|
|
|
|
|
t=config["log_level"];
|
|
|
|
if (t.size()!=1 && (t[0]<'0' || t[0]>'3'))
|
|
|
|
throw ApplicationError("Invalid log_level given.","main()");
|
|
|
|
|
2003-02-21 23:21:44 +00:00
|
|
|
if (config["log_error"]!="" && config["log_error"]!="-") {
|
2003-02-19 08:19:51 +00:00
|
|
|
error = new ofstream(config["log_error"].c_str(),ios::app);
|
|
|
|
if (! (*error)) {
|
|
|
|
cerr << "Can't open error log file. Writing to stderr." << endl;
|
|
|
|
delete error;
|
|
|
|
error = &cerr;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
error=&cerr;
|
|
|
|
|
2004-01-10 14:16:40 +00:00
|
|
|
t=config["DDI_length"];
|
|
|
|
for (int i=0;i<t.size();i++)
|
|
|
|
if (t[i]<'0' || t[i]>'9')
|
|
|
|
throw ApplicationError("Invalid DDI_length given.","readConfiguration()");
|
|
|
|
|
|
|
|
t=config["DDI_base_length"];
|
|
|
|
for (int i=0;i<t.size();i++)
|
|
|
|
if (t[i]<'0' || t[i]>'9')
|
|
|
|
throw ApplicationError("Invalid DDI_base_length given.","readConfiguration()");
|
|
|
|
|
|
|
|
t=config["DDI_stop_numbers"];
|
|
|
|
for (int i=0;i<t.size();i++)
|
|
|
|
if ((t[i]<'0' || t[i]>'9') && t[i]!=',')
|
|
|
|
throw ApplicationError("Invalid DDI_stop_numbers given.","readConfiguration()");
|
|
|
|
|
2003-02-19 08:19:51 +00:00
|
|
|
if (daemonmode) {
|
|
|
|
if (debug==&cout) {
|
2003-03-06 09:34:44 +00:00
|
|
|
cerr << "FATAL error: not allowed to write to stdout in daemon mode." << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (error==&cerr) {
|
2003-03-06 09:34:44 +00:00
|
|
|
cerr << "FATAL error: not allowed to write to stderr in daemon mode." << endl;
|
2003-02-19 08:19:51 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::readCommandline(int argc, char** argv)
|
|
|
|
{
|
|
|
|
struct option long_options[] = {
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
|
|
|
{"config", required_argument, NULL, 'c'},
|
|
|
|
{"daemon", no_argument, NULL, 'd'},
|
|
|
|
{0, 0, 0, 0}
|
|
|
|
};
|
|
|
|
|
|
|
|
int result=0;
|
|
|
|
do {
|
|
|
|
result=getopt_long(argc,argv,"hdc:",long_options,NULL);
|
|
|
|
switch (result) {
|
|
|
|
case -1: // end
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'c':
|
|
|
|
custom_configfile=optarg;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'd':
|
|
|
|
daemonmode=true;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
default:
|
|
|
|
help();
|
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (result!=-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapiSuite::help()
|
|
|
|
{
|
|
|
|
cout << "CapiSuite " << VERSION << " (c) by Gernot Hillier <gernot@hillier.de>" << endl << endl;
|
|
|
|
cout << "CapiSuite is an python-scriptable ISDN Telecommunication Suite providing some" << endl;
|
|
|
|
cout << "ISDN services like fax, voice recording/playing, etc. For further documentation" << endl;
|
|
|
|
cout << "please have a look at the HTML documents provided with it." << endl << endl;
|
|
|
|
cout << "syntax: capisuite [-h] [-c file]" << endl << endl;
|
|
|
|
cout << "-h, --help show this help" << endl;
|
|
|
|
cout << "-c file, --config=file use a custom configuration file" << endl;
|
|
|
|
cout << " (default: " << PKGSYSCONFDIR <<"/capisuite.conf)" << endl;
|
|
|
|
cout << "-d, --daemon run as daemon" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* History
|
|
|
|
|
2003-12-28 21:01:04 +00:00
|
|
|
Old Log (for new changes see ChangeLog):
|
2004-01-10 14:16:40 +00:00
|
|
|
|
|
|
|
Revision 1.5.2.3 2003/11/06 18:32:15 gernot
|
|
|
|
- implemented DDIStopNumbers
|
|
|
|
|
|
|
|
Revision 1.5.2.2 2003/11/02 14:58:16 gernot
|
|
|
|
- use DDI_base_length instead of DDI_base
|
|
|
|
- added DDI_stop_numbers option
|
|
|
|
- use DDI_* options in the Connection class
|
|
|
|
- call the Python script if number is complete
|
|
|
|
|
|
|
|
Revision 1.5.2.1 2003/10/26 16:51:55 gernot
|
|
|
|
- begin implementation of DDI, get DDI Info Elements
|
|
|
|
|
2003-04-03 21:09:46 +00:00
|
|
|
Revision 1.5 2003/04/03 21:09:46 gernot
|
|
|
|
- Capi::getInfo isn't static any longer
|
|
|
|
|
2003-03-06 09:34:44 +00:00
|
|
|
Revision 1.4 2003/03/06 09:34:44 gernot
|
|
|
|
- added missing endl's in error messages
|
|
|
|
|
2003-02-25 13:22:42 +00:00
|
|
|
Revision 1.3 2003/02/25 13:22:42 gernot
|
|
|
|
- remove old, unused attribute
|
|
|
|
- correct some forgotten references to CallControl to IncomingScript
|
|
|
|
|
2003-02-21 23:21:44 +00:00
|
|
|
Revision 1.2 2003/02/21 23:21:44 gernot
|
|
|
|
- follow some a little bit stricter rules of gcc-2.95.3
|
|
|
|
|
|
|
|
Revision 1.1.1.1 2003/02/19 08:19:53 gernot
|
|
|
|
initial checkin of 0.4
|
2003-02-19 08:19:51 +00:00
|
|
|
|
|
|
|
Revision 1.14 2003/02/17 16:49:24 ghillie
|
|
|
|
- cosmetic...
|
|
|
|
|
|
|
|
Revision 1.13 2003/02/10 14:14:39 ghillie
|
|
|
|
merged from NATIVE_PTHREADS to HEAD
|
|
|
|
|
|
|
|
Revision 1.12.2.1 2003/02/09 14:58:13 ghillie
|
|
|
|
- rewritten parseConfigFile to use STL strings instead of CommonC++ strtokenizer
|
|
|
|
- no need to call detach on thread classes any more (because of their new
|
|
|
|
usage of native pthreads)
|
|
|
|
|
|
|
|
Revision 1.12 2003/02/05 15:57:57 ghillie
|
|
|
|
- improved error handling, replaced some outputs to cerr with
|
|
|
|
correct error stream
|
|
|
|
|
|
|
|
Revision 1.11 2003/01/31 11:25:53 ghillie
|
|
|
|
- moved capisuiteInstance from header to cpp (mustn't be defined in
|
|
|
|
each file including capisuite.h, use extern there instead!)
|
|
|
|
|
|
|
|
Revision 1.10 2003/01/27 19:25:14 ghillie
|
|
|
|
- config moved to etc/capisuite/*
|
|
|
|
|
|
|
|
Revision 1.9 2003/01/19 16:50:27 ghillie
|
|
|
|
- removed severity in exceptions. No FATAL-automatic-exit any more.
|
|
|
|
Removed many FATAL conditions, other ones are exiting now by themselves
|
|
|
|
|
|
|
|
Revision 1.8 2003/01/19 12:06:05 ghillie
|
|
|
|
- support starting as daemon with "-d" (resolving TODO)
|
|
|
|
- nicer formatting for getInfo output at startup (resolves TODO)
|
|
|
|
- new methods logMessage() and errorMessage() for use in python scripts
|
|
|
|
(resolves TODO)
|
|
|
|
|
|
|
|
Revision 1.7 2003/01/18 12:51:08 ghillie
|
|
|
|
- initialization of cStringIO needed for printing tracebacks to error log
|
|
|
|
(solved one TODO item), pass on reference to *Script
|
|
|
|
|
|
|
|
Revision 1.6 2003/01/13 21:24:17 ghillie
|
|
|
|
- corrected typos
|
|
|
|
- reverted change to config options
|
|
|
|
|
|
|
|
Revision 1.5 2003/01/08 15:59:05 ghillie
|
|
|
|
- updated for new configuration variables for pathes, new method checkOption()
|
|
|
|
|
|
|
|
Revision 1.4 2003/01/07 14:51:19 ghillie
|
|
|
|
- added commandline parsing (new methods help(), readCommandLine():
|
|
|
|
-h/--help and -c/--config (other configuration file)
|
|
|
|
|
|
|
|
Revision 1.3 2003/01/06 21:00:24 ghillie
|
|
|
|
- added SIGHUP support (new functions hup_handler, CapiSuite::reload)
|
|
|
|
|
|
|
|
Revision 1.2 2003/01/06 16:20:36 ghillie
|
|
|
|
- added error check for idle->detach()
|
|
|
|
- removed superfluous delete idle calls (SEGV)
|
|
|
|
|
|
|
|
Revision 1.1 2003/01/05 12:28:09 ghillie
|
|
|
|
- renamed FlowControl to CapiSuite
|
|
|
|
- the code from main() was moved to this class
|
|
|
|
|
|
|
|
Revision 1.23 2003/01/04 15:57:03 ghillie
|
|
|
|
- added exit handler for SIGINT and SIGTERM
|
|
|
|
- added static FlowControl pointer
|
|
|
|
- added finish method for exit handler
|
|
|
|
- added timestamp in log files
|
|
|
|
- log_level support
|
|
|
|
|
|
|
|
Revision 1.22 2002/12/14 14:01:06 ghillie
|
|
|
|
- just terminate() IdleScript instance, don't delete it (will delete self!)
|
|
|
|
|
|
|
|
Revision 1.21 2002/12/11 13:01:59 ghillie
|
|
|
|
- executeIdleScript() removed, its function is now done by IdleScript
|
|
|
|
object (changes in constructor and mainLoop())
|
|
|
|
- removed getCapi()
|
|
|
|
|
|
|
|
Revision 1.20 2002/12/10 15:52:18 ghillie
|
|
|
|
- begin changes for moving functionality from executeIdleScript() to
|
|
|
|
IdleScript class
|
|
|
|
|
|
|
|
Revision 1.19 2002/12/10 15:05:14 ghillie
|
|
|
|
- changed CallControl to IncomingScript
|
|
|
|
- added some missing =NULL statements in executeIdleScript()
|
|
|
|
|
|
|
|
Revision 1.18 2002/12/09 15:26:11 ghillie
|
|
|
|
- callWaiting does add Connection to queue only, real handling moved
|
|
|
|
to mainLoop() as it may block in error handling
|
|
|
|
- error output/exception improvements (WARNING -> ERROR severity, ...)
|
|
|
|
- removed obsolete debug() method
|
|
|
|
|
|
|
|
Revision 1.17 2002/12/07 22:37:56 ghillie
|
|
|
|
- moved capisuitemodule_init() call from executeIdleScript() to constructor
|
|
|
|
- get __main__ as it's not returned by capisuitemodule_init() any more
|
|
|
|
- MEMORY FIX: added missing fclose call
|
|
|
|
|
|
|
|
Revision 1.16 2002/12/05 15:55:10 ghillie
|
|
|
|
- removed callCompleted() as now exception will be thrown in python script any more
|
|
|
|
- removed instances attribute
|
|
|
|
|
|
|
|
Revision 1.15 2002/12/05 14:52:31 ghillie
|
|
|
|
- in executeIdleScript(): removed ugly strncpy, used const_cast<char*>() instead to satisfy PyRun_SimpleFile()
|
|
|
|
- cleaned up python reference counting
|
|
|
|
- new method getCapi()
|
|
|
|
|
|
|
|
Revision 1.14 2002/12/02 12:28:09 ghillie
|
|
|
|
- FlowControl constructor now takes 3 additional parameters for the scripts to be used
|
|
|
|
- added support for regular execution of an idle script in mainLoop(), added executeIdleScript()
|
|
|
|
|
|
|
|
Revision 1.13 2002/11/29 10:20:44 ghillie
|
|
|
|
- updated docs, use doxygen format now
|
|
|
|
|
|
|
|
Revision 1.12 2002/11/27 15:57:25 ghillie
|
|
|
|
added missing throw() declaration
|
|
|
|
|
|
|
|
Revision 1.11 2002/11/23 16:40:19 ghillie
|
|
|
|
removed unnecessary include
|
|
|
|
|
|
|
|
Revision 1.10 2002/11/21 11:35:54 ghillie
|
|
|
|
- in case of call Completion just call instance->callCompleted() instead of deleting it.
|
|
|
|
This allows us to continue w/o waiting for the thread to finish.
|
|
|
|
|
|
|
|
Revision 1.9 2002/11/20 17:17:46 ghillie
|
|
|
|
- FIX: instances weren't erased when exception occurred -> this lead to double used PLCI
|
|
|
|
- in mainLoop(): changed sleep to nanosleep
|
|
|
|
|
|
|
|
Revision 1.8 2002/11/19 15:57:18 ghillie
|
|
|
|
- Added missing throw() declarations
|
|
|
|
- phew. Added error handling. All exceptions are caught now.
|
|
|
|
|
|
|
|
Revision 1.7 2002/11/18 14:21:07 ghillie
|
|
|
|
- moved global severity_t to ApplicationError::severity_t
|
|
|
|
- added throw() declarations to header files
|
|
|
|
|
|
|
|
Revision 1.6 2002/11/14 17:05:19 ghillie
|
|
|
|
major structural changes - much is easier, nicer and better prepared for the future now:
|
|
|
|
- added DisconnectLogical handler to CallInterface
|
|
|
|
- DTMF handling moved from CallControl to Connection
|
|
|
|
- new call module ConnectModule for establishing connection
|
|
|
|
- python script reduced from 2 functions to one (callWaiting, callConnected
|
|
|
|
merged to callIncoming)
|
|
|
|
- call modules implement the CallInterface now, not CallControl any more
|
|
|
|
=> this freed CallControl from nearly all communication stuff
|
|
|
|
|
|
|
|
Revision 1.5 2002/11/13 08:34:54 ghillie
|
|
|
|
moved history to the bottom
|
|
|
|
|
|
|
|
Revision 1.4 2002/11/10 17:02:54 ghillie
|
|
|
|
mainLoop prepared for Python execution
|
|
|
|
|
|
|
|
Revision 1.3 2002/11/07 08:19:04 ghillie
|
|
|
|
some improvements and fixes in Python global lock and thread state handling
|
|
|
|
|
|
|
|
Revision 1.2 2002/10/27 12:47:20 ghillie
|
|
|
|
- added multithread support for python
|
|
|
|
- changed callcontrol reference to stay in the python namespace
|
|
|
|
- changed ApplicationError to support differen severity
|
|
|
|
|
|
|
|
Revision 1.1 2002/10/25 13:29:38 ghillie
|
|
|
|
grouped files into subdirectories
|
|
|
|
|
|
|
|
Revision 1.8 2002/10/24 09:55:52 ghillie
|
|
|
|
many fixes. Works for one call now
|
|
|
|
|
|
|
|
Revision 1.7 2002/10/23 15:40:15 ghillie
|
|
|
|
added python integration...
|
|
|
|
|
|
|
|
Revision 1.6 2002/10/09 14:36:22 gernot
|
|
|
|
added CallModule base class for all call handling modules
|
|
|
|
|
|
|
|
Revision 1.5 2002/10/05 20:43:32 gernot
|
|
|
|
quick'n'dirty, but WORKS
|
|
|
|
|
|
|
|
Revision 1.4 2002/10/05 13:53:00 gernot
|
|
|
|
changed to use thread class of CommonC++ instead of the threads-package
|
|
|
|
some cosmetic improvements (indentation...)
|
|
|
|
|
|
|
|
Revision 1.3 2002/10/04 15:48:03 gernot
|
|
|
|
structure changes completed & compiles now!
|
|
|
|
|
|
|
|
Revision 1.2 2002/10/04 13:27:15 gernot
|
|
|
|
some restructuring to get it to a working state ;-)
|
|
|
|
|
|
|
|
does not do anything useful yet nor does it even compile...
|
|
|
|
|
|
|
|
Revision 1.1 2002/10/02 14:10:07 gernot
|
|
|
|
first version
|
|
|
|
|
|
|
|
*/
|