Logo Search packages:      
Sourcecode: yate version File versions  Download package

bool SIPTransaction::processMessage ( SIPMessage message,
const String branch 
) [virtual]

Check if a message belongs to this transaction and process it if so

Parameters:
message A pointer to the message to check, should not be used afterwards if this method returned True
branch The branch parameter extracted from first Via header
Returns:
True if the message was handled by this transaction, in which case it takes ownership over the message

Definition at line 266 of file transaction.cpp.

References TelEngine::String::c_str(), TelEngine::SIPMessage::code, TelEngine::Debug(), getCallID(), TelEngine::SIPMessage::getCSeq(), getDialogTag(), TelEngine::SIPMessage::getHeaderValue(), getMethod(), TelEngine::SIPMessage::getParam(), TelEngine::SIPMessage::getParamValue(), getURI(), TelEngine::SIPMessage::isACK(), TelEngine::SIPMessage::isAnswer(), isIncoming(), isInvite(), isOutgoing(), TelEngine::SIPMessage::method, TelEngine::String::null(), processClientMessage(), processServerMessage(), and TelEngine::SIPMessage::uri.

Referenced by TelEngine::SIPEngine::addMessage().

{
    if (!(message && m_firstMessage))
      return false;
    DDebug("SIPTransaction",DebugAll,"processMessage(%p,'%s') [%p]",
      message,branch.c_str(),this);
    if (branch) {
      if (branch != m_branch) {
          // different branch is allowed only for ACK in incoming INVITE...
          if (!(isInvite() && isIncoming() && message->isACK()))
            return false;
          // ...and only if we sent a 200 response...
          if (!m_lastMessage || ((m_lastMessage->code / 100) != 2))
            return false;
          // ...and if also matches the CSeq, Call-ID and To: tag
          if ((m_firstMessage->getCSeq() != message->getCSeq()) ||
            (getCallID() != message->getHeaderValue("Call-ID")) ||
            (getDialogTag() != message->getParamValue("To","tag")))
            return false;
          Debug("SIPTransaction",DebugAll,"Found non-branch ACK response to our 2xx");
      }
      else if (getMethod() != message->method) {
          if (!(isIncoming() && isInvite() && message->isACK()))
            return false;
      }
    }
    else {
      if (getMethod() != message->method) {
          if (!(isIncoming() && isInvite() && message->isACK()))
            return false;
      }
      if ((m_firstMessage->getCSeq() != message->getCSeq()) ||
          (getURI() != message->uri) ||
          (getCallID() != message->getHeaderValue("Call-ID")) ||
          (m_firstMessage->getHeaderValue("From") != message->getHeaderValue("From")) ||
          (m_firstMessage->getHeaderValue("To") != message->getHeaderValue("To")) ||
          (m_firstMessage->getHeaderValue("Via") != message->getHeaderValue("Via")))
          return false;
      if (message->isACK() && (getDialogTag() != message->getParamValue("To","tag")))
          return false;
    }
    if (isOutgoing() != message->isAnswer()) {
      Debug("SIPTransaction",DebugAll,"Ignoring retransmitted %s %p '%s' in [%p]",
          message->isAnswer() ? "answer" : "request",
          message,message->method.c_str(),this);
      return false;
    }
    Debug("SIPTransaction",DebugAll,"Processing %s %p '%s' in [%p]",
      message->isAnswer() ? "answer" : "request",
      message,message->method.c_str(),this);

    if (m_tag.null() && message->isAnswer()) {
      const NamedString* ns = message->getParam("To","tag");
      if (ns) {
          m_tag = *ns;
          Debug("SIPTransaction",DebugInfo,"Found dialog tag '%s' [%p]",
            m_tag.c_str(),this);
      }
    }

    if (isOutgoing())
      processClientMessage(message,m_state);
    else
      processServerMessage(message,m_state);
    return true;
}


Generated by  Doxygen 1.6.0   Back to index