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

📄 connection.cpp

📁 基于sipfoundy 公司开发的sipx协议API
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// // // Copyright (C) 2005-2006 SIPez LLC.// Licensed to SIPfoundry under a Contributor Agreement.// // Copyright (C) 2004-2006 SIPfoundry Inc.// Licensed by SIPfoundry under the LGPL license.// // Copyright (C) 2004-2006 Pingtel Corp.// Licensed to SIPfoundry under a Contributor Agreement.// // $$//////////////////////////////////////////////////////////////////////////////// Author: Dan Petrie (dpetrie AT SIPez DOT com) // SYSTEM INCLUDES// APPLICATION INCLUDES#include <cp/Connection.h>#include <cp/CpGhostConnection.h>#include <mi/CpMediaInterface.h>#include <cp/CpMultiStringMessage.h>#include <cp/CpCall.h>#include <net/SdpCodec.h>#include <net/SipSession.h>#include <os/OsLock.h>#include <os/OsMsg.h>#include <os/OsDatagramSocket.h>#include <os/OsServerTask.h>#include <os/OsQueuedEvent.h>#include <os/OsTimer.h>#include "os/OsDateTime.h"#include "os/OsUtil.h"#include <tao/TaoObjectMap.h>#include <tao/TaoReference.h>#include <tao/TaoListenerEventMessage.h>#include <ptapi/PtConnection.h>#include <net/TapiMgr.h>// EXTERNAL FUNCTIONS// EXTERNAL VARIABLES// CONSTANTS#define CONN_DELETE_DELAY_SECS  10    // Number of seconds to wait before a                                       // connection should be removed from a                                       // call and deleted.// STATIC VARIABLE INITIALIZATIONS/* //////////////////////////// PUBLIC //////////////////////////////////// *//* ============================ CREATORS ================================== */// ConstructorConnection::Connection(CpCallManager* callMgr,                       CpCall* call,                       CpMediaInterface* mediaInterface,                        //UiContext* callUiContext,                       int offeringDelayMilliSeconds,                       int availableBehavior,                        const char* forwardUnconditionalUrl,                       int busyBehavior, const char* forwardOnBusyUrl,                       int forwardOnNoAnswerSeconds)    : mConnectionId(-1)   , callIdMutex(OsMutex::Q_FIFO)   , mDeleteAfter(OsTime::OS_INFINITY){#ifdef TEST_PRINT    UtlString callId;    if (call) {       call->getCallId(callId);       OsSysLog::add(FAC_CP, PRI_DEBUG, "Connection constructed: %s\n", callId.data());    } else       OsSysLog::add(FAC_CP, PRI_DEBUG, "Connection constructed: call is Null\n");#endif    mOfferingDelay = offeringDelayMilliSeconds;    mLineAvailableBehavior = availableBehavior;    if(mLineAvailableBehavior == FORWARD_UNCONDITIONAL &&        forwardUnconditionalUrl != NULL)    {        mForwardUnconditional.append(forwardUnconditionalUrl);    }    mLineBusyBehavior = busyBehavior;    if(mLineBusyBehavior == FORWARD_ON_BUSY &&        forwardOnBusyUrl != NULL)    {        mForwardOnBusy.append(forwardOnBusyUrl);    }    mForwardOnNoAnswerSeconds = forwardOnNoAnswerSeconds;    mRemoteIsCallee = FALSE;	mRemoteRequestedHold = FALSE;    remoteRtpPort = PORT_NONE;    sendCodec = -1;    receiveCodec = -1;    mLocalConnectionState = CONNECTION_IDLE;    mRemoteConnectionState = CONNECTION_IDLE;    mConnectionStateCause = CONNECTION_CAUSE_NORMAL;    mTerminalConnState = PtTerminalConnection::IDLE;	mFarEndHoldState = TERMCONNECTION_NONE;	mResponseCode = 0;	    mResponseText.remove(0);    mpCallManager = callMgr;    mpCall = call;    mpMediaInterface = mediaInterface;    mConnectionId = -10;    //mpCallUiContext = callUiContext;	mpListenerCnt = new TaoReference();	mpListeners = new TaoObjectMap();    m_eLastMajor = (SIPX_CALLSTATE_EVENT) -1 ;    m_eLastMinor = (SIPX_CALLSTATE_CAUSE) -1 ;    m_eLastAudioMajor = (SIPX_CALLSTATE_EVENT) -1 ;    m_eLastAudioMinor = (SIPX_CALLSTATE_CAUSE) -1 ;    mpCallManager->getNewSessionId(this) ;#ifdef TEST_PRINT        if (!callId.isNull())       OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving Connection constructed: %s\n", callId.data());    else       OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving Connection constructed: call is Null\n");#endif}// Copy constructorConnection::Connection(const Connection& rConnection)     : UtlString(rConnection)       , callIdMutex(OsMutex::Q_FIFO){	mpListenerCnt = rConnection.mpListenerCnt;	mpListeners = rConnection.mpListeners;}// DestructorConnection::~Connection(){#ifdef TEST_PRINT     UtlString callId;    if (mpCall) {	   mpCall->getCallId(callId);       OsSysLog::add(FAC_CP, PRI_DEBUG, "Connection destructed: %s\n", callId.data());    } else       OsSysLog::add(FAC_CP, PRI_DEBUG, "Connection destructed: call is Null\n");#endif   if (	mpListenerCnt )   {	   delete mpListenerCnt;	   mpListenerCnt = 0;   }   if (	mpListeners )   {	   delete mpListeners;	   mpListeners = 0;   }#ifdef TEST_PRINT     if (!callId.isNull())       OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving Connection destructed: %s\n", callId.data());    else       OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving Connection destructed: call is Null\n");#endif}/* ============================ MANIPULATORS ============================== */void Connection::prepareForSplit() {    if ((mpMediaInterface) && (mConnectionId != -1))    {        mpMediaInterface->deleteConnection(mConnectionId) ;    }    mpCall = NULL ;    mpMediaInterface = NULL ;    mConnectionId = -1 ;}void Connection::prepareForJoin(CpCall* pNewCall, CpMediaInterface* pNewMediaInterface) {    mpCall = pNewCall ;    mpMediaInterface = pNewMediaInterface ;    mpMediaInterface->createConnection(mConnectionId, NULL) ;    // VIDEO: Need to include window handle!}void Connection::setState(int newState, int isLocal, int newCause, int termState){   UtlString oldStateString;   UtlString newStateString;   int currentState = isLocal ? mLocalConnectionState : mRemoteConnectionState;   getStateString(currentState, &oldStateString);   getStateString(newState, &newStateString);   int metaEventId = 0;   int metaEventType = PtEvent::META_EVENT_NONE;   int numCalls = 0;   const UtlString* metaEventCallIds = NULL;   if (mpCall)   {      mpCall->getMetaEvent(metaEventId, metaEventType, numCalls,                           &metaEventCallIds);   }   UtlString callId;   if (mpCall) {      mpCall->getCallId(callId);   }   if (callId.isNull())      callId="null";   UtlString strCallName;   if (mpCall) {      strCallName = mpCall->getName();   }   if (strCallName.isNull())   {      strCallName="null";   }   if (!isStateTransitionAllowed(newState, currentState))   {      // Under some conditions, "invalid" state changes are allowed.      if (!(!isLocal && metaEventId > 0 && metaEventType == PtEvent::META_CALL_TRANSFERRING))      {         if (newState == currentState)         {            OsSysLog::add(FAC_CP, PRI_DEBUG, "Connection::setState: "                          "Questionable connection state change - isLocal %d, for call "                          "'%s' with callid '%s' from %s to %s, cause %d",                          isLocal, strCallName.data(), callId.data(),                          oldStateString.data(), newStateString.data(), newCause);         }         else         {            OsSysLog::add(FAC_CP, PRI_ERR, "Connection::setState: "                          "Invalid connection state change - isLocal %d, for call "                          "'%s' with callid '%s' from %s to %s, cause %d",                          isLocal, strCallName.data(), callId.data(),                          oldStateString.data(), newStateString.data(), newCause);         }         return;      }   }   UtlBoolean bPostStateChange = FALSE;   if (newState != currentState || newCause != CONNECTION_CAUSE_NORMAL)   {      if (isLocal && newState == CONNECTION_DISCONNECTED)      {         if ((mpCall->canDisconnectConnection(this) || newCause == CONNECTION_CAUSE_CANCELLED) &&             metaEventType != PtEvent::META_CALL_TRANSFERRING)         {            bPostStateChange = TRUE;         }      }      else      {         bPostStateChange = TRUE;      }   }   OsSysLog::add(FAC_CP, PRI_DEBUG,                 "Call %s %s state isLocal %d\nchange\nfrom %s to\n\t %s\ncause=%d\npost change to upper layer %d",            strCallName.data(),            callId.data(),            isLocal,            oldStateString.data(),            newStateString.data(),            newCause,            bPostStateChange);   if (bPostStateChange)   {      mConnectionStateCause = newCause;      mTerminalConnState = termState == -1 ? terminalConnectionState(newState) : termState;      if (isLocal)      {         mLocalConnectionState = newState;      }      else      {         mRemoteConnectionState = newState;      }      postTaoListenerMessage(newState, newCause, isLocal);   }}void Connection::setTerminalConnectionState(int newState, int isLocal, int newCause){	mTerminalConnState = newState;	mConnectionStateCause = newCause;}   #if 1int Connection::getState(int isLocal) const{   int state;      if (mRemoteIsCallee)      state = mRemoteConnectionState;        else      state = mLocalConnectionState;   if ((mLocalConnectionState == CONNECTION_FAILED) &&       state != mLocalConnectionState)   {      UtlString oldStateString, newStateString;      getStateString(mLocalConnectionState, &oldStateString);      getStateString(state, &newStateString);      state = mLocalConnectionState;   }    else if ((mRemoteConnectionState == CONNECTION_FAILED) &&            mRemoteConnectionState != state)   {      UtlString oldStateString, newStateString;      getStateString(mRemoteConnectionState, &oldStateString);      getStateString(state, &newStateString);      state = mRemoteConnectionState;   }   return state;}#endif /* 1 */int Connection::getState(int isLocal, int& cause) const{   cause = mConnectionStateCause;   int state;   if (isLocal)      state = mLocalConnectionState;   else      state = mRemoteConnectionState;   if ((mLocalConnectionState == CONNECTION_FAILED) &&       state != mLocalConnectionState)   {      UtlString oldStateString, newStateString;      getStateString(mLocalConnectionState, &oldStateString);      getStateString(state, &newStateString);      state = mLocalConnectionState;   }    else if ((mRemoteConnectionState == CONNECTION_FAILED) &&            mRemoteConnectionState != state)   {      UtlString oldStateString, newStateString;      getStateString(mRemoteConnectionState, &oldStateString);      getStateString(state, &newStateString);      state = mRemoteConnectionState;   }   return state;}int Connection::getTerminalState(int isLocal) const{	int state;	state = mTerminalConnState;	return state;}void Connection::getStateString(int state, UtlString* stateLabel){	stateLabel->remove(0);	switch(state)	{	case CONNECTION_IDLE:		stateLabel->append("CONNECTION_IDLE");		break;		case CONNECTION_INITIATED:		stateLabel->append("CONNECTION_INITIATED");		break;	case CONNECTION_QUEUED:		stateLabel->append("CONNECTION_QUEUED");		break;	case CONNECTION_OFFERING:		stateLabel->append("CONNECTION_OFFERING");		break;	case CONNECTION_ALERTING:		stateLabel->append("CONNECTION_ALERTING");		break;	case CONNECTION_ESTABLISHED:		stateLabel->append("CONNECTION_ESTABLISHED");		break;	case CONNECTION_FAILED:		stateLabel->append("CONNECTION_FAILED");		break;	case CONNECTION_DISCONNECTED:		stateLabel->append("CONNECTION_DISCONNECTED");		break;	case CONNECTION_DIALING:		stateLabel->append("CONNECTION_DIALING");		break;	default:		stateLabel->append("CONNECTION_UNKNOWN");		break;	}}// Assignment operatorConnection& Connection::operator=(const Connection& rhs){   if (this == &rhs)            // handle the assignment to self case      return *this;   return *this;}void Connection::setLocalAddress(const char* address){	OsLock lock(callIdMutex);	mLocalAddress.remove(0);	mLocalAddress.append(address);}void Connection::unimplemented(const char* methodName) const{    osPrintf("%s NO IMPLEMENTED\n",methodName);}// Is this connection marked for deletion?void Connection::markForDeletion() {   OsTime timeNow ;   OsTime deleteAfterSecs(CONN_DELETE_DELAY_SECS, 0) ;      OsDateTime::getCurTimeSinceBoot(deleteAfterSecs) ;     mDeleteAfter = timeNow + deleteAfterSecs ;}void Connection::setMediaInterface(CpMediaInterface* pMediaInterface) {        if ((mpMediaInterface) && (mConnectionId != -1))    {       mpMediaInterface->deleteConnection( mConnectionId );    }    mConnectionId = -1;    mpMediaInterface = pMediaInterface ;}UtlBoolean Connection::validStateTransition(SIPX_CALLSTATE_EVENT eFrom, SIPX_CALLSTATE_EVENT eTo){    UtlBoolean bValid = TRUE ;    switch (eFrom)    {        case DISCONNECTED:            bValid = (eTo == DESTROYED) ;            break ;        case DESTROYED:            bValid = FALSE ;            break ;        default:            break;    }    // Make sure a local focus change doesn't kick off an established event    if ((eTo == CONNECTED) && (getLocalState() != CONNECTION_ESTABLISHED))    {        bValid = FALSE ;    }    return bValid ;}void Connection::fireSipXEvent(SIPX_CALLSTATE_EVENT eventCode,                                SIPX_CALLSTATE_CAUSE causeCode,                                void* pEventData,                               const char* assertedRemoteIdentity) {    UtlString callId ;    UtlString remoteAddress ;    SipSession session ;    UtlBoolean bDuplicateAudio =            (eventCode == CALLSTATE_AUDIO_EVENT && causeCode == m_eLastAudioMinor) ? TRUE : FALSE;    // Avoid sending duplicate events    if ((   (eventCode != m_eLastMajor) || (causeCode != m_eLastMinor)) &&             validStateTransition(m_eLastMajor, eventCode) && !bDuplicateAudio)    {        if (eventCode == CALLSTATE_AUDIO_EVENT)        {            m_eLastAudioMajor = eventCode;            m_eLastAudioMinor = causeCode;        }        else if(eventCode == CALLSTATE_IDENTITY_CHANGE)        {            // Do not cache the asserted identity change as it            // should always be sent through.  Also do not cache so            // we do not duplicate other event types (e.g.            // CALLSTATE_FOO, CALLSTATE_IDENTITY_CHANGE, CALLSTATE_FOO            // should not notify CALLSTATE_FOO twice        }        else        {            m_eLastMajor = eventCode;            m_eLastMinor = causeCode;        }        getCallId(&callId) ;        getRemoteAddress(&remoteAddress);        getSession(session) ;        TapiMgr::getInstance().fireCallEvent(mpCallManager,                                              callId.data(),                                              &session,                                              remoteAddress.data(),                                              eventCode,                                              causeCode,                                              pEventData,                                             assertedRemoteIdentity);    }}/* ============================ ACCESSORS ================================= */void Connection::getLocalAddress(UtlString* address){	*address = mLocalAddress;

⌨️ 快捷键说明

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