diff --git a/apps/Makefile b/apps/Makefile index 71c54a9f..7acbdf71 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -13,6 +13,7 @@ $(info exclude_app_modules: $(exclude_app_modules)) app_modules = $(filter-out $(subst ;, ,$(exclude_app_modules))\ $(wildcard Makefile*) CVS CMakeLists.txt, \ $(wildcard *) examples/tutorial/cc_acc ) +$(info app_modules: $(app_modules)) #modules = wav gsm ilbc bot echo announcement recorder voicemail dtmf_demo ivr diff --git a/apps/announce_transfer/AnnounceTransfer.cpp b/apps/announce_transfer/AnnounceTransfer.cpp index b868ec07..7b210d32 100644 --- a/apps/announce_transfer/AnnounceTransfer.cpp +++ b/apps/announce_transfer/AnnounceTransfer.cpp @@ -181,7 +181,7 @@ void AnnounceTransferDialog::onSipRequest(const AmSipRequest& req) } -void AnnounceTransferDialog::onSipReply(const AmSipReply& rep) { +void AnnounceTransferDialog::onSipReply(const AmSipReply& rep, int old_dlg_status) { if ((status==Transfering ||status==Hangup) && dlg.get_uac_trans_method(rep.cseq) == "REFER") { if (rep.code >= 300) { @@ -191,7 +191,7 @@ void AnnounceTransferDialog::onSipReply(const AmSipReply& rep) { } } - AmSession::onSipReply(rep); + AmSession::onSipReply(rep, old_dlg_status); } void AnnounceTransferDialog::onBye(const AmSipRequest& req) diff --git a/apps/announce_transfer/AnnounceTransfer.h b/apps/announce_transfer/AnnounceTransfer.h index 2f734f52..b2840401 100644 --- a/apps/announce_transfer/AnnounceTransfer.h +++ b/apps/announce_transfer/AnnounceTransfer.h @@ -72,7 +72,7 @@ public: void startSession(); void onBye(const AmSipRequest& req); void onSipRequest(const AmSipRequest& req); - void onSipReply(const AmSipReply& rep); + void onSipReply(const AmSipReply& rep, int old_dlg_status); void onDtmf(int event, int duration_msec) {} void process(AmEvent* event); diff --git a/apps/auth_b2b/AuthB2B.cpp b/apps/auth_b2b/AuthB2B.cpp index 3cdd6ab2..80fd1277 100644 --- a/apps/auth_b2b/AuthB2B.cpp +++ b/apps/auth_b2b/AuthB2B.cpp @@ -147,7 +147,7 @@ void AuthB2BDialog::onInvite(const AmSipRequest& req) removeHeader(invite_req.hdrs,PARAM_HDR); removeHeader(invite_req.hdrs,"P-App-Name"); - dlg.updateStatus(req); + //dlg.updateStatus(req); recvd_req.insert(std::make_pair(req.cseq,req)); set_sip_relay_only(true); @@ -314,15 +314,15 @@ inline UACAuthCred* AuthB2BCalleeSession::getCredentials() { return &credentials; } -void AuthB2BCalleeSession::onSipReply(const AmSipReply& reply) { +void AuthB2BCalleeSession::onSipReply(const AmSipReply& reply, int old_dlg_status) { if (NULL == auth) { - AmB2BCalleeSession::onSipReply(reply); + AmB2BCalleeSession::onSipReply(reply,old_dlg_status); return; } - int cseq_before = dlg.cseq; + unsigned int cseq_before = dlg.cseq; if (!auth->onSipReply(reply)) { - AmB2BCalleeSession::onSipReply(reply); + AmB2BCalleeSession::onSipReply(reply,old_dlg_status); } else { if (cseq_before != dlg.cseq) { DBG("uac_auth consumed reply with cseq %d and resent with cseq %d; " diff --git a/apps/auth_b2b/AuthB2B.h b/apps/auth_b2b/AuthB2B.h index 5a841961..5619a881 100644 --- a/apps/auth_b2b/AuthB2B.h +++ b/apps/auth_b2b/AuthB2B.h @@ -95,7 +95,7 @@ class AuthB2BCalleeSession AmSessionEventHandler* auth; protected: - void onSipReply(const AmSipReply& reply); + void onSipReply(const AmSipReply& reply, int old_dlg_status); void onSendRequest(const string& method, const string& content_type, const string& body, string& hdrs, int flags, unsigned int cseq); diff --git a/apps/call_timer/CallTimer.cpp b/apps/call_timer/CallTimer.cpp index 24d6cd96..c9c51764 100644 --- a/apps/call_timer/CallTimer.cpp +++ b/apps/call_timer/CallTimer.cpp @@ -131,7 +131,6 @@ CallTimerDialog::~CallTimerDialog() void CallTimerDialog::onInvite(const AmSipRequest& req) { - if (dlg.getStatus() == AmSipDialog::Connected) { DBG("not acting on re-Invite\n"); return; @@ -152,7 +151,7 @@ void CallTimerDialog::onInvite(const AmSipRequest& req) removeHeader(invite_req.hdrs, "P-App-Param"); removeHeader(invite_req.hdrs, "P-App-Name"); - dlg.updateStatus(invite_req); + //dlg.updateStatus(invite_req); recvd_req.insert(std::make_pair(invite_req.cseq,invite_req)); set_sip_relay_only(true); diff --git a/apps/conference/Conference.cpp b/apps/conference/Conference.cpp index f95fe93e..a877ab67 100644 --- a/apps/conference/Conference.cpp +++ b/apps/conference/Conference.cpp @@ -862,10 +862,10 @@ void ConferenceDialog::onSipRequest(const AmSipRequest& req) return; } -void ConferenceDialog::onSipReply(const AmSipReply& reply) +void ConferenceDialog::onSipReply(const AmSipReply& reply, int old_dlg_status) { int status = dlg.getStatus(); - AmSession::onSipReply(reply); + AmSession::onSipReply(reply,old_dlg_status); DBG("ConferenceDialog::onSipReply: code = %i, reason = %s\n, status = %i\n", reply.code,reply.reason.c_str(),dlg.getStatus()); diff --git a/apps/conference/Conference.h b/apps/conference/Conference.h index ea88018b..ce284b04 100644 --- a/apps/conference/Conference.h +++ b/apps/conference/Conference.h @@ -153,7 +153,7 @@ public: void onBye(const AmSipRequest& req); void onSipRequest(const AmSipRequest& req); - void onSipReply(const AmSipReply& reply); + void onSipReply(const AmSipReply& reply, int old_dlg_status); #ifdef WITH_SAS_TTS void onZRTPEvent(zrtp_event_t event, zrtp_stream_ctx_t *stream_ctx); diff --git a/apps/registrar_client/SIPRegistrarClient.cpp b/apps/registrar_client/SIPRegistrarClient.cpp index 8bce7d0c..7afabb37 100644 --- a/apps/registrar_client/SIPRegistrarClient.cpp +++ b/apps/registrar_client/SIPRegistrarClient.cpp @@ -96,52 +96,54 @@ void SIPRegistration::setSessionEventHandler(AmSessionEventHandler* new_seh) { seh = new_seh; } -void SIPRegistration::doRegistration() { - waiting_result = true; - req.to_tag = ""; - dlg.remote_tag = ""; - req.r_uri = "sip:"+info.domain; - dlg.remote_uri = req.r_uri; - - // set outbound proxy as next hop -// DBG("proxy is '%s' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", -// info.proxy.c_str()); -// if (!info.proxy.empty()) { -// dlg.next_hop = info.proxy; -// } else if (!AmConfig::OutboundProxy.empty()) -// dlg.next_hop = AmConfig::OutboundProxy; -// else -// dlg.next_hop = ""; - - dlg.sendRequest(req.method, "", "", "Expires: 1000\n"); - - // save TS - struct timeval now; - gettimeofday(&now, NULL); - reg_send_begin = now.tv_sec; +void SIPRegistration::doRegistration() +{ + waiting_result = true; + req.to_tag = ""; + dlg.remote_tag = ""; + req.r_uri = "sip:"+info.domain; + dlg.remote_uri = req.r_uri; + + // set outbound proxy as next hop + DBG("proxy is '%s' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + info.proxy.c_str()); + if (!info.proxy.empty()) { + dlg.outbound_proxy = info.proxy; + } else if (!AmConfig::OutboundProxy.empty()) + dlg.outbound_proxy = AmConfig::OutboundProxy; + //else + // dlg.outbound_proxy = ""; + + dlg.sendRequest(req.method, "", "", "Expires: 1000\n"); + + // save TS + struct timeval now; + gettimeofday(&now, NULL); + reg_send_begin = now.tv_sec; } -void SIPRegistration::doUnregister() { - waiting_result = true; - req.to_tag = ""; - dlg.remote_tag = ""; - req.r_uri = "sip:"+info.domain; - dlg.remote_uri = req.r_uri; - - // set outbound proxy as next hop -// if (!info.proxy.empty()) { -// dlg.next_hop = info.proxy; -// } else if (!AmConfig::OutboundProxy.empty()) -// dlg.next_hop = AmConfig::OutboundProxy; -// else -// dlg.next_hop = ""; - - dlg.sendRequest(req.method, "", "", "Expires: 0\n"); +void SIPRegistration::doUnregister() +{ + waiting_result = true; + req.to_tag = ""; + dlg.remote_tag = ""; + req.r_uri = "sip:"+info.domain; + dlg.remote_uri = req.r_uri; + + // set outbound proxy as next hop + if (!info.proxy.empty()) { + dlg.outbound_proxy = info.proxy; + } else if (!AmConfig::OutboundProxy.empty()) + dlg.outbound_proxy = AmConfig::OutboundProxy; + //else + // dlg.outbound_proxy = ""; + + dlg.sendRequest(req.method, "", "", "Expires: 0\n"); - // save TS - struct timeval now; - gettimeofday(&now, NULL); - reg_send_begin = now.tv_sec; + // save TS + struct timeval now; + gettimeofday(&now, NULL); + reg_send_begin = now.tv_sec; } void SIPRegistration::onSendRequest(const string& method, @@ -315,7 +317,8 @@ void SIPRegistrarClient::onServerShutdown() { // return; } -void SIPRegistrarClient::process(AmEvent* ev) { +void SIPRegistrarClient::process(AmEvent* ev) +{ if (ev->event_id == E_SYSTEM) { AmSystemEvent* sys_ev = dynamic_cast(ev); if(sys_ev){ @@ -329,7 +332,7 @@ void SIPRegistrarClient::process(AmEvent* ev) { AmSipReplyEvent* sip_rep = dynamic_cast(ev); if (sip_rep) { - onSipReplyEvent(sip_rep); + onSipReplyEvent(sip_rep); return; } @@ -351,7 +354,7 @@ void SIPRegistrarClient::process(AmEvent* ev) { void SIPRegistrarClient::onSipReplyEvent(AmSipReplyEvent* ev) { SIPRegistration* reg = get_reg(ev->reply.local_tag); if (reg != NULL) { - reg->onSipReply(ev->reply); + reg->getDlg()->updateStatus(ev->reply);//onSipReply(ev->reply); } } @@ -369,14 +372,13 @@ bool SIPRegistration::registerExpired(time_t now_sec) { return ((reg_begin+reg_expires) < (unsigned int)now_sec); } -void SIPRegistration::onSipReply(AmSipReply& reply) { +void SIPRegistration::onSipReply(const AmSipReply& reply, int old_dlg_status) +{ if ((seh!=NULL) && seh->onSipReply(reply)) return; waiting_result = false; - dlg.updateStatus(reply); - if ((reply.code>=200)&&(reply.code<300)) { DBG("positive reply to REGISTER!\n"); size_t end = 0; @@ -408,7 +410,7 @@ void SIPRegistration::onSipReply(AmSipReply& reply) { if (server_contact.isEqual(local_contact)) { DBG("contact found\n"); found = active = true; - bool str2i(const string& str, unsigned int& result); + //bool str2i(const string& str, unsigned int& result); if (str2i(server_contact.params["expires"], reg_expires)) { ERROR("could not extract expires value.\n"); diff --git a/apps/registrar_client/SIPRegistrarClient.h b/apps/registrar_client/SIPRegistrarClient.h index 4acb55ec..d4c19d47 100644 --- a/apps/registrar_client/SIPRegistrarClient.h +++ b/apps/registrar_client/SIPRegistrarClient.h @@ -118,11 +118,15 @@ class SIPRegistration : public AmSipDialogEventHandler, const string& body, string& hdrs, int flags); + // DialogControl if AmSipDialog* getDlg() { return &dlg; } // CredentialHolder UACAuthCred* getCredentials() { return &cred; } - void onSipReply(AmSipReply& reply); + + void onSipReply(const AmSipReply& reply, int old_dlg_status); + void onSipRequest(const AmSipRequest& req) {} + void onInvite2xx(const AmSipReply&) {} /** is this registration registered? */ bool active; diff --git a/apps/sst_b2b/SSTB2B.cpp b/apps/sst_b2b/SSTB2B.cpp index e483a887..fccf531c 100644 --- a/apps/sst_b2b/SSTB2B.cpp +++ b/apps/sst_b2b/SSTB2B.cpp @@ -121,7 +121,7 @@ void SSTB2BDialog::onInvite(const AmSipRequest& req) removeHeader(invite_req.hdrs,PARAM_HDR); removeHeader(invite_req.hdrs,"P-App-Name"); - dlg.updateStatus(req); + //dlg.updateStatus(req); recvd_req.insert(std::make_pair(req.cseq,req)); set_sip_relay_only(true); @@ -163,7 +163,8 @@ void SSTB2BDialog::onSipRequest(const AmSipRequest& req) { AmB2BCallerSession::onSipRequest(req); } -void SSTB2BDialog::onSipReply(const AmSipReply& reply) { +void SSTB2BDialog::onSipReply(const AmSipReply& reply, int old_dlg_status) +{ TransMap::iterator t = relayed_req.find(reply.cseq); bool fwd = t != relayed_req.end(); @@ -173,7 +174,7 @@ void SSTB2BDialog::onSipReply(const AmSipReply& reply) { CALL_EVENT_H(onSipReply,reply); } - AmB2BCallerSession::onSipReply(reply); + AmB2BCallerSession::onSipReply(reply,old_dlg_status); } bool SSTB2BDialog::onOtherReply(const AmSipReply& reply) @@ -335,7 +336,8 @@ void SSTB2BCalleeSession::onSipRequest(const AmSipRequest& req) { AmB2BCalleeSession::onSipRequest(req); } -void SSTB2BCalleeSession::onSipReply(const AmSipReply& reply) { +void SSTB2BCalleeSession::onSipReply(const AmSipReply& reply, int old_dlg_status) +{ // call event handlers where it is not done TransMap::iterator t = relayed_req.find(reply.cseq); bool fwd = t != relayed_req.end(); @@ -346,13 +348,13 @@ void SSTB2BCalleeSession::onSipReply(const AmSipReply& reply) { } if (NULL == auth) { - AmB2BCalleeSession::onSipReply(reply); + AmB2BCalleeSession::onSipReply(reply,old_dlg_status); return; } - int cseq_before = dlg.cseq; + unsigned int cseq_before = dlg.cseq; if (!auth->onSipReply(reply)) { - AmB2BCalleeSession::onSipReply(reply); + AmB2BCalleeSession::onSipReply(reply,old_dlg_status); } else { if (cseq_before != dlg.cseq) { DBG("uac_auth consumed reply with cseq %d and resent with cseq %d; " diff --git a/apps/sst_b2b/SSTB2B.h b/apps/sst_b2b/SSTB2B.h index 439ee4f0..2d6aa0f0 100644 --- a/apps/sst_b2b/SSTB2B.h +++ b/apps/sst_b2b/SSTB2B.h @@ -93,7 +93,7 @@ class SSTB2BDialog : public AmB2BCallerSession void sendReinvite(bool updateSDP, const string& headers); protected: - void onSipReply(const AmSipReply& reply); + void onSipReply(const AmSipReply& reply, int old_dlg_status); void onSipRequest(const AmSipRequest& req); protected: @@ -115,7 +115,7 @@ class SSTB2BCalleeSession protected: void onSipRequest(const AmSipRequest& req); - void onSipReply(const AmSipReply& reply); + void onSipReply(const AmSipReply& reply, int old_dlg_status); void onSendRequest(const string& method, const string& content_type, const string& body, string& hdrs, int flags, unsigned int cseq); diff --git a/apps/sw_prepaid_sip/SWPrepaidSIP.cpp b/apps/sw_prepaid_sip/SWPrepaidSIP.cpp index 339d1d23..7c6bb46d 100644 --- a/apps/sw_prepaid_sip/SWPrepaidSIP.cpp +++ b/apps/sw_prepaid_sip/SWPrepaidSIP.cpp @@ -183,7 +183,7 @@ void SWPrepaidSIPDialog::onInvite(const AmSipRequest& req) } invite_req = req; - dlg.updateStatus(req); + //dlg.updateStatus(req); recvd_req.insert(std::make_pair(req.cseq,req)); connectCallee("<" + m_ruri + ">", m_proxy + ";sw_prepaid", true); diff --git a/apps/webconference/WebConferenceDialog.cpp b/apps/webconference/WebConferenceDialog.cpp index d95ac6f5..b26806c4 100644 --- a/apps/webconference/WebConferenceDialog.cpp +++ b/apps/webconference/WebConferenceDialog.cpp @@ -173,12 +173,13 @@ void WebConferenceDialog::onSessionStart(const AmSipReply& rep) { connectConference(dlg.user); } -void WebConferenceDialog::onSipReply(const AmSipReply& reply) { - int status = dlg.getStatus(); +void WebConferenceDialog::onSipReply(const AmSipReply& reply, int old_dlg_status) +{ + //int status = dlg.getStatus(); - AmSession::onSipReply(reply); + AmSession::onSipReply(reply,old_dlg_status); - if ((status < AmSipDialog::Connected) && + if ((old_dlg_status < AmSipDialog::Connected) && (dlg.getStatus() == AmSipDialog::Disconnected)) { DBG("Call failed.\n"); setStopped(); diff --git a/apps/webconference/WebConferenceDialog.h b/apps/webconference/WebConferenceDialog.h index c41641ef..203dee43 100644 --- a/apps/webconference/WebConferenceDialog.h +++ b/apps/webconference/WebConferenceDialog.h @@ -94,7 +94,7 @@ public: ~WebConferenceDialog(); void process(AmEvent* ev); - void onSipReply(const AmSipReply& reply); + void onSipReply(const AmSipReply& reply, int old_dlg_status); void onSessionStart(const AmSipRequest& req); void onSessionStart(const AmSipReply& rep); void onEarlySessionStart(const AmSipReply& rep); diff --git a/core/AmB2ABSession.cpp b/core/AmB2ABSession.cpp index 96dd61de..658be2cd 100644 --- a/core/AmB2ABSession.cpp +++ b/core/AmB2ABSession.cpp @@ -353,9 +353,10 @@ void AmB2ABCalleeSession::onSessionStart(const AmSipReply& rep) { relayEvent(new B2ABConnectAudioEvent()); } -void AmB2ABCalleeSession::onSipReply(const AmSipReply& rep) { - int status_before = dlg.getStatus(); - AmB2ABSession::onSipReply(rep); +void AmB2ABCalleeSession::onSipReply(const AmSipReply& rep, int old_dlg_status) { + + int status_before = old_dlg_status;//dlg.getStatus(); + AmB2ABSession::onSipReply(rep, old_dlg_status); int status = dlg.getStatus(); if ((status_before == AmSipDialog::Pending)&& diff --git a/core/AmB2ABSession.h b/core/AmB2ABSession.h index 57a8a101..ad05edb0 100644 --- a/core/AmB2ABSession.h +++ b/core/AmB2ABSession.h @@ -247,7 +247,7 @@ class AmB2ABCalleeSession: public AmB2ABSession void onEarlySessionStart(const AmSipReply& rep); void onSessionStart(const AmSipReply& rep); - void onSipReply(const AmSipReply& rep); + void onSipReply(const AmSipReply& rep, int old_dlg_status); protected: void onB2ABEvent(B2ABEvent* ev); diff --git a/core/AmB2BSession.cpp b/core/AmB2BSession.cpp index f6b0c341..419d1ab5 100644 --- a/core/AmB2BSession.cpp +++ b/core/AmB2BSession.cpp @@ -188,14 +188,14 @@ void AmB2BSession::onSipRequest(const AmSipRequest& req) if(!fwd) AmSession::onSipRequest(req); else { - dlg.updateStatus(req); + //dlg.updateStatus(req); recvd_req.insert(std::make_pair(req.cseq,req)); } relayEvent(new B2BSipRequestEvent(req,fwd)); } -void AmB2BSession::onSipReply(const AmSipReply& reply) +void AmB2BSession::onSipReply(const AmSipReply& reply, int old_dlg_status) { TransMap::iterator t = relayed_req.find(reply.cseq); bool fwd = t != relayed_req.end(); @@ -206,7 +206,7 @@ void AmB2BSession::onSipReply(const AmSipReply& reply) AmSipReply n_reply = reply; n_reply.cseq = t->second.cseq; - dlg.updateStatus(reply, false); + //dlg.updateStatus(reply, false); relayEvent(new B2BSipReplyEvent(n_reply,true)); if(reply.code >= 200) { @@ -238,28 +238,33 @@ void AmB2BSession::onSipReply(const AmSipReply& reply) // todo (?): add do_200_ack flag to AmSession::onSipReply and call AmSession::onSipReply CALL_EVENT_H(onSipReply,reply); - int status = dlg.getStatus(); - dlg.updateStatus(reply, false); + //int status = dlg.getStatus(); + //dlg.updateStatus(reply, false); - if (status != dlg.getStatus()) + if (old_dlg_status != dlg.getStatus()) DBG("Dialog status changed %s -> %s (stopped=%s) \n", - AmSipDialog::status2str[status], + AmSipDialog::status2str[old_dlg_status], AmSipDialog::status2str[dlg.getStatus()], getStopped() ? "true" : "false"); else - DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[status], + DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[old_dlg_status], getStopped() ? "true" : "false"); } else { relayed_body_req.erase(rel_body_it); - AmSession::onSipReply(reply); + AmSession::onSipReply(reply, old_dlg_status); } } else { - AmSession::onSipReply(reply); + AmSession::onSipReply(reply, old_dlg_status); } relayEvent(new B2BSipReplyEvent(reply,false)); } } +void AmB2BSession::onInvite2xx(const AmSipReply& reply) +{ + // do not send the 200 ACK yet... +} + void AmB2BSession::relayEvent(AmEvent* ev) { DBG("AmB2BSession::relayEvent: id=%s\n", diff --git a/core/AmB2BSession.h b/core/AmB2BSession.h index 97fe830e..331a21d5 100644 --- a/core/AmB2BSession.h +++ b/core/AmB2BSession.h @@ -170,7 +170,8 @@ class AmB2BSession: public AmSession /** @see AmSession */ void onSipRequest(const AmSipRequest& req); - void onSipReply(const AmSipReply& reply); + void onSipReply(const AmSipReply& reply, int old_dlg_status); + void onInvite2xx(const AmSipReply& reply); /** @see AmEventQueue */ void process(AmEvent* event); diff --git a/core/AmPlugIn.h b/core/AmPlugIn.h index cf999fe4..3f61c0bf 100644 --- a/core/AmPlugIn.h +++ b/core/AmPlugIn.h @@ -42,9 +42,7 @@ class AmPluginFactory; class AmSessionFactory; class AmSessionEventHandlerFactory; class AmDynInvokeFactory; -//class AmSIPEventHandler; class AmLoggingFacility; -//class AmCtrlInterfaceFactory; class AmSipRequest; struct amci_exports_t; @@ -120,7 +118,6 @@ class AmPlugIn : public AmPayloadProviderInterface int loadBasePlugIn(AmPluginFactory* cb); int loadDiPlugIn(AmPluginFactory* cb); int loadLogFacPlugIn(AmPluginFactory* f); - //int loadCtrlFacPlugIn(AmPluginFactory* f); public: diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 4dee96af..41563f49 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -636,9 +636,9 @@ void AmSession::process(AmEvent* ev) } AmAudioEvent* audio_ev = dynamic_cast(ev); - if(audio_ev && (audio_ev->event_id == AmAudioEvent::cleared)){ - setStopped(); - return; + if(audio_ev){ + onAudioEvent(audio_ev); + return; } AmDtmfEvent* dtmf_ev = dynamic_cast(ev); @@ -671,14 +671,16 @@ void AmSession::onSipEvent(AmSipEvent* sip_ev) AmSipRequestEvent* req_ev = dynamic_cast(sip_ev); if(req_ev) { - onSipRequest(req_ev->req); + //onSipRequest(req_ev->req); + dlg.updateStatus(req_ev->req); return; } AmSipReplyEvent* reply_ev = dynamic_cast(sip_ev); if(reply_ev) { - onSipReply(reply_ev->reply); + //onSipReply(reply_ev->reply); + dlg.updateStatus(reply_ev->reply); return; } @@ -689,7 +691,7 @@ void AmSession::onSipRequest(const AmSipRequest& req) { CALL_EVENT_H(onSipRequest,req); - dlg.updateStatus(req); + //dlg.updateStatus(req); DBG("onSipRequest: method = %s\n",req.method.c_str()); if(req.method == "INVITE"){ @@ -730,25 +732,25 @@ void AmSession::onSipRequest(const AmSipRequest& req) } -void AmSession::onSipReply(const AmSipReply& reply) +void AmSession::onSipReply(const AmSipReply& reply, int old_dlg_status) { CALL_EVENT_H(onSipReply,reply); - int status = dlg.getStatus(); - dlg.updateStatus(reply); +// int status = dlg.getStatus(); +// dlg.updateStatus(reply); - if (status != dlg.getStatus()) + if (old_dlg_status != dlg.getStatus()) DBG("Dialog status changed %s -> %s (stopped=%s) \n", - AmSipDialog::status2str[status], + AmSipDialog::status2str[old_dlg_status], AmSipDialog::status2str[dlg.getStatus()], sess_stopped.get() ? "true" : "false"); else - DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[status], + DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[old_dlg_status], sess_stopped.get() ? "true" : "false"); if (negotiate_onreply) { - if(status < AmSipDialog::Connected){ + if(old_dlg_status < AmSipDialog::Connected){ switch(dlg.getStatus()){ @@ -764,8 +766,8 @@ void AmSession::onSipReply(const AmSipReply& reply) onSessionStart(reply); if(input || output || local_input || local_output) - AmMediaProcessor::instance()->addSession(this, - callgroup); + AmMediaProcessor::instance()->addSession(this, + callgroup); else { DBG("no audio input and output set. " "Session will not be attached to MediaProcessor.\n"); @@ -824,6 +826,18 @@ void AmSession::onSipReply(const AmSipReply& reply) } } +void AmSession::onInvite2xx(const AmSipReply& reply) +{ + AmSipTransaction* t = dlg.get_uac_trans(reply.cseq); + if(t) dlg.send_200_ack(*t); +} + +void AmSession::onAudioEvent(AmAudioEvent* audio_ev) +{ + if (audio_ev->event_id == AmAudioEvent::cleared) + setStopped(); +} + void AmSession::onInvite(const AmSipRequest& req) { try { diff --git a/core/AmSession.h b/core/AmSession.h index 21e4257c..8200ddf8 100644 --- a/core/AmSession.h +++ b/core/AmSession.h @@ -467,8 +467,15 @@ public: /** Entry point for SIP Requests */ virtual void onSipRequest(const AmSipRequest& req); /** Entry point for SIP Replies */ - virtual void onSipReply(const AmSipReply& reply); + virtual void onSipReply(const AmSipReply& reply, int old_dlg_status); + /** 2xx reply has been received for an INVITE transaction */ + virtual void onInvite2xx(const AmSipReply& reply); + + /** + * Entry point for Audio events + */ + virtual void onAudioEvent(AmAudioEvent* audio_ev); /** * entry point for system events diff --git a/core/AmSessionEventHandler.h b/core/AmSessionEventHandler.h index 96ee5df2..61e23c37 100644 --- a/core/AmSessionEventHandler.h +++ b/core/AmSessionEventHandler.h @@ -64,6 +64,7 @@ public: * shall be stopped after them. */ virtual bool process(AmEvent*); + virtual bool onSipEvent(AmSipEvent*); virtual bool onSipRequest(const AmSipRequest&); virtual bool onSipReply(const AmSipReply&); diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index 66175a09..304b7b8b 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -75,6 +75,11 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) return; } + if (req.cseq <= r_cseq){ + reply_error(req,500,"Server Internal Error"); + return; + } + if(uas_trans.find(req.cseq) == uas_trans.end()){ DBG("req.tt = {%p,%p}\n",req.tt._bucket, req.tt._t); uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq,req.tt); @@ -105,6 +110,9 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) local_party = req.to; route = req.route; } + + if(hdl) + hdl->onSipRequest(req); } /** @@ -186,7 +194,7 @@ int AmSipDialog::updateStatusReply(const AmSipRequest& req, unsigned int code) return 0; } -void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack) +void AmSipDialog::updateStatus(const AmSipReply& reply/*, bool do_200_ack*/) { TransMap::iterator t_it = uac_trans.find(reply.cseq); if(t_it == uac_trans.end()){ @@ -197,6 +205,7 @@ void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack) DBG("updateStatus(reply): transaction found!\n"); AmSipTransaction& t = t_it->second; + int old_dlg_status = status; // rfc3261 12.1 // Dialog established only by 101-199 or 2xx @@ -262,12 +271,22 @@ void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack) // TODO: // - place this somewhere else. // (probably in AmSession...) - if((reply.code < 300) && (t.method == "INVITE") && do_200_ack) { - send_200_ack(t); - } + if((reply.code < 300) && (t.method == "INVITE")) { - uac_trans.erase(t_it); + if(hdl) { + hdl->onInvite2xx(reply); + } + else { + send_200_ack(t); + } + } + else { + uac_trans.erase(t_it); + } } + + if(hdl) + hdl->onSipReply(reply, old_dlg_status); } string AmSipDialog::getContactHdr() @@ -608,6 +627,16 @@ string AmSipDialog::get_uac_trans_method(unsigned int cseq) return ""; } +AmSipTransaction* AmSipDialog::get_uac_trans(unsigned int cseq) +{ + TransMap::iterator t = uac_trans.find(cseq); + + if (t != uac_trans.end()) + return &(t->second); + + return NULL; +} + int AmSipDialog::drop() { status = Disconnected; @@ -636,7 +665,6 @@ int AmSipDialog::send_200_ack(const AmSipTransaction& t, req.method = "ACK"; req.r_uri = remote_uri; - //req.next_hop = next_hop; req.from = SIP_HDR_COLSP(SIP_HDR_FROM) + local_party; if(!local_tag.empty()) diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h index c427d1f9..49828547 100644 --- a/core/AmSipDialog.h +++ b/core/AmSipDialog.h @@ -70,23 +70,35 @@ typedef std::map TransMap; */ class AmSipDialogEventHandler { - public: - virtual void onSendRequest(const string& method, +public: + + /** Hook called when a request has been received */ + virtual void onSipRequest(const AmSipRequest& req)=0; + + /** Hook called when a reply has been received */ + virtual void onSipReply(const AmSipReply& reply, int old_dlg_status)=0; + + /** Hook called before a request is sent */ + virtual void onSendRequest(const string& method, + const string& content_type, + const string& body, + string& hdrs, + int flags, + unsigned int cseq)=0; + + /** Hook called before a reply is sent */ + virtual void onSendReply(const AmSipRequest& req, + unsigned int code, + const string& reason, const string& content_type, const string& body, string& hdrs, - int flags, - unsigned int cseq)=0; - - virtual void onSendReply(const AmSipRequest& req, - unsigned int code, - const string& reason, - const string& content_type, - const string& body, - string& hdrs, - int flags)=0; - - virtual ~AmSipDialogEventHandler() {}; + int flags)=0; + + /** Hook called when a local INVITE request has been replied with 2xx */ + virtual void onInvite2xx(const AmSipReply& reply)=0; + + virtual ~AmSipDialogEventHandler() {}; }; /** @@ -136,7 +148,8 @@ class AmSipDialog string outbound_proxy; bool force_outbound_proxy; - int cseq; // Local CSeq for next request + unsigned int cseq; // Local CSeq for next request + unsigned int r_cseq; // last remote CSeq AmSipDialog(AmSipDialogEventHandler* h=0); ~AmSipDialog(); @@ -145,12 +158,12 @@ class AmSipDialog int getStatus() { return status; } string getContactHdr(); - void updateStatus(const AmSipRequest& req); - void updateStatus(const AmSipReply& reply, bool do_200_ack=true); - /** update Status from locally originated request (e.g. INVITE) */ void updateStatusFromLocalRequest(const AmSipRequest& req); + void updateStatus(const AmSipRequest& req); + void updateStatus(const AmSipReply& reply); + int reply(const AmSipRequest& req, unsigned int code, const string& reason, @@ -190,6 +203,8 @@ class AmSipDialog */ string get_uac_trans_method(unsigned int cseq); + AmSipTransaction* get_uac_trans(unsigned int cseq); + static int reply_error(const AmSipRequest& req, unsigned int code, const string& reason,