* configuration can be accessed in IVR scripts while they are loaded

* pin_collect applications again has two modes: authentication via XMLRPC 
  server, and sending out transfer REFER with PIN in URI
* added documentation for pin_collect, and transfer for conference



git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@257 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 20 years ago
parent eec606aedb
commit 0ce5e2c3d2

@ -294,16 +294,43 @@ bool IvrFactory::loadScript(const string& path)
{
PYLOCK;
PyObject *modName,*mod,*dict, *dlg_class, *config=NULL;
modName = PyString_FromString(path.c_str());
mod = PyImport_Import(modName);
PyObject *modName=NULL,*mod=NULL,*dict=NULL,*dlg_class=NULL,*config=NULL;
// load module configuration
AmConfigReader cfg;
string cfg_file = add2path(AmConfig::ModConfigPath,1,(path + ".conf").c_str());
if(cfg.loadFile(cfg_file)){
ERROR("could not load config file at %s\n",cfg_file.c_str());
goto error2;
}
config = PyDict_New();
if(!config){
ERROR("could not allocate new dict for config\n");
goto error2;
}
for(map<string,string>::const_iterator it = cfg.begin();
it != cfg.end(); it++){
PyDict_SetItem(config,
PyString_FromString(it->first.c_str()),
PyString_FromString(it->second.c_str()));
}
// set config ivr ivr_module while loading
Py_INCREF(config);
PyObject_SetAttrString(ivr_module,"config",config);
// load module
modName = PyString_FromString(path.c_str());
mod = PyImport_Import(modName);
Py_DECREF(modName);
// remove config ivr ivr_module while loading
PyObject_DelAttrString(ivr_module, "config");
Py_DECREF(config);
if(!mod){
PyErr_Print();
WARN("IvrFactory: Failed to load \"%s\"\n", path.c_str());
@ -335,25 +362,6 @@ bool IvrFactory::loadScript(const string& path)
goto error2;
}
if(cfg.loadFile(cfg_file)){
ERROR("could not load config file at %s\n",cfg_file.c_str());
goto error2;
}
config = PyDict_New();
if(!config){
ERROR("could not allocate new dict for config\n");
goto error2;
}
for(map<string,string>::const_iterator it = cfg.begin();
it != cfg.end(); it++){
PyDict_SetItem(config,
PyString_FromString(it->first.c_str()),
PyString_FromString(it->second.c_str()));
}
PyObject_SetAttrString(mod,"config",config);
mod_reg.insert(make_pair(path,

@ -1,6 +1,15 @@
# authentication mode:
# XMLRPC : authenticate against XMLRPC server
# REFER : add pin to REFER sent out to be checked at proxy
auth_mode=XMLRPC
# XMLRPC url to authenticate against if auth_mode==XMLRPC
auth_xmlrpc_url = http://127.0.0.1:9090/
# messages to play to caller
welcome_msg=/usr/lib/sems/audio/pincollect/welcome.wav
pin_msg=/usr/lib/sems/audio/pincollect/enter_pin.wav
fail_msg=/usr/lib/sems/audio/pincollect/fail.wav
auth_fail_msg=/usr/lib/sems/audio/pincollect/notcorrect.wav
auth_xmlrpc_url = http://127.0.0.1:9090/

@ -1,6 +1,8 @@
from log import *
from ivr import *
import xmlrpclib
if (config['auth_mode'] == 'XMLRPC'):
import xmlrpclib
#states
collect = 0
@ -64,31 +66,50 @@ class IvrDialog(IvrDialogBase):
def onDtmf(self,key,duration):
if self.state == collect:
self.flush()
if key < 10:
self.keys += str(key)
debug("added key, PIN = " + self.keys)
self.setTimer(HINT_TIMER, HINT_TIMEOUT)
elif key == 10:
c = xmlrpclib.ServerProxy(config['auth_xmlrpc_url'])
erg = c.authorize(self.dialog.user, self.keys)
debug('result of authentication: '+ str(erg))
if erg == 'OK':
# XMLRPC authentication mode
if (config['auth_mode'] == 'XMLRPC'):
try:
c = xmlrpclib.ServerProxy(config['auth_xmlrpc_url'])
erg = c.authorize(self.dialog.user, self.keys)
debug('result of authentication: '+ str(erg))
if erg == 'OK':
self.state = connect
self.removeTimer(HINT_TIMER)
self.dlg_remote_uri = self.dialog.remote_uri
debug("saved remote_uri "+ self.dlg_remote_uri)
self.transfer_cseq = self.dialog.cseq
self.redirect("sip:" + self.dialog.user + "@" + \
self.dialog.domain)
else:
self.flush()
self.keys = ''
if self.auth_fail_msg == None:
self.auth_fail_msg = IvrAudioFile()
self.auth_fail_msg.open(config['auth_fail_msg'],AUDIO_READ)
self.enqueue(self.auth_fail_msg,None)
except:
self.dlg_remote_uri = self.dialog.remote_uri
self.state = connect_failed
self.fail_msg = IvrAudioFile()
self.fail_msg.open(config['fail_msg'],AUDIO_READ)
self.enqueue(self.fail_msg,None)
else:
self.state = connect
self.removeTimer(HINT_TIMER)
self.dlg_remote_uri = self.dialog.remote_uri
self.dlg_remote_uri = self.dialog.remote_uri
debug("saved remote_uri "+ self.dlg_remote_uri)
self.transfer_cseq = self.dialog.cseq
self.redirect("sip:" + self.dialog.user + "@" + \
self.dialog.domain)
else:
self.flush()
self.keys = ''
if self.auth_fail_msg == None:
self.auth_fail_msg = IvrAudioFile()
self.auth_fail_msg.open(config['auth_fail_msg'],AUDIO_READ)
self.enqueue(self.auth_fail_msg,None)
self.redirect("sip:" + self.dialog.user + "+" + self.keys + "@" + \
self.dialog.domain)
def onEmptyQueue(self):

@ -41,3 +41,34 @@ drop_sound: sound to be played to all the participants
dialout_suffix: suffix to be append to the numbered entered by
the user. Example: @iptel.org
Adding participants with "Transfer" REFER:
------------------------------------------
The "Transfer REFER" is a proprietary REFER call flow which transfers a
SIP dialog and session to another user agent ('taker'). If the transfer
REFER is accepted, the one transfering the call just "forgets" the dialog
and associated session, while the taker can send a re-Invite, thus overtaking
the dialog and session. For this to work, both transferer and taker must
be behind the same record routing proxy, and the callers user agent must
properly support re-Invite (updating of contact, and session, as specified
in RFC3261).
The transfer request sent out has two headers, which are needed by the
entity taking the call:
P-Transfer-RR : route set of the call
P-Transfer-NH : next hop
These headers must be configured in ser.cfg to be passed to the conference
application, for example using the following tw_append:
# appends for REFER
modparam( "tm", "tw_append",
"refer_append:hdr[P-Transfer-NH];hdr[P-Transfer-RR]")
...
t_write_unix("/tmp/msp_conference_sock","conference/refer_append");
Note that while this request has the method 'REFER', it does not follow rfc3515,
for example the Refer-To header is not used.

@ -0,0 +1,33 @@
SEMS pin_collect application Readme
This application collects a PIN and then transfers using a
(proprietary) REFER the call.
The authentication mode can be set in the configuration file
(auth_mode parameter).
Authentication Modes:
XMLRPC : Authenticate against an XMLRPC server (python example
server in test/authserver.py
REFER : the transfer request (REFER) sent out has as user part of
the URI the original user part, a plus sign, and the entered
PIN. The PIN can thus be verified by the proxy handling the
transfer REFER.
"Transfer" REFER:
The "Transfer REFER" is a proprietary REFER call flow which transfers a
SIP dialog and session to another user agent ('taker'). If the transfer
REFER is accepted, the one transfering the call just "forgets" the dialog
and associated session, while the taker can send a re-Invite, thus overtaking
the dialog and session. For this to work, both transferer and taker must
be behind the same record routing proxy, and the callers user agent must
properly support re-Invite (updating of contact, and session, as specified
in RFC3261).
The transfer request sent out has two headers, which are needed by the
entity taking the call:
P-Transfer-RR : route set of the call
P-Transfer-NH : next hop
Loading…
Cancel
Save