capisuite/src/application/incomingscript.cpp

319 lines
11 KiB
C++
Raw Normal View History

/* @file incomingscript.cpp
@brief Contains IncomingScript - Incoming call handling. One object for each incoming call is created.
@author Gernot Hillier <gernot@hillier.de>
$Revision: 1.2 $
*/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "incomingscript.h"
#include "../modules/disconnectmodule.h"
#include "capisuitemodule.h"
#define TEMPORARY_FAILURE 0x34A9 // see ETS 300 102-1, Table 4.13 (cause information element)
void* incomingscript_exec_handler(void* arg)
{
if (!arg) {
cerr << "FATAL ERROR: no IncomingScript reference given in incomingscript_exec_handler" << endl;
exit(1);
}
pthread_cleanup_push(incomingscript_cleanup_handler,arg);
IncomingScript *instance=static_cast<IncomingScript*>(arg);
instance->run();
pthread_cleanup_pop(1); // run the cleanup_handler and then deregister it
}
void incomingscript_cleanup_handler(void* arg)
{
if (!arg) {
cerr << "FATAL ERROR: no IncomingScript reference given in incomingscript_exec_handler" << endl;
exit(1);
}
IncomingScript *instance=static_cast<IncomingScript*>(arg);
instance->final();
}
IncomingScript::IncomingScript(ostream &debug, unsigned short debug_level, ostream &error, Connection *conn, string incoming_script, PycStringIO_CAPI* cStringIO) throw (ApplicationError)
:PythonScript(debug,debug_level,error,incoming_script,"callIncoming",cStringIO),conn(conn)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
int ret=pthread_create(&thread_handle, &attr, incomingscript_exec_handler, this); // start thread as detached
if (ret)
throw ApplicationError("error while creating thread","PythonScript::PythonScript()");
if (debug_level>=2)
debug << prefix() << "Connection " << conn << " created IncomingScript" << endl;
}
IncomingScript::~IncomingScript()
{
if (conn) {
error << prefix() << "Warning: Connection still established in IncomingScript destructor. Disconnecting." << endl;
try {
DisconnectModule active(conn,TEMPORARY_FAILURE);
active.mainLoop();
}
catch (CapiError e) {
error << prefix() << "ERROR: disconnection also failed. Too bad..." << endl;
}
delete conn;
}
if (debug_level>=2)
debug << prefix() << "IncomingScript deleted" << endl;
}
void
IncomingScript::run() throw()
{
PyObject *conn_ref=NULL;
PyThreadState *py_state=NULL;
try {
// thread safe Python init, taken out of PyApache 4.26
PyEval_AcquireLock();
if (!(py_state=Py_NewInterpreter() )) {
PyEval_ReleaseLock();
capisuitemodule_destruct_connection(conn);
throw ApplicationError("error while creating new python interpreter","IncomingScript::run()");
}
capisuitemodule_init();
conn_ref=PyCObject_FromVoidPtr(conn,capisuitemodule_destruct_connection); // new ref
if (!conn_ref) {
capisuitemodule_destruct_connection(conn);
throw ApplicationError("unable to create CObject from Connection reference","IncomingScript::run()");
}
args=Py_BuildValue("Oiss",conn_ref,conn->getService(),conn->getCallingPartyNumber().c_str(),conn->getCalledPartyNumber().c_str());
if (!args)
throw ApplicationError("error during argument building","IncomingScript::run()");
PythonScript::run();
Py_DECREF(args);
args=NULL;
Py_DECREF(conn_ref);
conn_ref=NULL;
conn=NULL; // Connection object will be deleted by Python destruction handler...
Py_EndInterpreter(py_state);
py_state=NULL;
PyEval_ReleaseLock(); // release lock
}
catch(ApplicationError e) {
error << prefix() << "Error occured. message was: " << e << endl;
if (args)
Py_DECREF(args);
if (conn_ref) {
Py_DECREF(conn_ref);
conn=NULL;
}
if (py_state) {
Py_EndInterpreter(py_state);
py_state=NULL;
PyEval_ReleaseLock();
}
}
}
/* History
Old Log (for new changes see ChangeLog):
Revision 1.1.1.1 2003/02/19 08:19:53 gernot
initial checkin of 0.4
Revision 1.9 2003/02/10 14:17:09 ghillie
merged from NATIVE_PTHREADS to HEAD
Revision 1.8.2.1 2003/02/09 15:03:41 ghillie
- rewritten to use native pthread_* calls instead of CommonC++ Thread
Revision 1.8 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.7 2003/01/19 12:08:47 ghillie
- changed some debug_levels
Revision 1.6 2003/01/18 12:53:06 ghillie
- pass on reference to Python C API to PythonScript
Revision 1.5 2003/01/04 16:00:53 ghillie
- log improvements: log_level, timestamp
Revision 1.4 2002/12/14 14:03:27 ghillie
- added throw() declaration to run() method
Revision 1.3 2002/12/13 09:57:10 ghillie
- error message formatting done by exception classes now
Revision 1.2 2002/12/10 15:52:32 ghillie
- removed debug output
Revision 1.1 2002/12/10 15:01:08 ghillie
- class IncomingScript now takes over the functionality of the old CallControl
class defined in callcontrol.*, but uses a base class now
Revision 1.29 2002/12/09 15:23:49 ghillie
- moved start() out of constructor in creator (was unspecified this way!)
- moved disconnection to destructor so it's assured it happens
- exception severity cleanup (no more WARNING exceptions)
- python reference counting cleanup
- added debug stream as constructor parameter, debug output improvement
Revision 1.28 2002/12/07 22:30:48 ghillie
- removed copying of filename to new char*, used const_cast from (const char*)
to (char*) instead
- moved python initialization code from constructor to run(), makes some
attributes obsolete
- getting __main__ namespace now taken out of capisuitemodule_init(), done
here instead
- use DisconnectModule for error handling now
Revision 1.27 2002/12/06 15:23:14 ghillie
- wait for successful disconnection when an error in the script occured
Revision 1.26 2002/12/06 12:50:02 ghillie
- passed the destruction function capisuitemodule_destruct_connection to the PyCObject containing connection reference
Revision 1.25 2002/12/05 15:52:48 ghillie
- begin restructuring for self deletion of Connection object after it gets its OK from CallControl/FlowControl
Revision 1.24 2002/12/05 14:48:25 ghillie
- cleaned up some python reference counting
Revision 1.23 2002/12/02 12:21:56 ghillie
- incoming script name is now a parameter to constructor, not #define'd any more
- service parameter to python script now uses constants defined in Connection::service_t
- SEGV FIX: isRunning is now set to false before ending Python interpreter in run(), callCompleted() acquires
python global lock _before_ reading isRunning -> race condition fixed
- exception handler in run() ends python interpreter correctly now
Revision 1.22 2002/11/29 11:09:04 ghillie
renamed CapiCom to CapiSuite (name conflict with MS crypto API :-( )
Revision 1.21 2002/11/29 10:20:44 ghillie
- updated docs, use doxygen format now
Revision 1.20 2002/11/25 11:44:48 ghillie
removed CIP value from application, use service type instead
Revision 1.19 2002/11/23 15:54:40 ghillie
pcallcontrol was renamed to capicommodule
Revision 1.18 2002/11/21 11:34:08 ghillie
- changed Reject cause when we have a problem from "Destination Out Of Order" to "Temporary Failure"
- moved Py_EndInterpreter from destructor to run()
- new method callCompleted() which throws CallGoneError into Python
- new method final() which is called automatically after thread has finished, now CallControl objects will delete themselves
to allow cleanup routines in Python scripts which may take some time to finish w/o freezing the whole application
Revision 1.17 2002/11/20 17:16:24 ghillie
- SEGV-Fix: CallGoneError only triggered if python script is still running in CallControl::~CallControl
- changed sleep in mainLoop() to nanosleep
- small typo fixed
Revision 1.16 2002/11/19 15:57:18 ghillie
- Added missing throw() declarations
- phew. Added error handling. All exceptions are caught now.
Revision 1.15 2002/11/18 14:21:07 ghillie
- moved global severity_t to ApplicationError::severity_t
- added throw() declarations to header files
Revision 1.14 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.13 2002/11/13 15:21:22 ghillie
added some error handling for python states
Revision 1.12 2002/11/13 08:34:54 ghillie
moved history to the bottom
Revision 1.11 2002/11/12 15:47:27 ghillie
added dataIn-handler
Revision 1.10 2002/11/10 17:02:22 ghillie
changed to pass CallControl reference to the called python functions
Revision 1.9 2002/11/07 08:19:04 ghillie
some improvements and fixes in Python global lock and thread state handling
Revision 1.8 2002/11/06 16:16:07 ghillie
added code to raise CallGoneError in any case so the script is cancelled when the call is gone surely
Revision 1.7 2002/10/31 12:35:58 ghillie
added DTMF support
Revision 1.6 2002/10/30 16:05:20 ghillie
cosmetic fixes...
Revision 1.5 2002/10/30 14:24:41 ghillie
added support for python call handling before call is connected
Revision 1.4 2002/10/30 10:45:51 ghillie
added #define for value which should go to config file later
Revision 1.3 2002/10/29 14:06:36 ghillie
several fixes in run method
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.9 2002/10/24 09:55:52 ghillie
many fixes. Works for one call now
Revision 1.8 2002/10/23 15:40:15 ghillie
added python integration...
Revision 1.7 2002/10/10 12:45:40 gernot
added AudioReceive module, some small details changed
Revision 1.6 2002/10/09 14:36:22 gernot
added CallModule base class for all call handling modules
Revision 1.5 2002/10/09 11:18:59 gernot
cosmetic changes (again...) and changed info function of CAPI class
Revision 1.4 2002/10/05 20:43:32 gernot
quick'n'dirty, but WORKS
Revision 1.3 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.2 2002/10/04 15:48:03 gernot
structure changes completed & compiles now!
Revision 1.1 2002/10/04 13:28:43 gernot
CallControll class added
*/