diff --git a/apps/Makefile b/apps/Makefile index c08285db..38f33769 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -1,7 +1,7 @@ COREPATH ?= ../core include $(COREPATH)/Makefile.defs -exclude_modules = +exclude_modules = mp3 modules = $(filter-out $(exclude_modules) \ $(wildcard Makefile*) CVS, \ $(wildcard *) ) diff --git a/apps/conf_auth/conf_auth.py b/apps/conf_auth/conf_auth.py index a32e2d18..836097d9 100644 --- a/apps/conf_auth/conf_auth.py +++ b/apps/conf_auth/conf_auth.py @@ -74,6 +74,7 @@ class IvrDialog(IvrDialogBase): def onDtmf(self,key,duration): if self.state == collect: + self.flush() if key == 10: c = xmlrpclib.ServerProxy(server_path ) @@ -91,11 +92,12 @@ class IvrDialog(IvrDialogBase): self.state = connect self.removeTimer(HINT_TIMER) else: + self.keys = '' self.auth_fail_msg = IvrAudioFile() self.auth_fail_msg.open(erg[1], ivr.AUDIO_READ) - self.flush() + #self.flush() self.enqueue(self.auth_fail_msg, None) - self.keys = '' + self.setTimer(HINT_TIMER, HINT_TIMEOUT) else: self.keys += str(key) @@ -109,7 +111,8 @@ class IvrDialog(IvrDialogBase): self.setRelayonly() self.connectCallee(self.conf_to, self.conf_uri) self.state = connected - self.setTimer(CONF_TIMER, self.conf_duration) + if (self.conf_duration > 0): + self.setTimer(CONF_TIMER, self.conf_duration) elif self.state == collect: self.setTimer(HINT_TIMER, HINT_TIMEOUT) @@ -118,6 +121,7 @@ class IvrDialog(IvrDialogBase): if id == HINT_TIMER and self.state == collect: self.enqueue(self.hint_msg, None) elif id == CONF_TIMER and self.state == connected: + debug("conference timer timeout. disconnecting " + self.conf_to + " uri: " + self.conf_uri) self.terminateOtherLeg() self.bye() self.stopSession() diff --git a/apps/conference/AmRingTone.cpp b/apps/conference/AmRingTone.cpp new file mode 100644 index 00000000..7e91caca --- /dev/null +++ b/apps/conference/AmRingTone.cpp @@ -0,0 +1,59 @@ +#include "AmRingTone.h" +#include + +#include "log.h" + +#define PI 3.14159 + +AmRingTone::AmRingTone(int length, int on, int off, int f, int f2) + : AmAudio(), + length(length), + on_period(on), + off_period(off), + freq(f),freq2(f2) +{} + +AmRingTone::~AmRingTone() +{} + +int AmRingTone::read(unsigned int user_ts, unsigned int size) +{ + int t = user_ts % ((on_period + off_period)<<3); + + if(length < 0) + return -1; + + if(t >= on_period<<3){ + + memset((unsigned char*)samples,0,size); + + return size; + } + + short* s = (short*)((unsigned char*)samples); + for(unsigned int i=0; i dial out will not be available\n"); - } + //RingTone = cfg.getParameter("ring_tone"); + +// DialoutSuffix = cfg.getParameter("dialout_suffix"); +// if(DialoutSuffix.empty()){ +// WARN("No dialout_suffix has been configured in the conference plug-in:\n"); +// WARN("\t -> dial out will not be available\n"); +// } return 0; } @@ -84,13 +86,28 @@ AmSession* ConferenceFactory::onInvite(const AmSipRequest& req) return new ConferenceDialog(req.user); } +AmSession* ConferenceFactory::onRefer(const AmSipRequest& req) +{ + if(req.to_tag.empty()) + throw AmSession::Exception(488,"Not accepted here"); + + AmSession* s = new ConferenceDialog(req.user); + s->dlg.local_tag = req.from_tag; + + + DBG("ConferenceFactory::onRefer: local_tag = %s\n",s->dlg.local_tag.c_str()); + + return s; +} + ConferenceDialog::ConferenceDialog(const string& conf_id, AmConferenceChannel* dialout_channel) : conf_id(conf_id), channel(0), play_list(this), dialout_channel(dialout_channel), - state(CS_normal) + state(CS_normal), + allow_dialout(false) { dialedout = this->dialout_channel.get() != 0; rtp_str.setAdaptivePlayout(true); @@ -107,14 +124,16 @@ void ConferenceDialog::onStart() void ConferenceDialog::onSessionStart(const AmSipRequest& req) { - setupAudio(); -} + allow_dialout = (getHeader(req.hdrs,"P-Dialout") == "yes"); -void ConferenceDialog::onSessionStart(const AmSipReply& reply) -{ setupAudio(); } +// void ConferenceDialog::onSessionStart(const AmSipReply& reply) +// { +// setupAudio(); +// } + void ConferenceDialog::setupAudio() { if(!ConferenceFactory::JoinSound.empty()) { @@ -133,10 +152,19 @@ void ConferenceDialog::setupAudio() DropSound.reset(0); } +// if(!ConferenceFactory::RingTone.empty()) { +// RingTone.reset(new AmAudioFile()); +// if(RingTone->open(ConferenceFactory::RingTone, +// AmAudioFile::Read)) +// RingTone.reset(0); +// } + + play_list.close();// !!! if(dialout_channel.get()){ + DBG("adding dialout_channel to the playlist (dialedout = %i)\n",dialedout); play_list.addToPlaylist(new AmPlaylistItem(dialout_channel.get(), dialout_channel.get())); } @@ -238,13 +266,41 @@ void ConferenceDialog::process(AmEvent* ev) case DoConfDisconnect: + DBG("****** Caller received DoConfDisconnect *******\n"); connectMainChannel(); + state = CS_normal; break; case DoConfConnect: state = CS_dialout_connected; + + play_list.close(); // !!! + play_list.addToPlaylist(new AmPlaylistItem(dialout_channel.get(), + dialout_channel.get())); + break; + + case DoConfRinging: + + if(!RingTone.get()) + RingTone.reset(new AmRingTone(0,2000,4000,440,480)); // US + + DBG("adding ring tone to the playlist (dialedout = %i)\n",dialedout); + play_list.close(); + play_list.addToPlaylist(new AmPlaylistItem(RingTone.get(),NULL)); + break; + + case DoConfError: + + DBG("****** Caller received DoConfError *******\n"); + if(!ErrorTone.get()) + ErrorTone.reset(new AmRingTone(2000,250,250,440,480)); + + DBG("adding error tone to the playlist (dialedout = %i)\n",dialedout); + //play_list.close(); + play_list.addToPlayListFront(new AmPlaylistItem(ErrorTone.get(),NULL)); break; + } } @@ -269,15 +325,17 @@ string dtmf2str(int event) } } + void ConferenceDialog::onDtmf(int event, int duration) { - DBG("ConferenceDialog::onDtmf, state = %d\n", state); - if(dialedout) + DBG("ConferenceDialog::onDtmf\n"); + if(dialedout || !allow_dialout) return; switch(state){ case CS_normal: + DBG("CS_normal\n"); dtmf_seq += dtmf2str(event); if(dtmf_seq.length() == 2){ @@ -288,16 +346,17 @@ void ConferenceDialog::onDtmf(int event, int duration) break; case CS_dialing_out:{ + DBG("CS_dialing_out\n"); string digit = dtmf2str(event); if(digit == "*"){ if(!dtmf_seq.empty()){ - createDialoutParticipant("sip:" + dtmf_seq + - ConferenceFactory::DialoutSuffix); + createDialoutParticipant(dtmf_seq); state = CS_dialed_out; } else { + DBG("state = CS_normal; ????????\n"); state = CS_normal; } @@ -310,6 +369,7 @@ void ConferenceDialog::onDtmf(int event, int duration) case CS_dialout_connected: + DBG("CS_dialout_connected\n"); if(event == 10){ // '*' AmSessionContainer::instance() @@ -319,17 +379,11 @@ void ConferenceDialog::onDtmf(int event, int duration) connectMainChannel(); state = CS_normal; - - } else if(event == 11){ // '#' - - disconnectDialout(); - state = CS_normal; } - break; case CS_dialed_out: + DBG("CS_dialed_out\n"); if(event == 11){ // '#' - disconnectDialout(); state = CS_normal; } @@ -338,8 +392,10 @@ void ConferenceDialog::onDtmf(int event, int duration) } } -void ConferenceDialog::createDialoutParticipant(const string& uri) +void ConferenceDialog::createDialoutParticipant(const string& uri_user) { + string uri = "sip:" + uri_user + "@" + dlg.domain; + dialout_channel.reset(AmConferenceStatus::getChannel(getLocalTag(),getLocalTag())); dialout_id = AmSession::getNewId(); @@ -363,11 +419,6 @@ void ConferenceDialog::createDialoutParticipant(const string& uri) dialout_session->sdp.genRequest(AmConfig::LocalIP,local_port,body); dialout_dlg.sendRequest("INVITE","application/sdp",body,""); - - play_list.close(); // !!! - play_list.addToPlaylist(new AmPlaylistItem(dialout_channel.get(), - dialout_channel.get())); - dialout_session->start(); AmSessionContainer* sess_cont = AmSessionContainer::instance(); @@ -392,6 +443,7 @@ void ConferenceDialog::disconnectDialout() ->postEvent(dialout_id, new DialoutConfEvent(DoConfDisconnect, getLocalTag())); + connectMainChannel(); } } @@ -399,6 +451,7 @@ void ConferenceDialog::disconnectDialout() void ConferenceDialog::connectMainChannel() { dialout_id = ""; + dialedout = false; dialout_channel.reset(NULL); play_list.close(); @@ -420,11 +473,46 @@ void ConferenceDialog::closeChannels() dialout_channel.reset(NULL); } +void ConferenceDialog::onSipRequest(const AmSipRequest& req) +{ + AmSession::onSipRequest(req); + if((dlg.getStatus() >= AmSipDialog::Connected) || + (req.method != "REFER")) + return; + + std::swap(dlg.local_party,dlg.remote_party); + dlg.remote_tag = ""; + + dlg.setRoute(getHeader(req.hdrs,"P-Transfer-RR")); + dlg.next_hop = getHeader(req.hdrs,"P-Transfer-NH"); + + DBG("ConferenceDialog::onSipRequest: local_party = %s\n",dlg.local_party.c_str()); + DBG("ConferenceDialog::onSipRequest: local_tag = %s\n",dlg.local_tag.c_str()); + DBG("ConferenceDialog::onSipRequest: remote_party = %s\n",dlg.remote_party.c_str()); + DBG("ConferenceDialog::onSipRequest: remote_tag = %s\n",dlg.remote_tag.c_str()); + + string body; + int local_port = rtp_str.getLocalPort(); + sdp.genRequest(AmConfig::LocalIP,local_port,body); + dlg.sendRequest("INVITE","application/sdp",body,""); + + transfer_req.reset(new AmSipRequest(req)); + + return; +} + void ConferenceDialog::onSipReply(const AmSipReply& reply) { int status = dlg.getStatus(); AmSession::onSipReply(reply); + + DBG("ConferenceDialog::onSipReply: code = %i, reason = %s\n, status = %i", + reply.code,reply.reason.c_str(),dlg.getStatus()); + if(!dialedout && + !transfer_req.get()) + return; + if(status < AmSipDialog::Connected){ switch(dlg.getStatus()){ @@ -432,40 +520,90 @@ void ConferenceDialog::onSipReply(const AmSipReply& reply) case AmSipDialog::Connected: // connected! - if(acceptAudio(reply.body,reply.hdrs)){ - ERROR("could not connect audio!!!\n"); - dlg.bye(); - setStopped(); - } - else { + try { + + acceptAudio(reply.body,reply.hdrs); + if(getDetached() && !getStopped()){ - - onSessionStart(reply); - + + setupAudio(); + if(getInput() || getOutput()) AmMediaProcessor::instance()->addSession(this, - getCallgroup()); + getCallgroup()); else { - ERROR("missing audio input and/or ouput.\n"); + ERROR("missing audio input and/or ouput.\n"); + return; + } + + if(!transfer_req.get()){ + + // send connect event + AmSessionContainer::instance() + ->postEvent(dialout_channel->getConfID(), + new DialoutConfEvent(DoConfConnect, + dialout_channel->getConfID())); + } + else { + dlg.reply(*(transfer_req.get()),202,"Accepted"); + transfer_req.reset(0); + connectMainChannel(); } - - // send connect event - AmSessionContainer::instance() - ->postEvent(dialout_channel->getConfID(), - new DialoutConfEvent(DoConfConnect, - dialout_channel->getConfID())); } + + } + catch(const AmSession::Exception& e){ + ERROR("%i %s\n",e.code,e.reason.c_str()); + dlg.bye(); + setStopped(); } break; case AmSipDialog::Pending: switch(reply.code){ - case 180: break;//TODO: local ring tone. + case 180: + + // send ringing event + AmSessionContainer::instance() + ->postEvent(dialout_channel->getConfID(), + new DialoutConfEvent(DoConfRinging, + dialout_channel->getConfID())); + + break; case 183: break;//TODO: remote ring tone. default: break;// continue waiting. } + break; + + case AmSipDialog::Disconnected: + + if(!transfer_req.get()){ + + disconnectDialout(); + //switch(reply.code){ + //default: + + AmSessionContainer::instance() + ->postEvent(dialout_channel->getConfID(), + new DialoutConfEvent(DoConfError, + dialout_channel->getConfID())); + //} + } + else { + + dlg.reply(*(transfer_req.get()),reply.code,reply.reason); + transfer_req.reset(0); + setStopped(); + } + break; + + + + default: break; } + + } } diff --git a/apps/conference/Conference.h b/apps/conference/Conference.h index c815c1e6..9aab5c18 100644 --- a/apps/conference/Conference.h +++ b/apps/conference/Conference.h @@ -33,6 +33,7 @@ #include "AmSession.h" #include "AmConferenceChannel.h" #include "AmPlaylist.h" +#include "AmRingTone.h" #include #include @@ -42,14 +43,17 @@ using std::string; class ConferenceStatus; class ConferenceStatusContainer; - + enum { CS_normal=0, CS_dialing_out, CS_dialed_out, CS_dialout_connected }; enum { DoConfConnect = 100, - DoConfDisconnect }; + DoConfDisconnect, + DoConfRinging, + DoConfError +}; struct DialoutConfEvent : public AmEvent { @@ -61,7 +65,7 @@ struct DialoutConfEvent : public AmEvent { conf_id(conf_id) {} }; - + class ConferenceFactory : public AmSessionFactory { public: @@ -69,9 +73,11 @@ public: static string JoinSound; static string DropSound; static string DialoutSuffix; + //static string RingTone; ConferenceFactory(const string& _app_name); virtual AmSession* onInvite(const AmSipRequest&); + virtual AmSession* onRefer(const AmSipRequest& req); virtual int onLoad(); }; @@ -82,6 +88,8 @@ class ConferenceDialog : public AmSession auto_ptr LonelyUserFile; auto_ptr JoinSound; auto_ptr DropSound; + auto_ptr RingTone; + auto_ptr ErrorTone; string conf_id; @@ -93,6 +101,10 @@ class ConferenceDialog : public AmSession string dialout_id; auto_ptr dialout_channel; + bool allow_dialout; + + auto_ptr transfer_req; + void createDialoutParticipant(const string& uri); void disconnectDialout(); @@ -109,10 +121,10 @@ public: void process(AmEvent* ev); void onStart(); void onDtmf(int event, int duration); - void onSessionStart(const AmSipReply& reply); void onSessionStart(const AmSipRequest& req); void onBye(const AmSipRequest& req); + void onSipRequest(const AmSipRequest& req); void onSipReply(const AmSipReply& reply); }; diff --git a/apps/early_announce/EarlyAnnounce.cpp b/apps/early_announce/EarlyAnnounce.cpp index 9faa0dac..09ffd286 100644 --- a/apps/early_announce/EarlyAnnounce.cpp +++ b/apps/early_announce/EarlyAnnounce.cpp @@ -73,20 +73,27 @@ int EarlyAnnounceFactory::onLoad() void EarlyAnnounceDialog::onInvite(const AmSipRequest& req) { - string sdp_reply; - if(acceptAudio(req.body,req.hdrs,&sdp_reply)!=0) - return; + try { - if(dlg.reply(req,183,"Session Progress", - "application/sdp",sdp_reply) != 0){ + string sdp_reply; + acceptAudio(req.body,req.hdrs,&sdp_reply); - setStopped(); - } - else { + if(dlg.reply(req,183,"Session Progress", + "application/sdp",sdp_reply) != 0){ - localreq = req; - } + throw AmSession::Exception(500,"could not reply"); + } + else { + + localreq = req; + } + + } catch(const AmSession::Exception& e) { + ERROR("%i %s\n",e.code,e.reason.c_str()); + setStopped(); + AmSipDialog::reply_error(req,e.code,e.reason); + } } diff --git a/apps/ivr/IvrAudio.h b/apps/ivr/IvrAudio.h index fa73f4ff..5408cd25 100644 --- a/apps/ivr/IvrAudio.h +++ b/apps/ivr/IvrAudio.h @@ -3,7 +3,7 @@ // Python stuff #include -#include "structmember.h" +#include #include "AmAudio.h" diff --git a/apps/ivr/Makefile b/apps/ivr/Makefile index 8f3cc947..bffc9247 100644 --- a/apps/ivr/Makefile +++ b/apps/ivr/Makefile @@ -1,22 +1,19 @@ - plug_in_name = ivr include Makefile.defs PY_VER = $(PYTHON_VERSION) +PY_EXE = python$(PY_VER) COREPATH ?=../../core -PYTHON_DIR = $(PYTHON_PREFIX)/include/python$(PY_VER) -PYTHON_LIBDIR = $(PYTHON_PREFIX)/lib/python$(PY_VER) +PYTHON_DIR = $(shell $(PY_EXE) ./python_inc.py) +PYTHON_LIBDIR = $(shell $(PY_EXE) ./python_lib.py) # put used Python modules from lib-dynload here, e.g. time, mysql, _cvs.so etc. -PYTHON_DYNLOAD_MODULES = $(wildcard $(PYTHON_LIBDIR)/lib-dynload/*.so) \ - $(wildcard $(PYTHON_LIBDIR)/site-packages/*.so) PYTHON_module_cflags = -I$(PYTHON_DIR) -fno-strict-aliasing PYTHON_module_ldflags = -Xlinker --export-dynamic \ -L$(PYTHON_LIBDIR)/config \ - -lpython$(PY_VER) \ - #$(PYTHON_DYNLOAD_MODULES) + -lpython$(PY_VER) ifeq ($(TTS), y) # diff --git a/apps/ivr/Makefile.defs b/apps/ivr/Makefile.defs index 7e279034..6118fa44 100644 --- a/apps/ivr/Makefile.defs +++ b/apps/ivr/Makefile.defs @@ -1,19 +1,10 @@ # Python version: 2.5, 2.4 or 2.3 # -# PYTHON_VERSION might also be 2.2 -- except for the use of GIL -# do a ls /usr/include/python2.3/Python.h to see if it's there -PYTHON_VERSION = 2.4 -# adjust to point to python include path -# can also be /usr/include/python$(PY_VER) -# look for Python.h in the specified path -# Python prefix is what you configured python with -# if you built from source (e.g. ./configure --with-prefix=/usr/local) -# on debian it's often /usr, on SuSE and FreeBSD /usr/local -PYTHON_PREFIX = /usr/local +PYTHON_VERSION ?= 2.4 # For flite text-to-speech set TTS = y # -TTS = y +TTS ?= n FLITE_DIR = /usr/src/flite-1.2-release ALT_FLITE_DIR = /usr/include/flite diff --git a/apps/ivr/python_inc.py b/apps/ivr/python_inc.py new file mode 100644 index 00000000..e2496dde --- /dev/null +++ b/apps/ivr/python_inc.py @@ -0,0 +1,3 @@ +import distutils.sysconfig + +print distutils.sysconfig.get_python_inc(True) diff --git a/apps/ivr/python_lib.py b/apps/ivr/python_lib.py new file mode 100644 index 00000000..9e6425fc --- /dev/null +++ b/apps/ivr/python_lib.py @@ -0,0 +1,3 @@ +import distutils.sysconfig + +print distutils.sysconfig.get_python_lib(True,True) diff --git a/core/AmSdp.cpp b/core/AmSdp.cpp index 27a3848f..63deaaf1 100644 --- a/core/AmSdp.cpp +++ b/core/AmSdp.cpp @@ -174,6 +174,7 @@ int AmSdp::parse() } telephone_event_pt = findPayload("telephone-event"); + //DBG("telephone_event_pt = %i\n",telephone_event_pt); return ret; } @@ -205,7 +206,7 @@ int AmSdp::genResponse(const string& localip, int localport, payloads += " " + int2str((*it)->payload_type); - if ((*it)->payload_type >= 96) // dynamic payload + //if ((*it)->payload_type >= 96) // dynamic payload options += "a=rtpmap:" + int2str((*it)->payload_type) + " " + (*it)->encoding_name + "/" + int2str((*it)->clock_rate) + "\r\n"; @@ -224,7 +225,7 @@ int AmSdp::genResponse(const string& localip, int localport, + options; if (hasTelephoneEvent()) { - out_buf += "a=rtmap:" + int2str(telephone_event_pt->payload_type) + " " + + out_buf += "a=rtpmap:" + int2str(telephone_event_pt->payload_type) + " " + telephone_event_pt->encoding_name + "/" + int2str(telephone_event_pt->clock_rate) + "\r\n" "a=fmtp:" + int2str(telephone_event_pt->payload_type) + " 0-15\r\n"; @@ -271,12 +272,12 @@ int AmSdp::genRequest(const string& localip,int localport, string& out_buf) for(it = payloads.begin();it != payloads.end();++it) { - if(it->first >= 96) { + //if(it->first >= 96) { out_buf += "a=rtpmap:" + int2str(it->first) + " " + string(it->second->name) + "/" + int2str(it->second->sample_rate) + "\r\n"; - } + //} } return 0; @@ -296,17 +297,26 @@ SdpPayload* AmSdp::getCompatiblePayload(int media_type, string& addr, int& port) vector::iterator it = m_it->payloads.begin(); for(; it != m_it->payloads.end(); ++it ) { - - if(it->payload_type < 96){ // static payload - - if( pi->payload(it->payload_type) ) { + + amci_payload_t* a_pl = NULL; + if(it->payload_type < 96){ + // try static payloads + a_pl = pi->payload(it->payload_type); + } + + if( a_pl ) { - payload = &(*it); - payload->int_pt = payload->payload_type; - goto end; - } + payload = &(*it); + payload->int_pt = a_pl->payload_id; + payload->encoding_name = a_pl->name; + payload->clock_rate = a_pl->sample_rate; + goto end; } - else { // dynamic payload + else { + // Try dynamic payloads + // and give a chance to broken + // implementation using a static payload number + // for dynamic ones. int int_pt = getDynPayload(it->encoding_name, it->clock_rate); @@ -615,13 +625,14 @@ static bool parse_sdp_media(AmSdp* sdp_msg, char*& s, char*& next_line) sdp_msg->media.push_back(m); s = next_line; + DBG("next_line=<%s>\n",next_line); ret = ret // Media title || parse_sdp_line(sdp_msg,s,'i',true,NULL) // connection information - optional if included at session-level || parse_sdp_line(sdp_msg,s,'c',true,parse_sdp_connection) // bandwidth information - || parse_sdp_line(sdp_msg,s,'b',true,NULL) + || parse_sdp_line(sdp_msg,s,'b',true,NULL,false) // encryption key || parse_sdp_line(sdp_msg,s,'k',true,NULL) // zero or more media attribute lines @@ -633,12 +644,14 @@ static bool parse_sdp_media(AmSdp* sdp_msg, char*& s, char*& next_line) } next_line = get_next_line(s); + DBG("ret=%i; next_line=<%s>\n",ret,next_line); return ret; } static bool parse_sdp_attribute(AmSdp* sdp_msg, char*& s, char*& next_line) { + DBG("parse_sdp_attribute: s=%s\n",s); if(sdp_msg->media.empty()){ ERROR("While parsing media options: no actual media !\n"); return true; @@ -672,6 +685,8 @@ static bool parse_sdp_attribute(AmSdp* sdp_msg, char*& s, char*& next_line) } parse_string_tok(s,params,'\0'); + DBG("sdp attribute: pt=%u; enc=%s; cr=%u\n", + payload_type,encoding_name.c_str(),clock_rate); vector::iterator pl_it; diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 992ec7c3..24211cc5 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -521,26 +521,29 @@ void AmSession::onSipReply(const AmSipReply& reply) case AmSipDialog::Connected: - // connected! - if(acceptAudio(reply.body,reply.hdrs)){ - ERROR("could not connect audio!!!\n"); - dlg.bye(); - setStopped(); - } - else { - if(detached.get() && !getStopped()){ - - onSessionStart(reply); + try { + acceptAudio(reply.body,reply.hdrs); + + if(detached.get() && !getStopped()){ - if(input || output) - AmMediaProcessor::instance()->addSession(this, - callgroup); - else { - ERROR("missing audio input and/or ouput.\n"); - } - } - } - break; + onSessionStart(reply); + + if(input || output) + AmMediaProcessor::instance()->addSession(this, + callgroup); + else { + ERROR("missing audio input and/or ouput.\n"); + } + } + + }catch(const AmSession::Exception& e){ + ERROR("could not connect audio!!!\n"); + ERROR("%i %s\n",e.code,e.reason.c_str()); + dlg.bye(); + setStopped(); + break; + } + break; case AmSipDialog::Pending: @@ -556,15 +559,19 @@ void AmSession::onSipReply(const AmSipReply& reply) void AmSession::onInvite(const AmSipRequest& req) { - string sdp_reply; - if(acceptAudio(req.body,req.hdrs,&sdp_reply)!=0) - return; + try { + string sdp_reply; - if(dlg.reply(req,200,"OK", - "application/sdp",sdp_reply) != 0){ + acceptAudio(req.body,req.hdrs,&sdp_reply); + if(dlg.reply(req,200,"OK", + "application/sdp",sdp_reply) != 0) + throw AmSession::Exception(500,"could not send response"); + + }catch(const AmSession::Exception& e){ - //throw AmSession::Exception(500,"error while sending response"); + ERROR("%i %s\n",e.code,e.reason.c_str()); setStopped(); + AmSipDialog::reply_error(req,e.code,e.reason); } } @@ -612,10 +619,12 @@ int AmSession::acceptAudio(const string& body, } catch(const AmSession::Exception& e){ ERROR("%i %s\n",e.code,e.reason.c_str()); -// if(dlg.reply(req,e.code,e.reason, "")){ -// dlg.bye(); -// } - setStopped(); + throw; + +// if(dlg.reply(req,e.code,e.reason, "")){ +// dlg.bye(); +// } +// setStopped(); } return -1; diff --git a/core/AmSession.h b/core/AmSession.h index bbb74819..2ab96225 100644 --- a/core/AmSession.h +++ b/core/AmSession.h @@ -149,16 +149,6 @@ public: Exception(int c, string r) : code(c), reason(r) {} }; -// struct SessionTimerException : Exception { -// unsigned int minSE; - -// SessionTimerException(unsigned int min_SE) -// : Exception(422, "Session Interval Too Small"), -// minSE(min_SE) { } - -// string getErrorHeaders() const; -// }; - /** * Session constructor. */ diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index eeb46d39..213ae16f 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -31,6 +31,9 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq); remote_uri = req.from_uri; + sip_ip = req.dstip; + sip_port = req.port; + if(callid.empty()){ callid = req.callid; remote_tag = req.from_tag; @@ -40,9 +43,6 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) remote_party = req.from; local_party = req.to; - sip_ip = req.dstip; - sip_port = req.port; - setRoute(req.route); next_hop = req.next_hop; } @@ -200,14 +200,14 @@ string AmSipDialog::getContactHdr() contact_uri = "Contact: