📄 sipsentresponsedb.cxx
字号:
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 + -