📄 callmanager.cpp
字号:
// // // Copyright (C) 2005, 2006 SIPez LLC// Licensed to SIPfoundry under a Contributor Agreement.//// Copyright (C) 2005, 2006 SIPfoundry Inc.// Licensed by SIPfoundry under the LGPL license.// // Copyright (C) 2004, 2005 Pingtel Corp.// Licensed to SIPfoundry under a Contributor Agreement.// // $$//////////////////////////////////////////////////////////////////////////////// Author: Dan Petrie (dpetrie AT SIPez DOT com)// SYSTEM INCLUDES#include <time.h>#include <assert.h>// APPLICATION INCLUDES#include <cp/CallManager.h>#include <net/SipMessageEvent.h>#include <net/SipUserAgent.h>#include <net/SdpCodec.h>#include <net/SdpCodecFactory.h>#include <net/Url.h>#include <net/SipSession.h>#include <net/SipDialog.h>#include <net/SipLineMgr.h>#include <cp/CpIntMessage.h>#include <cp/CpStringMessage.h>#include <cp/CpMultiStringMessage.h>#include <cp/Connection.h>#include <mi/CpMediaInterfaceFactory.h>#include <utl/UtlRegex.h>#include <os/OsUtil.h>#include <os/OsConfigDb.h>#include <os/OsEventMsg.h>#include <os/OsTimer.h>#include <os/OsQueuedEvent.h>#include <os/OsEvent.h>#include <os/OsReadLock.h>#include <os/OsWriteLock.h>#include <net/NameValueTokenizer.h>#include <cp/CpPeerCall.h>#include "tao/TaoMessage.h"#include "tao/TaoProviderAdaptor.h"#include "tao/TaoString.h"#include "tao/TaoPhoneComponentAdaptor.h"#ifndef EXCLUDE_STREAMING#include "ptapi/PtCall.h"#include "ptapi/PtEvent.h"#endif// TO_BE_REMOVED#ifndef EXCLUDE_STREAMING#include "mp/MpPlayer.h"#include "mp/MpStreamMsg.h"#include "mp/MpStreamPlayer.h"#include "mp/MpStreamQueuePlayer.h"#include "mp/MpStreamPlaylistPlayer.h"#include <mp/MpMediaTask.h> #endif// EXTERNAL FUNCTIONS// EXTERNAL VARIABLES// CONSTANTS#define MAXIMUM_CALLSTATE_LOG_SIZE 100000#define CALL_STATUS_FIELD "status"#define SEND_KEY '#'char CONVERT_TO_STR[17] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','*', '#', 'A', 'B', 'C', 'D', 'F'};/* _________________________0--9 0--9* 10# 11A--D 12--15Flash 16*/// STATIC VARIABLE INITIALIZATIONS/* //////////////////////////// PUBLIC //////////////////////////////////// *//* ============================ CREATORS ================================== */// ConstructorCallManager::CallManager(UtlBoolean isRequredUserIdMatch, SipLineMgr* pLineMgrTask, UtlBoolean isEarlyMediaFor180Enabled, SdpCodecFactory* pCodecFactory, int rtpPortStart, int rtpPortEnd, const char* localAddress, const char* publicAddress, SipUserAgent* userAgent, int sipSessionReinviteTimer, void* mgcpStackTask, // Depricated const char* defaultCallExtension, int availableBehavior, const char* unconditionalForwardUrl, int forwardOnNoAnswerSeconds, const char* forwardOnNoAnswerUrl, int busyBehavior, const char* sipForwardOnBusyUrl, OsConfigDb* pConfigDb, CallTypes phonesetOutgoingCallProtocol, int numDialPlanDigits, int holdType, int offeringDelay, const char* locale, int inviteExpireSeconds, int expeditedIpTos, int maxCalls, CpMediaInterfaceFactory* pMediaFactory) : CpCallManager("CallManager-%d", "call", rtpPortStart, rtpPortEnd, localAddress, publicAddress) , mIsEarlyMediaFor180(TRUE) , mpMediaFactory(NULL){ dialing = FALSE; mOffHook = FALSE; speakerOn = FALSE; flashPending = FALSE; mIsEarlyMediaFor180 = isEarlyMediaFor180Enabled; mNumDialPlanDigits = numDialPlanDigits; mHoldType = holdType; mnTotalIncomingCalls = 0; mnTotalOutgoingCalls = 0; mMaxCalls = maxCalls ; mDelayInDeleteCall = 0; if (pMediaFactory) { mpMediaFactory = pMediaFactory; } else { assert(false); } // Instruct the factory to use the specified port range mpMediaFactory->getFactoryImplementation()->setRtpPortRange(rtpPortStart, rtpPortEnd) ; mStunServer = NULL; mLineAvailableBehavior = availableBehavior; mOfferedTimeOut = offeringDelay; mNoAnswerTimeout = forwardOnNoAnswerSeconds; if(forwardOnNoAnswerUrl) { mForwardOnNoAnswer = forwardOnNoAnswerUrl; if (mNoAnswerTimeout < 0) mNoAnswerTimeout = 24; // default } if(unconditionalForwardUrl) mForwardUnconditional = unconditionalForwardUrl; mLineBusyBehavior = busyBehavior; if(sipForwardOnBusyUrl) { mSipForwardOnBusy.append(sipForwardOnBusyUrl); }#ifdef TEST OsSysLog::add(FAC_CP, PRI_DEBUG, "SIP forward on busy URL: %s\nSIP unconditional forward URL: %s\nSIP no answer timeout:%d URL: %s\n", mSipForwardOnBusy.data(), mForwardUnconditional.data(), forwardOnNoAnswerSeconds, mForwardOnNoAnswer.data());#endif mLocale = locale ? locale : ""; if (inviteExpireSeconds > 0 && inviteExpireSeconds < CP_MAXIMUM_RINGING_EXPIRE_SECONDS) mInviteExpireSeconds = inviteExpireSeconds; else mInviteExpireSeconds = CP_MAXIMUM_RINGING_EXPIRE_SECONDS; mpLineMgrTask = pLineMgrTask; mIsRequredUserIdMatch = isRequredUserIdMatch; mExpeditedIpTos = expeditedIpTos; // Register with the SIP user agent sipUserAgent = userAgent; if(sipUserAgent) { sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_INVITE_METHOD, TRUE, // want to get requests TRUE, // and responses TRUE, // Incoming messages FALSE); // Don't want to see out going messages sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_BYE_METHOD, TRUE, // want to get requests TRUE, // and responses TRUE, // Incoming messages FALSE); // Don't want to see out going messages sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_CANCEL_METHOD, TRUE, // want to get requests TRUE, // and responses TRUE, // Incoming messages FALSE); // Don't want to see out going messages sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_ACK_METHOD, TRUE, // want to get requests FALSE, // no such thing as a ACK response TRUE, // Incoming messages FALSE); // Don't want to see out going messages sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_REFER_METHOD, TRUE, // want to get requests TRUE, // and responses TRUE, // Incoming messages FALSE); // Don't want to see out going messages sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_OPTIONS_METHOD, FALSE, // don't want to get requests TRUE, // do want responses TRUE, // Incoming messages FALSE); // Don't want to see out going messages sipUserAgent->addMessageObserver(*(this->getMessageQueue()), SIP_NOTIFY_METHOD, TRUE, // do want to get requests TRUE, // do want responses TRUE, // Incoming messages FALSE); // Don't want to see out going messages // Allow the "replaces" extension, because CallManager // implements the INVITE-with-Replaces logic. sipUserAgent->allowExtension(SIP_REPLACES_EXTENSION); int sipExpireSeconds = sipUserAgent->getDefaultExpiresSeconds(); if (mInviteExpireSeconds > sipExpireSeconds) mInviteExpireSeconds = sipExpireSeconds; } mSipSessionReinviteTimer = sipSessionReinviteTimer; if(defaultCallExtension) { mOutboundLine = defaultCallExtension; } infocusCall = NULL; mOutGoingCallType = phonesetOutgoingCallProtocol; mLocalAddress = localAddress;#ifdef TEST_PRINT OsSysLog::add(FAC_CP, PRI_DEBUG, "CallManager: localAddress: %s mLocalAddress: %s publicAddress: %s mPublicAddress %s\n", localAddress, mLocalAddress.data(), publicAddress, mPublicAddress.data());#endif mpCodecFactory = pCodecFactory;#ifdef TEST_PRINT // Default the log on startCallStateLog();#else // Disable the message log stopCallStateLog();#endif mListenerCnt = 0; mMaxNumListeners = 20; mpListeners = (TaoListenerDb**)malloc(sizeof(TaoListenerDb *)*mMaxNumListeners); if (!mpListeners) { OsSysLog::add(FAC_CP, PRI_ERR, "Unable to allocate listeners\n"); return; } for (int i = 0; i < mMaxNumListeners; i++) mpListeners[i] = 0; // Pre-allocate all of the history memory to minimze fragmentation for(int h = 0; h < CP_CALL_HISTORY_LENGTH ; h++) mCallManagerHistory[h].capacity(256); mMessageEventCount = -1; mStunOptions = 0 ; mStunKeepAlivePeriodSecs = 0 ;}// Copy constructorCallManager::CallManager(const CallManager& rCallManager) :CpCallManager("CallManager-%d", "call"){}// DestructorCallManager::~CallManager(){ waitUntilShutDown(); if(sipUserAgent) { delete sipUserAgent; sipUserAgent = NULL; } while(getCallStackSize()) { delete popCall(); } if (mMaxNumListeners > 0) // check if listener exists. { for (int i = 0; i < mListenerCnt; i++) { if (mpListeners[i]) { delete mpListeners[i]; mpListeners[i] = 0; } } free(mpListeners); } // do not delete the codecFactory it is not owned here}/* ============================ MANIPULATORS ============================== */void CallManager::setOutboundLine(const char* lineUrl){ mOutboundLine = lineUrl ? lineUrl : "";}OsStatus CallManager::addTaoListener(OsServerTask* pListener, char* callId, int ConnectId, int mask){ OsReadLock lock(mCallListMutex); OsStatus rc = OS_UNSPECIFIED; if (callId) { CpCall* handlingCall = findHandlingCall(callId); if (handlingCall) { handlingCall->addTaoListener(pListener, callId, ConnectId, mask); rc = OS_SUCCESS; } } else { if (infocusCall) { infocusCall->addTaoListener(pListener, callId, ConnectId, mask); rc = OS_SUCCESS; } if (!callStack.isEmpty()) { // Create an iterator to sequence through callStack. UtlSListIterator iterator(callStack); UtlInt* callCollectable; CpCall* call; callCollectable = (UtlInt*)iterator(); while (callCollectable) { call = (CpCall*)callCollectable->getValue(); if (call)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -