bool SIPNict::onSendMessage(SIPMessage::Ptr pMsg) { SIPTransaction::Ptr pTransaction = static_cast<SIPTransaction::WeakPtr*>(_owner)->lock(); if (!pTransaction) return false; if (pTransaction->getState() == SIPTransaction::TRN_STATE_IDLE) { startTimerMaxLifetime(300000); /// five minutes _pRequest = pMsg; pTransaction->setState(TRYING); std::string sTimeout; if (pMsg->getProperty(OSS::PropertyMap::PROP_TransactionTimeout, sTimeout) && !sTimeout.empty()) { _timerEValue = OSS::string_to_number<unsigned long>(sTimeout.c_str()) / 64; } else { _timerEValue = _timerProps.timerE(); } if (!pTransaction->transport()->isReliableTransport()) { startTimerE(_timerEValue); startTimerF(_timerEValue*64); } else { startTimerF(RELIABLE_TIMER_F_VALUE); } return true; } return false; }
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(); }