⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sipsentresponsedb.cxx

📁 SIP(Session Initiation Protocol)是由IETF定义
💻 CXX
📖 第 1 页 / 共 2 页
字号:
		msgContainer->msg.out = "";		msgContainer->retransCount = 0;	    }	}	else	{	    /// this is a first time receive of this message            int msgSeqNumber                   = msgContainer->msg.in->getCSeq().getCSeqData().convertInt();#if 1            if (SipTransceiver::myAppContext != APP_CONTEXT_PROXY)            {                if(!( (msgContainer->msg.in->getType() == SIP_ACK) ||                      (msgContainer->msg.in->getType() == SIP_CANCEL) ))                {		    // Not ACK or CANCEL                    if(level2Node->seqSet)                    {                      // Check the seq number of the message for the same call-leg.                                      // 1.  if the seq number is higher than previous one Msg is OK                      // 2.  If sequence number is lower, it is an error                      // 3.  If sequence number is equal and message is not an                      //     ACK or CANCEL it is an error.  ACK and CANCELs w/                      //     the same seqence number are OK.                        int storedSeqNum = level2Node->seqNumber;                        if( msgSeqNumber > storedSeqNum )                        {                            cpLog(LOG_DEBUG, "***** Bumping seq to %d", msgSeqNumber);                            //Bump up the next sequenece only if not ACK or CANCEL                                  level2Node->seqNumber = msgSeqNumber;                        }                        else if( (msgSeqNumber < storedSeqNum) ||                                 (msgSeqNumber == storedSeqNum) )                        {                                          // Error condition                             Sptr<SipCommand> sipCmd;                             sipCmd.dynamicCast(msgContainer->msg.in);                             assert(sipCmd != 0);                             Sptr<StatusMsg> statusMsg = new StatusMsg(*sipCmd, 400);                              Data reason = "Sequence number out of order";                             statusMsg->setReasonPhrase(reason);		             msgContainer->msg.in = statusMsg;                             msgContainer->msg.type = statusMsg->getType();                             msgContainer->msg.transport = statusMsg->getVia(0).getTransport();		             msgContainer->msg.out = "";	                     msgContainer->retransCount = 1;                                                  if(topNode)                               topNode->lock.unlock();                             processSend(statusMsg);                             return 0;                        }                    }                 }                 else                 {                     level2Node->seqNumber = msgSeqNumber;                     level2Node->seqSet = true;                     cpLog(LOG_DEBUG_STACK, "***** Setting seq to %d for callId %s", msgSeqNumber, msgContainer->msg.in->getCallId().encode().logData());                 }            }#endif	    nodePtr->val->msgs.request = msgContainer;	    nodePtr->val->msgs.request->level3Ptr = nodePtr->val;	    /// construct the msg queue to be sent up to application	    retVal = new SipMsgQueue;	    if(msgContainer->msg.in->getType() == SIP_ACK)	    {		SipTransactionList<SipTransLevel3Node *>::SipTransListNode		    *curr = level2Node->level3.getLast();		while(curr)		{		    /// look for the INVITE message		    if(curr->val->myKey == INVITE_METHOD)			break;		    curr = level2Node->level3.getPrev(curr);		}		if( !curr )                {		    cpLog(LOG_DEBUG_STACK,"No INVITE, try without Via branch");		    curr = topNode->findLevel3AckInvite( id );                }		if(curr)		{		    cpLog(LOG_DEBUG_STACK,"Found INVITE");                    // add the other items of this transaction, and                    // reduce memory usage by clearing the parsed                    // message in the in pointer		    if(curr->val->msgs.request)                    {			retVal->push_back(curr->val->msgs.request->msg.in);                        curr->val->msgs.request->msg.in = 0;                    }		    if(curr->val->msgs.response)                    {			retVal->push_back(curr->val->msgs.response->msg.in);                        curr->val->msgs.response->msg.in = 0;                    }		    /// also cancel the retrans of response		    cancel(curr->val->msgs.response);		    cpLog(DEBUG_NEW_STACK,"Stopping retrans of response[%s]",			  curr->val->myKey.logData());		}		else		{		    cpLog(LOG_DEBUG_STACK,"INVITE not Found");		    /////////// ACK w/o INVITE !!!!		    ////////// (may have been gc'd)		}	    }	    retVal->push_back(msgContainer->msg.in);	    /// also inform the cleanup            if(msgContainer->msg.in->getType() != SIP_INVITE)            {                SipTransactionGC::instance()->                    collect(nodePtr->val->msgs.request,                            MESSAGE_CLEANUP_DELAY);            }            msgContainer->msg.in = 0;	}    }    /// release the lock acquired on top level node    if(topNode)    {        topNode->lock.unlock();    }    return retVal;}SipTransLevel1Node*SipSentResponseDB::getTopNode(const SipTransactionId& id,                               const Sptr<SipMsg>& msg){    SipTransHashTable::SipTransRWLockHelper helper;    SipTransHashTable::Node * bktNode;    if(msg->getType()==SIP_STATUS)    {	/// this finds if there's a transaction, and locks for READ	bktNode = table.find(id.getLevel1(), &helper);	if(bktNode)	  if(bktNode->myNode->toTag == NOVAL)	  {              // this is the first response going out for this call              // leg, hence / update the state info with To tag              bktNode->myNode->toTag = msg->getTo().getTag();	  }	  else	  {	    /// make sure that response has the To tag same as previous	    /// responses for this call leg	    if(bktNode->myNode->toTag != msg->getTo().getTag())	      {		cpLog(LOG_DEBUG_STACK,		      "To tag of outgoing %d[%s] %s [%s] is incorrect",                      msg->getType(),		      msg->getTo().getTag().logData(),		      "in existing transaction",		      bktNode->myNode->toTag.logData());                if(SipTransceiver::myAppContext != APP_CONTEXT_PROXY)                {                    SipTo to = msg->getTo();		    cpLog(LOG_DEBUG, "Setting to-tag of outgoing response from=%s to=%s", to.getTag().logData(), bktNode->myNode->toTag.logData() );                    to.setTag(bktNode->myNode->toTag);                    msg->setTo(to);                }	      }	  }    }    else    {	// this creates a new transaction, if none exists, and locks	// for write otherwise just returns the existing transaction	// with read lock	bktNode = table.findOrInsert(id.getLevel1(), &helper);	if(bktNode->myNode == 0)	{	    bktNode->myNode = new SipTransLevel1Node();	    bktNode->myNode->bucketNode = bktNode;	}	/// if there's a transaction, then check the to tag	else if((bktNode->myNode->toTag!= NOVAL) &&		(bktNode->myNode->toTag != msg->getTo().getTag()))	{	    cpLog(LOG_DEBUG_STACK,"To tag of incoming %d[%s] %s [%s] is incorrect",		  msg->getType(),		  msg->getTo().getTag().logData(),		  "in existing transaction",		  bktNode->myNode->toTag.logData());	}    }    if(bktNode)    {	// acquire a lock on the top level node, before releasing the	// bucket node: due to race w/ cleanup thread!!!	bktNode->myNode->lock.lock();	return bktNode->myNode;    }    else	return 0;}/* Local Variables: *//* c-file-style: "stroustrup" *//* indent-tabs-mode: nil *//* c-file-offsets: ((access-label . -) (inclass . ++)) *//* c-basic-offset: 4 *//* End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -