Beispiel #1
0
void SIPIctPool::onAttachFSM(const SIPTransaction::Ptr& pTransaction)
{
  if (!pTransaction->fsm())
  {
    pTransaction->type() = SIPTransaction::TYPE_ICT;
    pTransaction->fsm() = SIPIct::Ptr(new SIPIct(_ioService, _timerProps));
    pTransaction->fsm()->setOwner(new SIPTransaction::WeakPtr(pTransaction));
    pTransaction->fsm()->dispatch() = dispatch();
  }
}
SIPTransaction::Ptr SIPTransaction::findBranch(const SIPMessage::Ptr& pRequest)
{
  //
  // Only a parent transaction can have branches
  //
  if(!isParent())
    return SIPTransaction::Ptr();

  OSS::mutex_critic_sec_lock lock(_branchesMutex);
  SIPTransaction::Ptr foundBranch;
  std::string branch = pRequest->getToTag();
  if (branch.empty())
    return SIPTransaction::Ptr();

  Branches::iterator pBranch = _branches.find(branch);
  
  //
  // Branch is non-existent.  Create a new one and attach a new FSM to it
  //
  if (pBranch == _branches.end())
  {
    foundBranch = SIPTransaction::Ptr(new SIPTransaction(shared_from_this()));
    _owner->onAttachFSM(foundBranch);
    foundBranch->fsm()->setRequest(fsm()->getRequest());
    foundBranch->_owner = _owner;
    foundBranch->_responseTU = _responseTU;
    _branches[branch] = foundBranch;
  }
  else
  {
    foundBranch = pBranch->second;
  }
  return foundBranch;
}
Beispiel #3
0
void SIPNict::onReceivedMessage(SIPMessage::Ptr pMsg, SIPTransportSession::Ptr pTransport)
{
  SIPTransaction::Ptr pTransaction = static_cast<SIPTransaction::WeakPtr*>(_owner)->lock();
  if (!pTransaction)
    return;


  int state = pTransaction->getState();
  if (!pMsg->isResponse() || state == SIPTransaction::TRN_STATE_TERMINATED || state == COMPLETED)
    return;

  bool is2xx = pMsg->is2xx();

  SIPTransaction::Ptr pParent = pTransaction->getParent();

  switch (pTransaction->getState())
  {
  case SIPTransaction::TRN_STATE_IDLE:
  case TRYING:
    if (pMsg->is1xx())
    {
      pTransaction->setState(PROCEEDING);
      if (!pTransaction->isParent() && pParent && pParent->getState() < PROCEEDING)
        pParent->setState(PROCEEDING);

      pTransaction->informTU(pMsg, pTransport);
    }
    else 
    {
      if (pTransaction->isParent() && !is2xx)
      {
        //
        // If we are the parent or this is and error response
        // cancel e and f timers
        //
        cancelTimerE();
        cancelTimerF();
      }
      else if (!pTransaction->isParent() && is2xx)
      {
        //
        // If this is a branch and it is a 2xx reponse,
        // then cancel both parents timers as sell
        //
        cancelTimerE();
        cancelTimerF();

        if (pParent)
        {
          pParent->fsm()->cancelTimerE();
          pParent->fsm()->cancelTimerF();
          pParent->setState(COMPLETED);
        }
      }
      else if (!pTransaction->isParent() && !is2xx)
      {
        //
        // If this is a branch and it is an error reponse,
        // then cancel both parent timers as well if there
        // is only one branch
        //
        cancelTimerE();
        cancelTimerF();

        if (pParent && pParent->getBranchCount() == 1)
        {
          pParent->fsm()->cancelTimerE();
          pParent->fsm()->cancelTimerF();
          pParent->setState(COMPLETED);
        }
      }

      pTransaction->setState(COMPLETED);
      pTransaction->informTU(pMsg, pTransport);
      
      if (!pTransport->isReliableTransport())
      {
        //
        // Start the longest time we want to handle retransmissions of 200 OK
        //
        startTimerK();
      }
      else
      {
        pTransaction->setState(SIPTransaction::TRN_STATE_TERMINATED);
        if (is2xx || pTransaction->allBranchesCompleted())
        {
          if (pParent)
            pParent->setState(SIPTransaction::TRN_STATE_TERMINATED);
        }
      }
    }
    break;
  case PROCEEDING:
    if (pMsg->is1xx())
    {
      pTransaction->informTU(pMsg, pTransport);
    }
    else 
    {
      if (pTransaction->isParent() && !is2xx)
      {
        //
        // If we are the parent or this is and error response
        // cancel e and f timers
        //
        cancelTimerE();
        cancelTimerF();
      }
      else if (!pTransaction->isParent() && is2xx)
      {
        //
        // If this is a branch and it is a 2xx reponse,
        // then cancel both parent timers as sell
        //
        cancelTimerE();
        cancelTimerF();
        if (pParent)
        {
          pParent->fsm()->cancelTimerE();
          pParent->fsm()->cancelTimerF();
          pParent->setState(COMPLETED);
        }
      }
      else if (!pTransaction->isParent() && !is2xx)
      {
        //
        // If this is a branch and it is an error reponse,
        // then cancel both parent timers as well if there
        // is only one branch
        //
        cancelTimerE();
        cancelTimerF();

        if (pParent)
        {
          if (pParent->getBranchCount() == 1)
          {
            pParent->fsm()->cancelTimerE();
            pParent->fsm()->cancelTimerF();
            pParent->setState(COMPLETED);
          }
        }
      }
      
      pTransaction->setState(COMPLETED);
      pTransaction->informTU(pMsg, pTransport);
      if (!pTransport->isReliableTransport())
      {
        //
        // Start the longest time we want to handle retransmissions of 200 OK
        //
        startTimerK();
      }
      else
      {
        pTransaction->setState(SIPTransaction::TRN_STATE_TERMINATED);
        if (is2xx || pTransaction->allBranchesCompleted())
          if (pParent)
            pParent->setState(SIPTransaction::TRN_STATE_TERMINATED);

      }
    }
    break;
  case COMPLETED:
    break;
  }

  if (pTransaction->getState() == SIPTransaction::TRN_STATE_TERMINATED)
      pTransaction->terminate();

  if (pParent && pParent->getState() == SIPTransaction::TRN_STATE_TERMINATED)
      pParent->terminate();

}