Пример #1
0
void DSMCall::B2BterminateOtherLeg() {
  terminateOtherLeg();
}
Пример #2
0
void AmB2BSession::onSessionTimeout() {
  DBG("Session Timer: Timeout, ending other leg\n");
  terminateOtherLeg();
  AmSession::onSessionTimeout();
}
Пример #3
0
void AmB2BSession::onNoAck(unsigned int cseq)
{
  DBG("OnNoAck(%u): terminate other leg.\n",cseq);
  terminateOtherLeg();
  AmSession::onNoAck(cseq);
}
Пример #4
0
void AmB2BSession::onRtpTimeout() {
  DBG("RTP Timeout, ending other leg\n");
  terminateOtherLeg();
  AmSession::onRtpTimeout();
}
Пример #5
0
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");
}
Пример #6
0
void AmB2BCallerSession::onCancel(const AmSipRequest& req)
{
  terminateOtherLeg();
  terminateLeg();
}
Пример #7
0
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);
}
Пример #8
0
void AmB2ABSession::onBye(const AmSipRequest& req) {
  terminateOtherLeg();
  disconnectSession();
  setStopped();
}