📄 cpcallmanager.cpp
字号:
CpCallManager& CpCallManager::operator=(const CpCallManager& rhs){ if (this == &rhs) // handle the assignment to self case return *this; // Copy of call manager not supported assert(0); return *this;}void CpCallManager::getNewCallId(UtlString* callId){ getNewCallId(mCallIdPrefix, callId);}void CpCallManager::getNewSessionId(UtlString* callId){ getNewCallId("session", callId);}// This implements a new strategy for generating Call-IDs after the// problems described in http://track.sipfoundry.org/browse/XCL-51.//// The Call-ID is composed of several fields:// - a prefix supplied by the caller// - a counter// - the Process ID// - a start time, to microsecond resolution// (when getNewCallId was first called)// - the host's name or IP address// The last three fields are hashed, and the first 16 characters// are used to represent them.//// The host name, process ID, start time, and counter together ensure// uniqueness. The start time is used to microsecond resolution// because on Windows process IDs can be recycled quickly. The// counter is a long-long-int because at a high ID generation rate// (1000 per second), an int counter can roll over in less than a// month.//// Replacing the final three fields with the first 16 characters of// their MD5 hash shortens the generated Call-IDs, as the last three// fields can easily exceed 30 characters. Retaining 16 characters// (64 bits) should ensure no collisions until the number of// concurrent calls reaches 2^32.//// The sections of the Call-ID are separated with "/" because those// cannot otherwise appear in the final components, and so a generated// Call-ID can be unambiguously parsed into its components from back// to front, regardless of the user-supplied prefix, which ensures// that regardless of the prefix, this function can never generate// duplicate Call-IDs.//// The generated Call-IDs are "words" according to the syntax of RFC// 3261. We do not append "@host" for simplicity. The callIdPrefix// is assumed to contain only "word" characters, but we check to// ensure that "@" does not appear because the earlier version of this// routine checked for "@" and replaced it with "_". The earlier// version checked whether the host name contained "@" and replaced it// with "_", but this version replaces it with "*". The earlier// version also checked whether the host name contained ":" and// replaced it with "_", but I do not see why, as ":" is a "word"// character. This version does not.//// The counter mCallNum is incremented by 19560001 rather than 1 so// that successive Call-IDs differ in more than 1 character, and so// hash better. This does not reduce the cycle time of the counter,// since 19560001 is relatively prime to the limit of a long-long-int,// 2^64. Because the increment ends in "0001", the final four digits// of this field of the Call-ID count in a human-readable way.//// Ideally, Call-IDs would have crypto-quality randomness (as// recommended in RFC 3261 section 8.1.1.4), but the previous version// did not either.void CpCallManager::getNewCallId(const char* callIdPrefix, UtlString* callId){ // Lock to protect mCallNum. OsLock lock(mCallNumMutex); // Buffer in which we will compose the new Call-ID. char buffer[256]; // Static information that is initialized once. static UtlString suffix; // Flag to record if the data has been initialized. static UtlBoolean initialized = FALSE; // Increment the call number. mCallNum += 19560001; // callID prefix shouldn't contain an @. if (strchr(callIdPrefix, '@') != NULL) { OsSysLog::add(FAC_CP, PRI_ERR, "CpCallManager::getNewCallId callIdPrefix='%s' contains '@'", callIdPrefix); } // If we haven't initialized yet, do so. if (!initialized) { // Get the start time. OsTime currentTime; OsDateTime::getCurTime(currentTime); // Get the process ID. PID processId; processId = OsProcess::getCurrentPID(); // Get the host identity. UtlString thisHost; OsSocket::getHostIp(&thisHost); // Ensure it does not contain @. thisHost.replace('@','*'); // Compose the static fields. // Force usecs. to be 6 digits withleading zeros so that we do not have to do 64 bit integer math // just to build a big unique string. sprintf(buffer, "%d/%ld%.6ld/%s", processId, currentTime.seconds(), currentTime.usecs(), thisHost.data()); // Hash them. NetMd5Codec encoder; encoder.encode(buffer, suffix); // Truncate the hash to 16 characters. suffix.remove(16); // Note initialization is done. initialized = TRUE; } // Compose the new Call-Id. sprintf(buffer, "%s/%lld/%s", callIdPrefix, mCallNum, suffix.data()); // Copy it to the destination. *callId = buffer;}CpCall* CpCallManager::findCall(const char* callId){ OsReadLock lock(mCallListMutex); UtlDListIterator callIterator(mCallList); CpCall* call = NULL; UtlInt* callCollectable = NULL; while ((callCollectable = (UtlInt*) callIterator())) { call = (CpCall*) callCollectable->getValue(); if(call && call->hasCallId(callId)) { break; } call = NULL; } return(call);}void CpCallManager::appendCall(CpCall* call){ OsWriteLock lock(mCallListMutex); UtlInt* callCollectable = new UtlInt((int)call); mCallList.append(callCollectable);}void CpCallManager::pushCall(CpCall* call){ OsWriteLock lock(mCallListMutex); UtlInt* callCollectable = new UtlInt((int)call); mCallList.insertAt(0, callCollectable);}void CpCallManager::setAddressForwarding(int size, PtAddressForwarding *pForwards){ if (size < 1) return; OsWriteLock lock(mAddressForwardMutex); if (mpAddressForwards == 0 && mAddressForwardingCnt == 0) { mpAddressForwards = new PtAddressForwarding[size]; mAddressForwardingCnt = size; for (int i = 0; i < size; i++) mpAddressForwards[i] = PtAddressForwarding(pForwards[i]); } else { // Dump the old list delete[] mpAddressForwards ; mpAddressForwards = NULL ; mAddressForwardingCnt = 0 ; // Create a new list if (size > 0) { mpAddressForwards = new PtAddressForwarding[size]; mAddressForwardingCnt = size; for (int k = 0; k < size; k++) mpAddressForwards[k] = PtAddressForwarding(pForwards[k]); } } for (int i = 0; i < mAddressForwardingCnt; i++) { int type = pForwards[i].mForwardingType; switch (type) { case PtAddressForwarding::FORWARD_ON_BUSY: mLineBusyBehavior = Connection::FORWARD_ON_BUSY; mSipForwardOnBusy = pForwards[i].mDestinationUrl; break; case PtAddressForwarding::FORWARD_ON_NOANSWER: { int timeout = pForwards[i].mNoAnswerTimeout; mLineAvailableBehavior = Connection::FORWARD_ON_NO_ANSWER; mForwardOnNoAnswer = pForwards[i].mDestinationUrl; if (timeout > 0) mNoAnswerTimeout = timeout; if (mNoAnswerTimeout <= 0) mNoAnswerTimeout = 24; } break; case PtAddressForwarding::FORWARD_UNCONDITIONALLY: mLineAvailableBehavior = Connection::FORWARD_UNCONDITIONAL; mForwardUnconditional = pForwards[i].mDestinationUrl; break; } }}void CpCallManager::cancelAddressForwarding(int size, PtAddressForwarding *pForwards){ mLineBusyBehavior = Connection::BUSY; mSipForwardOnBusy = OsUtil::NULL_OS_STRING; mLineAvailableBehavior = Connection::RING; mForwardOnNoAnswer = OsUtil::NULL_OS_STRING; mForwardUnconditional = OsUtil::NULL_OS_STRING; int i; OsWriteLock lock(mAddressForwardMutex); if (pForwards == 0) // cancel all address forwarding { delete[] mpAddressForwards ; mpAddressForwards = NULL ; mAddressForwardingCnt = 0 ; } else { if (mpAddressForwards && mAddressForwardingCnt > 0) { for (i = 0; i < size; i++) { for (int j = 0; j < mAddressForwardingCnt; j++) { if (*pForwards == (PtAddressForwarding&) mpAddressForwards[j]) { mAddressForwardingCnt--; for (int k = j; k < mAddressForwardingCnt; k++) mpAddressForwards[k] = mpAddressForwards[k + 1]; break; } } } if (mAddressForwardingCnt <= 0) { delete[] mpAddressForwards; mpAddressForwards = 0; mAddressForwardingCnt = 0; } } } for (i = 0; i < mAddressForwardingCnt; i++) { int type = pForwards[i].mForwardingType; switch (type) { case PtAddressForwarding::FORWARD_ON_BUSY: mLineBusyBehavior = Connection::FORWARD_ON_BUSY; mSipForwardOnBusy = pForwards[i].mDestinationUrl; break; case PtAddressForwarding::FORWARD_ON_NOANSWER: mLineAvailableBehavior = Connection::FORWARD_ON_NO_ANSWER; mForwardOnNoAnswer = pForwards[i].mDestinationUrl; if (mNoAnswerTimeout <= 0) mNoAnswerTimeout = 24; break; case PtAddressForwarding::FORWARD_UNCONDITIONALLY: mLineAvailableBehavior = Connection::FORWARD_UNCONDITIONAL; mForwardUnconditional = pForwards[i].mDestinationUrl; break; } }}void CpCallManager::setDoNotDisturb(int flag){ mDoNotDisturbFlag = flag;}void CpCallManager::setMessageWaiting(int flag){ mMsgWaitingFlag = flag;}void CpCallManager::setOfferedTimeout(int milisec){ mOfferedTimeOut = milisec;}/* ============================ ACCESSORS ================================= */int CpCallManager::getNewMetaEventId(){ mLastMetaEventId++; return(mLastMetaEventId);}/* ============================ INQUIRY =================================== */UtlBoolean CpCallManager::isCallStateLoggingEnabled(){ return(mCallStateLogEnabled);}/* //////////////////////////// PROTECTED ///////////////////////////////// */int CpCallManager::aquireCallIndex(){ int index = 0; UtlInt matchCallIndexColl; // Find the first unused slot UtlInt* existingCallIndex = NULL; do { index++; matchCallIndexColl.setValue(index); existingCallIndex = (UtlInt*) mCallIndices.find(&matchCallIndexColl); } while(existingCallIndex); // Insert the new one mCallIndices.insert(new UtlInt(matchCallIndexColl)); return(index);}void CpCallManager::releaseCallIndex(int callIndex){ if(callIndex > 0) { UtlInt matchCallIndexColl(callIndex); UtlInt* callIndexColl = NULL; callIndexColl = (UtlInt*) mCallIndices.remove(&matchCallIndexColl); if(callIndexColl) delete callIndexColl; callIndexColl = NULL; }}/* //////////////////////////// PRIVATE /////////////////////////////////// *//* ============================ FUNCTIONS ================================= */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -