void DSMCall::B2BterminateOtherLeg() { terminateOtherLeg(); }
void AmB2BSession::onSessionTimeout() { DBG("Session Timer: Timeout, ending other leg\n"); terminateOtherLeg(); AmSession::onSessionTimeout(); }
void AmB2BSession::onNoAck(unsigned int cseq) { DBG("OnNoAck(%u): terminate other leg.\n",cseq); terminateOtherLeg(); AmSession::onNoAck(cseq); }
void AmB2BSession::onRtpTimeout() { DBG("RTP Timeout, ending other leg\n"); terminateOtherLeg(); AmSession::onRtpTimeout(); }
void AmB2BSession::onB2BEvent(B2BEvent* ev) { DBG("AmB2BSession::onB2BEvent\n"); switch(ev->event_id){ case B2BSipRequest: { B2BSipRequestEvent* req_ev = dynamic_cast<B2BSipRequestEvent*>(ev); assert(req_ev); DBG("B2BSipRequest: %s (fwd=%s)\n", req_ev->req.method.c_str(), req_ev->forward?"true":"false"); if(req_ev->forward){ // Check Max-Forwards first if(req_ev->req.max_forwards == 0) { relayError(req_ev->req.method,req_ev->req.cseq, true,483,SIP_REPLY_TOO_MANY_HOPS); return; } if (req_ev->req.method == SIP_METH_INVITE && dlg->getUACInvTransPending()) { // don't relay INVITE if INV trans pending DBG("not sip-relaying INVITE with pending INV transaction, " "b2b-relaying 491 pending\n"); relayError(req_ev->req.method, req_ev->req.cseq, true, 491, SIP_REPLY_PENDING); return; } if (req_ev->req.method == SIP_METH_BYE && dlg->getStatus() != AmBasicSipDialog::Connected) { DBG("not sip-relaying BYE in not connected dlg, b2b-relaying 200 OK\n"); relayError(req_ev->req.method, req_ev->req.cseq, true, 200, "OK"); return; } } if( (req_ev->req.method == SIP_METH_BYE) // CANCEL is handled differently: other side has already // sent a terminate event. //|| (req_ev->req.method == SIP_METH_CANCEL) ) { if (onOtherBye(req_ev->req)) req_ev->processed = true; // app should have relayed 200 to BYE } if(req_ev->forward && !req_ev->processed){ int res = relaySip(req_ev->req); if(res < 0) { // reply relayed request internally relayError(req_ev->req.method, req_ev->req.cseq, true, res); return; } } } return; case B2BSipReply: { B2BSipReplyEvent* reply_ev = dynamic_cast<B2BSipReplyEvent*>(ev); assert(reply_ev); DBG("B2BSipReply: %i %s (fwd=%s)\n",reply_ev->reply.code, reply_ev->reply.reason.c_str(),reply_ev->forward?"true":"false"); DBG("B2BSipReply: content-type = %s\n", reply_ev->reply.body.getCTStr().c_str()); if(reply_ev->forward){ std::map<int,AmSipRequest>::iterator t_req = recvd_req.find(reply_ev->reply.cseq); if (t_req != recvd_req.end()) { if ((reply_ev->reply.code >= 300) && (reply_ev->reply.code <= 305) && !reply_ev->reply.contact.empty()) { // relay with Contact in 300 - 305 redirect messages AmSipReply n_reply(reply_ev->reply); n_reply.hdrs+=SIP_HDR_COLSP(SIP_HDR_CONTACT) + reply_ev->reply.contact+ CRLF; if(relaySip(t_req->second,n_reply) < 0) { terminateOtherLeg(); terminateLeg(); } } else { // relay response if(relaySip(t_req->second,reply_ev->reply) < 0) { terminateOtherLeg(); terminateLeg(); } } } else { DBG("Cannot relay reply: request already replied" " (code=%u;cseq=%u;call-id=%s)", reply_ev->reply.code, reply_ev->reply.cseq, reply_ev->reply.callid.c_str()); } } else { // check whether not-forwarded (locally initiated) // INV/UPD transaction changed session in other leg if (SIP_IS_200_CLASS(reply_ev->reply.code) && (!reply_ev->reply.body.empty()) && (reply_ev->reply.cseq_method == SIP_METH_INVITE || reply_ev->reply.cseq_method == SIP_METH_UPDATE)) { if (updateSessionDescription(reply_ev->reply.body)) { if (reply_ev->reply.cseq != est_invite_cseq) { if (dlg->getUACInvTransPending()) { DBG("changed session, but UAC INVITE trans pending\n"); // todo(?): save until trans is finished? return; } DBG("session description changed - refreshing\n"); sendEstablishedReInvite(); } else { DBG("reply to establishing INVITE request - not refreshing\n"); } } } } } return; case B2BTerminateLeg: DBG("terminateLeg()\n"); terminateLeg(); break; } //ERROR("unknown event caught\n"); }
void AmB2BCallerSession::onCancel(const AmSipRequest& req) { terminateOtherLeg(); terminateLeg(); }
void AmB2BCallerSession::onB2BEvent(B2BEvent* ev) { bool processed = false; if(ev->event_id == B2BSipReply){ AmSipReply& reply = ((B2BSipReplyEvent*)ev)->reply; if(getOtherId().empty()){ //DBG("Discarding B2BSipReply from other leg (other_id empty)\n"); DBG("B2BSipReply: other_id empty (" "reply code=%i; method=%s; callid=%s; from_tag=%s; " "to_tag=%s; cseq=%i)\n", reply.code,reply.cseq_method.c_str(),reply.callid.c_str(),reply.from_tag.c_str(), reply.to_tag.c_str(),reply.cseq); //return; } else if(getOtherId() != reply.from_tag){// was: local_tag DBG("Dialog mismatch! (oi=%s;ft=%s)\n", getOtherId().c_str(),reply.from_tag.c_str()); return; } DBG("%u %s reply received from other leg\n", reply.code, reply.reason.c_str()); switch(callee_status){ case NoReply: case Ringing: if (reply.cseq == invite_req.cseq) { if (reply.code < 200) { if ((!sip_relay_only) && (reply.code>=180 && reply.code<=183 && (!reply.body.empty()))) { // save early media SDP updateSessionDescription(reply.body); if (sip_relay_early_media_sdp) { if (reinviteCaller(reply)) { ERROR("re-INVITEing caller for early session failed - " "stopping this and other leg\n"); terminateOtherLeg(); terminateLeg(); break; } } } callee_status = Ringing; } else if(reply.code < 300){ callee_status = Connected; DBG("setting callee status to connected\n"); if (!sip_relay_only) { DBG("received 200 class reply to establishing INVITE: " "switching to SIP relay only mode, sending re-INVITE to caller\n"); sip_relay_only = true; AmSipReply n_reply = reply; if (n_reply.body.empty() && !established_body.empty()) { DBG("callee FR without SDP, using provisional response's (18x) one\n"); n_reply.body = established_body; } if (reinviteCaller(n_reply)) { ERROR("re-INVITEing caller failed - stopping this and other leg\n"); terminateOtherLeg(); terminateLeg(); } } } else { // DBG("received %i from other leg: other_id=%s; reply.local_tag=%s\n", // reply.code,other_id.c_str(),reply.local_tag.c_str()); // TODO: terminated my own leg instead? (+ clear_other()) terminateOtherLeg(); } processed = onOtherReply(reply); } break; default: DBG("reply from callee: %u %s\n",reply.code,reply.reason.c_str()); break; } } if (!processed) AmB2BSession::onB2BEvent(ev); }
void AmB2ABSession::onBye(const AmSipRequest& req) { terminateOtherLeg(); disconnectSession(); setStopped(); }