Jetzt zum den individuellen Anpassungen.
Zunächst zu capisuite.
Um einen Anruf abzupassen und Aktionen auszuführen ist das incomming-script nötig. Ich habe das Default skript durch folgendes ersetzt:
Code: Select all
# implement simple callback to internet function
# Iniziiere internetverbindung wenn bestimmter Anschluss anruft.
# Danach kann mit vpn ein Zugang hergestellt werden...
import os, string, capisuite, commands
numbers="hier stehen meine erlaubten Telefonnummern mit komma getrennt"
msn="meine msn"
def callIncoming(call,service,call_from,call_to):
if (call_from not in numbers.split(',') or call_to!=msn):
capisuite.log("call from "+call_from+" to "+call_to+" ignoring",1,call)
capisuite.reject(call,0x3495)
return
# Wenn menschlicher Anrufer, dann Rueckmeldung
if (service==capisuite.SERVICE_VOICE):
capisuite.log("call from "+call_from+" to "+call_to+" accepted",1,call)
capisuite.connect_voice(call,2)
capisuite.audio_send(call,"/usr/share/capisuite/beep.la")
else:
capisuite.reject(call,0x3490)
capisuite.disconnect(call)
# Starte Verbindung
erg=commands.getoutput("ping -c 4 www.t-com.de")
capisuite.log("ping command output: "+erg,1,call)
erg=commands.getoutput("logger \"capisuite initiated connection\" ")
capisuite.log("logger command output: "+erg,1,call)
Das Skript testet, ob die Nummer gelistet ist. Wenn ja startet es ein Ping zur Interneteinwahl und gibt ein "beep" aus.
Nun musste ich feststellen, das das idle-skript nicht auf Kommando zum Laufen gebacht werden konnnte. Und einen Dauerlauf alle 2s
ist zu viel und 30s waren zu lange. Also habe ich capisuite gepatch um das Skript auf Signal SIGUSR1 zu starten. Zusätzlich kann ich im Skript Abfragen, ob der Start erzwungen war oder nicht.
Der Patch dazu ist hier:
Code: Select all
Nur in capisuite-0.4.5u1/scripts: capisuitefax.
diff -ur capisuite-0.4.5/src/application/capisuite.cpp capisuite-0.4.5u1/src/application/capisuite.cpp
--- capisuite-0.4.5/src/application/capisuite.cpp 2004-11-28 14:35:24.000000000 +0100
+++ capisuite-0.4.5u1/src/application/capisuite.cpp 2005-12-25 17:25:13.000000000 +0100
@@ -47,6 +47,14 @@
capisuiteInstance->reload();
signal(SIGHUP,hup_handler);
}
+
+void usr1_handler(int)
+{
+ if (capisuiteInstance)
+ capisuiteInstance->forceIdleRun();
+ signal(SIGUSR1,usr1_handler);
+}
+
CapiSuite::CapiSuite(int argc,char **argv)
:capi(NULL),waiting(),config(),idle(NULL),py_state(NULL),debug(NULL),error(NULL),finish_flag(false),custom_configfile(),daemonmode(false)
@@ -129,6 +137,7 @@
signal(SIGTERM,exit_handler);
signal(SIGINT,exit_handler); // this must be located after pyhton initialization
signal(SIGHUP,hup_handler);
+ signal(SIGUSR1,usr1_handler);
}
catch (CapiError e) {
capisuiteInstance=NULL;
@@ -199,6 +208,21 @@
idle->activate();
}
+void CapiSuite::forceIdleRun()
+{
+ if (debug_level >= 2)
+ (*debug) << prefix() << "forced start of idle script" << endl;
+ if (idle)
+ idle->forceRun();
+}
+
+bool CapiSuite::idleRunWasForced() {
+ if (idle)
+ return idle->runWasForced();
+ else
+ return false;
+}
+
void
CapiSuite::callWaiting (Connection *conn)
{
diff -ur capisuite-0.4.5/src/application/capisuite.h capisuite-0.4.5u1/src/application/capisuite.h
--- capisuite-0.4.5/src/application/capisuite.h 2004-11-28 14:35:24.000000000 +0100
+++ capisuite-0.4.5u1/src/application/capisuite.h 2005-12-25 15:53:57.000000000 +0100
@@ -114,6 +114,14 @@
*/
void reload();
+ /** @brief force run of idle script on SIGUSR1
+ */
+ void forceIdleRun();
+
+ /** @brief check if Idle was forced to run
+ */
+ bool idleRunWasForced();
+
/** @brief print a message to the log
Prints message to the log if it's level is high enough.
@@ -162,7 +170,6 @@
map<string,string> config; ///< holds the configuration read from the configfile
string custom_configfile; ///< holds the name of the custom config file if given
-
};
#endif
diff -ur capisuite-0.4.5/src/application/capisuitemodule.cpp capisuite-0.4.5u1/src/application/capisuitemodule.cpp
--- capisuite-0.4.5/src/application/capisuitemodule.cpp 2004-11-28 14:35:25.000000000 +0100
+++ capisuite-0.4.5u1/src/application/capisuitemodule.cpp 2005-12-25 17:28:23.000000000 +0100
@@ -915,6 +915,16 @@
return (result);
}
+static PyObject*
+capisuite_forced_run(PyObject*, PyObject *args)
+{
+ PyArg_NoArgs(args);
+ if (capisuiteInstance->idleRunWasForced())
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
/** PCallControlMethods - array of functions in module capisuite
*/
@@ -935,6 +945,7 @@
{"read_DTMF", capisuite_read_DTMF, METH_VARARGS, "Read and clear received DTMF. For further details see capisuite module reference."},
{"log", capisuite_log, METH_VARARGS, "Write log message. For further details see capisuite module reference."},
{"error", capisuite_error, METH_VARARGS, "Write error message. For further details see capisuite module reference."},
+ {"forced_run", capisuite_forced_run, METH_NOARGS, "Check if idle script was forced to run via SIGUSR. For further details see capisuite module reference."},
{NULL,NULL,0,NULL}
};
@@ -977,7 +988,6 @@
}
}
-
/* History
$Log: capisuitemodule.cpp,v $
diff -ur capisuite-0.4.5/src/application/idlescript.h capisuite-0.4.5u1/src/application/idlescript.h
--- capisuite-0.4.5/src/application/idlescript.h 2004-11-28 14:35:24.000000000 +0100
+++ capisuite-0.4.5u1/src/application/idlescript.h 2005-12-25 17:34:16.000000000 +0100
@@ -82,6 +82,12 @@
*/
void activate(void);
+ /** @brief force run of idle script (e.g. for user signals)
+ */
+ void forceRun(void);
+
+ bool runWasForced(void);
+
private:
/** @brief Thread body. Calls the python function idle().
@@ -109,8 +115,10 @@
int idlescript_interval; ///< interval between subsequent executions of idle script
Capi *capi; ///< reference to Capi object
bool active; ///< used to disable IdleScript in case of too much errors
-
+ bool forced; ///< used to force run of IdleScript
pthread_t thread_handle; ///< handle for the created pthread thread
+ pthread_mutex_t idle_mut; //< mutex for forced run of IdleScript
+ pthread_cond_t idle_cond; //< condition for forced run of IdleScript
};
#endif
Wie man den patch einspielt? Durch einen Trick. Ich juble ebuild meinen Patch einfach unter, weil ich zu faul bin einen eigenen ebuild zu schreiben.
Code: Select all
ebuild /usr/portage/net-dialup/capisuite/capisuite-0.4.5.ebuild unpack
cd /var/lib/portage/capisuite-0.4.5/work
patch -p0 < capisuite-0.4.5-u1.patch
ebuild /usr/portage/net-dialup/capisuite/capisuite-0.4.5.ebuild compile install qmerge
Danach kann ich mein idle-skript auf der client-Seite wie folgt erstellen:
Code: Select all
# idle script fuer client
import os, string, capisuite
my_nr="hier meine msn"
callback_nr="hier die anzurufende Nummer"
def idle(capi):
capisuite.log("idle script running",2)
if (capisuite.forced_run()):
capisuite.log("idle script forced to run",2)
capisuite.log("initiating callback for server...",1)
(call,result)=capisuite.call_voice(capi,1,my_nr,callback_nr,20,0)
if (result!=0):
capisuite.log("...no success! Error is 0x%x" % result,1)
else:
capisuite.log("...success!",1)
capisuite.disconnect(call)
return
Es testet zunächst, ob es normal oder per Signal gestartet wurde. Wenn das Signal kam, wählt es die gewünschte Nummer und wartet auf eine erfolgreiche Antwort, legt dann gleich auf. Voila!
(Hier könnte man jetzt auch eine Übermittlung dynamischer ip-Adressen per dialtone einbauen...)