some extensions to ivr

* new methods onSipRequest/onSipReply, the whole AmSipReply/AmSipRequest structure is passed to python
SipDialog
 * state is changed only on reply to INVITE, not other requests 
* made pin_collect work


git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@189 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 20 years ago
parent 17530b75bd
commit 14489dd125

@ -101,7 +101,7 @@ AmSession* EarlyAnnounceFactory::onInvite(const AmSipRequest& req)
{
string announce_path = AnnouncePath;
string announce_file = announce_path + req.domain
+ "/" + req.user + ".wav";
+ "/" + get_header_param(req.r_uri, "play") + ".wav";
DBG("trying '%s'\n",announce_file.c_str());
if(file_exists(announce_file))

@ -21,6 +21,8 @@
#include "IvrDialogBase.h"
#include "IvrSipDialog.h"
#include "IvrSipRequest.h"
#include "IvrSipReply.h"
#include "IvrAudio.h"
#include "IvrUAC.h"
#include "Ivr.h"
@ -206,6 +208,11 @@ void IvrFactory::import_ivr_builtins()
// IvrDialogBase
import_object(ivr_module,"IvrDialogBase",&IvrDialogBaseType);
// IvrSipRequest
import_object(ivr_module,"IvrSipRequest",&IvrSipRequestType);
// IvrSipReply
import_object(ivr_module,"IvrSipReply",&IvrSipReplyType);
// IvrAudioFile
import_object(ivr_module,"IvrAudioFile",&IvrAudioFileType);
@ -469,6 +476,15 @@ int IvrDialog::transfer(const string& target)
return dlg.transfer(target);
}
int IvrDialog::drop()
{
int res = dlg.drop();
if (res)
setStopped();
return res;
}
/**
* Load a script using user name from URI.
* Note: there is no default script.
@ -633,6 +649,18 @@ void IvrDialog::onOtherReply(const AmSipReply& r)
AmB2BSession::onOtherReply(r);
}
void IvrDialog::onSipReply(const AmSipReply& r) {
AmSipReply* rep_cpy = new AmSipReply(r);
callPyEventHandler("onSipReply","O",IvrSipReply_FromPtr(rep_cpy));
AmB2BSession::onSipReply(r);
}
void IvrDialog::onSipRequest(const AmSipRequest& r){
AmSipRequest* req_cpy = new AmSipRequest(r);
callPyEventHandler("onSipRequest","O", IvrSipRequest_FromPtr(req_cpy));
AmB2BSession::onSipRequest(r);
}
void IvrDialog::process(AmEvent* event)
{
DBG("IvrDialog::process\n");

@ -132,6 +132,7 @@ public:
void setPyPtrs(PyObject *mod, PyObject *dlg);
int transfer(const string& target);
int drop();
void onSessionStart(const AmSipRequest& req);
void onBye(const AmSipRequest& req);
@ -139,6 +140,10 @@ public:
void onOtherBye(const AmSipRequest& req);
void onOtherReply(const AmSipReply& r);
void onSipReply(const AmSipReply& r);
void onSipRequest(const AmSipRequest& r);
};
#endif

@ -145,6 +145,15 @@ static PyObject* IvrDialogBase_stopSession(IvrDialogBase* self, PyObject*)
return Py_None;
}
static PyObject* IvrDialogBase_dropSession(IvrDialogBase* self, PyObject*)
{
assert(self->p_dlg);
self->p_dlg->drop();
self->p_dlg->postEvent(0);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* IvrDialogBase_bye(IvrDialogBase* self, PyObject*)
{
assert(self->p_dlg);
@ -434,6 +443,9 @@ static PyMethodDef IvrDialogBase_methods[] = {
{"redirect", (PyCFunction)IvrDialogBase_redirect, METH_VARARGS,
"Refers the remote party to some third party."
},
{"dropSession", (PyCFunction)IvrDialogBase_dropSession, METH_NOARGS,
"Drop the session and forget it without replying"
},
// Media control
{"enqueue", (PyCFunction)IvrDialogBase_enqueue, METH_VARARGS,
"Add some audio to the queue (mostly IvrAudioFile)"

@ -67,6 +67,20 @@ def_IvrSipDialog_GETTER(IvrSipDialog_getlocal_party, local_party)
def_IvrSipDialog_GETTER(IvrSipDialog_getroute, getRoute())
def_IvrSipDialog_GETTER(IvrSipDialog_getnext_hop, next_hop)
#define def_IvrSipDialog_SETTER(setter_name, attr) \
static int \
setter_name(IvrSipDialog *self, PyObject* value, void *closure) \
{ \
char* text; \
if(!PyArg_Parse(value,"s",&text))\
return -1;\
\
self->p_dlg->attr = text; \
return 0; \
}
def_IvrSipDialog_SETTER(IvrSipDialog_setremote_uri, remote_uri)
// static PyObject*
// IvrSipDialog_getuser(IvrSipDialog *self, void *closure)
// {
@ -85,7 +99,7 @@ static PyGetSetDef IvrSipDialog_getset[] = {
{"sip_ip", (getter)IvrSipDialog_getsip_ip, NULL, "destination IP of first received message", NULL},
{"sip_port", (getter)IvrSipDialog_getsip_port, NULL, "optional: SIP port", NULL},
{"local_uri", (getter)IvrSipDialog_getlocal_uri, NULL, "local uri", NULL},
{"remote_uri", (getter)IvrSipDialog_getremote_uri, NULL, "remote uri", NULL},
{"remote_uri", (getter)IvrSipDialog_getremote_uri, (setter)IvrSipDialog_setremote_uri, "remote uri", NULL},
{"contact_uri", (getter)IvrSipDialog_getcontact_uri, NULL, "pre-calculated contact uri", NULL},
{"callid", (getter)IvrSipDialog_getcallid, NULL, "call id", NULL},
{"remote_tag", (getter)IvrSipDialog_getremote_tag, NULL, "remote tag", NULL},

@ -0,0 +1,174 @@
/*
* $Id: IvrSipReply.cpp,v 1.15.2.1 2005/09/02 13:47:46 sayer Exp $
*
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "IvrSipReply.h"
#include "log.h"
// Data definition
typedef struct {
PyObject_HEAD
AmSipReply* p_req;
} IvrSipReply;
// Constructor
static PyObject* IvrSipReply_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"ivr_req", NULL};
IvrSipReply *self;
self = (IvrSipReply *)type->tp_alloc(type, 0);
if (self != NULL) {
PyObject* o_req = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &o_req)){
Py_DECREF(self);
return NULL;
}
if (!PyCObject_Check(o_req)){
Py_DECREF(self);
return NULL;
}
self->p_req = (AmSipReply*)PyCObject_AsVoidPtr(o_req);
}
DBG("IvrSipReply_new\n");
return (PyObject *)self;
}
// static void
// IvrSipRequest_dealloc(IvrSipRequest* self)
// {
// self->ob_type->tp_free((PyObject*)self);
// }
#define def_IvrSipReply_GETTER(getter_name, attr) \
static PyObject* \
getter_name(IvrSipReply *self, void *closure) \
{ \
return PyString_FromString(self->p_req->attr.c_str()); \
} \
def_IvrSipReply_GETTER(IvrSipReply_getreason, reason)
def_IvrSipReply_GETTER(IvrSipReply_getnext_request_uri, next_request_uri)
def_IvrSipReply_GETTER(IvrSipReply_gethdrs, hdrs)
def_IvrSipReply_GETTER(IvrSipReply_getremote_tag, remote_tag)
def_IvrSipReply_GETTER(IvrSipReply_getlocal_tag, local_tag)
def_IvrSipReply_GETTER(IvrSipReply_getroute, route)
def_IvrSipReply_GETTER(IvrSipReply_getnext_hop, next_hop)
def_IvrSipReply_GETTER(IvrSipReply_getbody, body)
// static PyObject*
// IvrSipReply_getuser(IvrSipReply *self, void *closure)
// {
// return PyString_FromString(self->p_req->user.c_str());
// }
static PyObject*
IvrSipReply_getcseq(IvrSipReply *self, void *closure)
{
return PyInt_FromLong(self->p_req->cseq);
}
static PyObject*
IvrSipReply_getcode(IvrSipReply *self, void *closure)
{
return PyInt_FromLong(self->p_req->code);
}
static PyGetSetDef IvrSipReply_getset[] = {
{"code", (getter)IvrSipReply_getcode, NULL, "code", NULL},
{"reason", (getter)IvrSipReply_getreason, NULL, "reason", NULL},
{"next_request_uri", (getter)IvrSipReply_getnext_request_uri, NULL, "next_request_uri", NULL},
{"next_hop", (getter)IvrSipReply_getnext_hop, NULL, "next_hop", NULL},
{"route", (getter)IvrSipReply_getroute, NULL, "route", NULL},
{"hdrs", (getter)IvrSipReply_gethdrs, NULL, "hdrs", NULL},
{"body", (getter)IvrSipReply_getbody, NULL, "body", NULL},
{"remote_tag", (getter)IvrSipReply_getremote_tag, NULL, "remote_tag", NULL},
{"local_tag", (getter)IvrSipReply_getlocal_tag, NULL, "local_tag", NULL},
{"cseq", (getter)IvrSipReply_getcseq, NULL, "CSeq for next request", NULL},
{NULL} /* Sentinel */
};
PyTypeObject IvrSipReplyType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"ivr.IvrSipReply", /*tp_name*/
sizeof(IvrSipReply), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Wrapper class for AmSipReply", /*tp_doc*/
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
IvrSipReply_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
IvrSipReply_new, /* tp_new */
};
PyObject* IvrSipReply_FromPtr(AmSipReply* req)
{
PyObject* c_req = PyCObject_FromVoidPtr(req,NULL);
PyObject* args = Py_BuildValue("(O)",c_req);
PyObject* py_req = IvrSipReply_new(&IvrSipReplyType,args,NULL);
Py_DECREF(args);
Py_DECREF(c_req);
return py_req;
}

@ -0,0 +1,34 @@
/*
* $Id: IvrSipReply.cpp,v 1.15.2.1 2005/09/02 13:47:46 sayer Exp $
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef IvrSipReply_h
#define IvrSipReply_h
// Python stuff
#include <Python.h>
#include "structmember.h"
#include "AmSipReply.h"
extern PyTypeObject IvrSipReplyType;
PyObject* IvrSipReply_FromPtr(AmSipReply* req);
#endif

@ -1,8 +1,29 @@
/*
* $Id$
* Copyright (C) 2002-2003 Fhg Fokus
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "IvrSipRequest.h"
//#include "AmSessionTimer.h"
#include "AmSipRequest.h"
#include "log.h"
#if 0
// Data definition
typedef struct {
@ -53,21 +74,27 @@ getter_name(IvrSipRequest *self, void *closure) \
return PyString_FromString(self->p_req->attr.c_str()); \
} \
def_IvrSipRequest_GETTER(IvrSipRequest_getmethod, method)
def_IvrSipRequest_GETTER(IvrSipRequest_getuser, user)
def_IvrSipRequest_GETTER(IvrSipRequest_getdomain, domain)
def_IvrSipRequest_GETTER(IvrSipRequest_getsip_ip, sip_ip)
def_IvrSipRequest_GETTER(IvrSipRequest_getsip_port, sip_port)
def_IvrSipRequest_GETTER(IvrSipRequest_getlocal_uri, local_uri)
def_IvrSipRequest_GETTER(IvrSipRequest_getremote_uri, remote_uri)
def_IvrSipRequest_GETTER(IvrSipRequest_getcontact_uri, contact_uri)
def_IvrSipRequest_GETTER(IvrSipRequest_getdstip, dstip)
def_IvrSipRequest_GETTER(IvrSipRequest_getport, port)
def_IvrSipRequest_GETTER(IvrSipRequest_getr_uri, r_uri)
def_IvrSipRequest_GETTER(IvrSipRequest_getfrom_uri, from_uri)
def_IvrSipRequest_GETTER(IvrSipRequest_getfrom, from)
def_IvrSipRequest_GETTER(IvrSipRequest_getto, to)
def_IvrSipRequest_GETTER(IvrSipRequest_getcallid, callid)
def_IvrSipRequest_GETTER(IvrSipRequest_getremote_tag, remote_tag)
def_IvrSipRequest_GETTER(IvrSipRequest_getlocal_tag, local_tag)
def_IvrSipRequest_GETTER(IvrSipRequest_getremote_party, remote_party)
def_IvrSipRequest_GETTER(IvrSipRequest_getlocal_party, local_party)
def_IvrSipRequest_GETTER(IvrSipRequest_getfrom_tag, from_tag)
def_IvrSipRequest_GETTER(IvrSipRequest_getto_tag, to_tag)
def_IvrSipRequest_GETTER(IvrSipRequest_getroute, route)
def_IvrSipRequest_GETTER(IvrSipRequest_getnext_hop, next_hop)
def_IvrSipRequest_GETTER(IvrSipRequest_getkey, key)
def_IvrSipRequest_GETTER(IvrSipRequest_getbody, body)
// static PyObject*
// IvrSipRequest_getuser(IvrSipRequest *self, void *closure)
// {
@ -81,21 +108,26 @@ IvrSipRequest_getcseq(IvrSipRequest *self, void *closure)
}
static PyGetSetDef IvrSipRequest_getset[] = {
{"user", (getter)IvrSipRequest_getuser, NULL, "local user", NULL},
{"domain", (getter)IvrSipRequest_getdomain, NULL, "local domain", NULL},
{"sip_ip", (getter)IvrSipRequest_getsip_ip, NULL, "destination IP of first received message", NULL},
{"sip_port", (getter)IvrSipRequest_getsip_port, NULL, "optional: SIP port", NULL},
{"local_uri", (getter)IvrSipRequest_getlocal_uri, NULL, "local uri", NULL},
{"remote_uri", (getter)IvrSipRequest_getremote_uri, NULL, "remote uri", NULL},
{"contact_uri", (getter)IvrSipRequest_getcontact_uri, NULL, "pre-calculated contact uri", NULL},
{"callid", (getter)IvrSipRequest_getcallid, NULL, "call id", NULL},
{"remote_tag", (getter)IvrSipRequest_getremote_tag, NULL, "remote tag", NULL},
{"local_tag", (getter)IvrSipRequest_getlocal_tag, NULL, "local tag", NULL},
{"remote_party",(getter)IvrSipRequest_getremote_party, NULL, "To/From", NULL},
{"local_party", (getter)IvrSipRequest_getlocal_party, NULL, "To/From", NULL},
{"method", (getter)IvrSipRequest_getmethod, NULL, "method", NULL},
{"user", (getter)IvrSipRequest_getuser, NULL, "local user", NULL},
{"domain", (getter)IvrSipRequest_getdomain, NULL, "local domain", NULL},
{"dstip", (getter)IvrSipRequest_getdstip, NULL, "dstip", NULL},
{"port", (getter)IvrSipRequest_getport, NULL, "port", NULL},
{"r_uri", (getter)IvrSipRequest_getr_uri, NULL, "port", NULL},
{"from_uri", (getter)IvrSipRequest_getfrom_uri, NULL, "port", NULL},
{"from", (getter)IvrSipRequest_getfrom, NULL, "port", NULL},
{"to", (getter)IvrSipRequest_getto, NULL, "port", NULL},
{"callid", (getter)IvrSipRequest_getcallid, NULL, "call id", NULL},
{"from_tag", (getter)IvrSipRequest_getfrom_tag, NULL, "remote tag", NULL},
{"to_tag", (getter)IvrSipRequest_getto_tag, NULL, "local tag", NULL},
{"route", (getter)IvrSipRequest_getroute, NULL, "record routing", NULL},
{"next_hop", (getter)IvrSipRequest_getnext_hop, NULL, "next_hop for t_uac_dlg", NULL},
{"cseq", (getter)IvrSipRequest_getcseq, NULL, "CSeq for next request", NULL},
{"key", (getter)IvrSipRequest_getkey, NULL, "CSeq for next request", NULL},
{"body", (getter)IvrSipRequest_getbody, NULL, "CSeq for next request", NULL},
{NULL} /* Sentinel */
};
@ -142,4 +174,16 @@ PyTypeObject IvrSipRequestType = {
IvrSipRequest_new, /* tp_new */
};
#endif
PyObject* IvrSipRequest_FromPtr(AmSipRequest* req)
{
PyObject* c_req = PyCObject_FromVoidPtr(req,NULL);
PyObject* args = Py_BuildValue("(O)",c_req);
PyObject* py_req = IvrSipRequest_new(&IvrSipRequestType,args,NULL);
Py_DECREF(args);
Py_DECREF(c_req);
return py_req;
}

@ -1,3 +1,25 @@
/*
* $Id$
* Copyright (C) 2002-2003 Fhg Fokus
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef IvrSipRequest_h
#define IvrSipRequest_h
@ -5,6 +27,9 @@
#include <Python.h>
#include "structmember.h"
#include "AmSipRequest.h"
extern PyTypeObject IvrSipRequestType;
PyObject* IvrSipRequest_FromPtr(AmSipRequest* req);
#endif

@ -1,9 +1,10 @@
from log import *
from ivr import *
collect = 0
connect = 1
connected = 2
collect = 0
connect = 1
connect_failed = 2
HINT_TIMER = 1
HINT_TIMEOUT = 10 # seconds until hint msg is played
@ -22,6 +23,9 @@ class IvrDialog(IvrDialogBase):
auth_fail_msg = None
pin_msg = None
transfer_cseq = None
dlg_remote_uri = None
state = collect
keys = ''
@ -73,15 +77,35 @@ class IvrDialog(IvrDialogBase):
elif key == 10:
self.state = connect
self.removeTimer(HINT_TIMER)
self.redirect("sip:" + self.dialog.user + \
self.keys + "@" + \
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)
self.stopSession()
def onEmptyQueue(self):
if self.state == collect:
self.setTimer(HINT_TIMER, HINT_TIMEOUT)
elif self.state == connect_failed:
debug("transfer failed. stopping session.")
debug("restoring remote_uri to " + self.dlg_remote_uri)
self.dialog.remote_uri = self.dlg_remote_uri
self.bye()
self.stopSession()
def onTimer(self, id):
if id == HINT_TIMER and self.state == collect:
self.enqueue(self.pin_msg, None)
def onSipReply(self, reply):
if reply.cseq == self.transfer_cseq:
# restore remote uri of dialog
if reply.code >= 200 and reply.code < 300:
debug("received positive reply to transfer request. dropping session.")
self.dropSession()
elif reply.code >= 300:
debug("transfer failed. notifying user")
self.state = connect_failed
self.fail_msg = IvrAudioFile()
self.fail_msg.open(config['fail_msg'],AUDIO_READ)
self.enqueue(self.fail_msg,None)

@ -48,6 +48,11 @@ AmSessionFactory::AmSessionFactory(const string& name)
{
}
AmSession* AmSessionFactory::onRefer(const AmSipRequest& req)
{
throw AmSession::Exception(488,"Not accepted here");
}
int AmSessionFactory::configureModule(AmConfigReader& cfg) {
return mod_conf.readFromConfig(cfg);
}

@ -144,6 +144,16 @@ public:
*/
virtual AmSession* onInvite(const AmSipRequest& req)=0;
/**
* Creates a dialog state on new REFER with local-tag.
* @return 0 if the request is not acceptable.
*
* Warning:
* This method should not make any expensive
* processing as it would block the server.
*/
virtual AmSession* onRefer(const AmSipRequest& req);
/**
* method to receive an Event that is posted
* to the factory

@ -309,47 +309,47 @@ void AmRequestHandler::dispatch(AmSipRequest& req)
sess_exists = sess_cont->postEvent(local_tag,ev);
if(!sess_exists){
if(req.method == "INVITE"){
sess_cont->startSessionUAS(req);
} else if(req.method == "REFER"){
// Out-of-dialog REFER
AmSipRequest n_req;
n_req.method = "INVITE";
n_req.dstip = AmConfig::LocalIP;
n_req.from = req.to;
n_req.from_uri = req.r_uri;
n_req.from_tag = AmSession::getNewId();
n_req.user = req.user;
n_req.r_uri = uri_from_name_addr(getHeader(req.hdrs, "Refer-To"));
n_req.to = getHeader(req.hdrs, "Refer-To");
n_req.to_tag = "";
n_req.cmd = req.cmd; // application from REFER
n_req.callid = AmSession::getNewId() + "@" + AmConfig::LocalIP;
if (AmSessionContainer::instance()->startSessionUAC(n_req)
!= NULL)
AmSipDialog::reply_error(req,202,"Accepted");
else
AmSipDialog::reply_error(req,500,"Not supported here");
} else {
if(!local_tag.empty() || req.method == "CANCEL"){
AmSipDialog::reply_error(req,481,"Call leg/Transaction does not exist");
}
else {
//TODO: reply some 4xx.
ERROR("sorry, we don't support beginning a new session with a '%s' message\n",
req.method.c_str());
AmSipDialog::reply_error(req,500,"Not supported here");
return;
}
}
if((req.method == "INVITE")||
((req.method == "REFER") && !local_tag.empty())){
sess_cont->startSessionUAS(req);
} else if(req.method == "REFER"){
// Out-of-dialog REFER
AmSipRequest n_req;
n_req.method = "INVITE";
n_req.dstip = AmConfig::LocalIP;
n_req.from = req.to;
n_req.from_uri = req.r_uri;
n_req.from_tag = AmSession::getNewId();
n_req.user = req.user;
n_req.r_uri = uri_from_name_addr(getHeader(req.hdrs, "Refer-To"));
n_req.to = getHeader(req.hdrs, "Refer-To");
n_req.to_tag = "";
n_req.cmd = req.cmd; // application from REFER
n_req.callid = AmSession::getNewId() + "@" + AmConfig::LocalIP;
if (AmSessionContainer::instance()->startSessionUAC(n_req)
!= NULL)
AmSipDialog::reply_error(req,202,"Accepted");
else
AmSipDialog::reply_error(req,500,"Not supported here");
} else {
if(!local_tag.empty() || req.method == "CANCEL"){
AmSipDialog::reply_error(req,481,"Call leg/Transaction does not exist");
}
else {
//TODO: reply some 4xx.
ERROR("sorry, we don't support beginning a new session with a '%s' message\n",
req.method.c_str());
AmSipDialog::reply_error(req,500,"Not supported here");
return;
}
}
}
}

@ -286,7 +286,7 @@ void AmSession::run()
(dlg.getStatus() == AmSipDialog::Disconnecting)// ||
// (dlg.getUACTransPending())
){
waitForEvent();
processEvents();

@ -334,7 +334,14 @@ AmSession* AmSessionContainer::createSession(AmSipRequest& req)
throw string("application '" + plugin_name + "' not found !");
}
AmSession* session = state_factory->onInvite(req);
AmSession* session = 0;
if (req.method == "INVITE")
session = state_factory->onInvite(req);
else if (req.method == "REFER")
session = state_factory->onRefer(req);
if(!session) {
// State creation failed:
// application denied session creation

@ -180,8 +180,9 @@ void AmSipDialog::updateStatus(const AmSipReply& reply)
case Pending:
case Disconnected:
if(t.method != "BYE"){
// only change status of dialog if reply
// to INVITE received
if(t.method == "INVITE"){
if(reply.code < 200)
status = Pending;
else if(reply.code >= 300)
@ -615,3 +616,9 @@ void AmSipDialog::setRoute(const string& n_route)
m_route = "";
}
}
int AmSipDialog::drop()
{
status = Disconnected;
return 1;
}

@ -143,6 +143,7 @@ public:
const string& body);
int refer(const string& refer_to);
int transfer(const string& target);
int drop();
/**
* @return true if a transaction could be found that

Loading…
Cancel
Save