📄 sipxtapiinternal.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.// // $$//////////////////////////////////////////////////////////////////////////////// SYSTEM INCLUDES#include <assert.h>// APPLICATION INCLUDES#include "net/SipUserAgent.h"#include "cp/CallManager.h"#include "net/SipLineMgr.h"#include "net/SipRefreshMgr.h"#include "net/SipSubscribeClient.h"#include "utl/UtlHashMap.h"#include "utl/UtlHashMapIterator.h"#include "utl/UtlString.h"#include "utl/UtlInt.h"#include "utl/UtlVoidPtr.h"#include "utl/UtlString.h"#include "utl/UtlDListIterator.h"#include "os/OsLock.h"#include "tapi/sipXtapi.h"#include "tapi/sipXtapiEvents.h"#include "tapi/sipXtapiInternal.h"#include "tapi/SipXHandleMap.h"#include "net/Url.h"#include "net/SipUserAgent.h"#include "cp/CallManager.h"#include "mi/CpMediaInterfaceFactory.h"// EXTERNAL FUNCTIONS// EXTERNAL VARIABLESextern UtlSList* g_pEventListeners ;extern OsMutex* g_pEventListenerLock ;// CONSTANTS// STATIC VARIABLE INITIALIZATIONS// GLOBAL VARIABLESSipXHandleMap* gpCallHandleMap = new SipXHandleMap(); /**< Global Map of call handles */SipXHandleMap* gpLineHandleMap = new SipXHandleMap() ; /**< Global Map of line handles */SipXHandleMap* gpConfHandleMap = new SipXHandleMap() ; /**< Global Map of conf handles */SipXHandleMap* gpInfoHandleMap = new SipXHandleMap() ; /**< Global Map of info handles */SipXHandleMap* gpPubHandleMap = new SipXHandleMap() ; /**< Global Map of Published (subscription server) event data handles */SipXHandleMap* gpSubHandleMap = new SipXHandleMap() ; /**< Global Map of Subscribed (client) event data handles */UtlDList* gpSessionList = new UtlDList() ; /**< List of sipX sessions (to be replaced by handle map in the future */OsMutex* gpSessionLock = new OsMutex(OsMutex::Q_FIFO);static int gSessions = 0;/* //////////////////////////// PUBLIC //////////////////////////////////// *//* ============================ CREATORS ================================== *//* ============================ MANIPULATORS ============================== *//* ============================ ACCESSORS ================================= *//* ============================ INQUIRY =================================== *//* //////////////////////////// PROTECTED ///////////////////////////////// *//* //////////////////////////// PRIVATE /////////////////////////////////// *//* ============================ FUNCTIONS ================================= */SIPX_CALL sipxCallLookupHandle(const UtlString& callID, const void* pSrc){ gpCallHandleMap->lock() ; UtlHashMapIterator iter(*gpCallHandleMap); UtlInt* pIndex = NULL; UtlVoidPtr* pObj = NULL; SIPX_CALL hCall = 0 ; while (pIndex = dynamic_cast<UtlInt*>( iter() ) ) { pObj = dynamic_cast<UtlVoidPtr*>(gpCallHandleMap->findValue(pIndex)); SIPX_CALL_DATA* pData = NULL ; if (pObj) { pData = (SIPX_CALL_DATA*) pObj->getValue() ; } if (pData && (pData->callId->compareTo(callID) == 0 || (pData->sessionCallId && (pData->sessionCallId->compareTo(callID) == 0))) && pData->pInst->pCallManager == pSrc) { hCall = pIndex->getValue() ; break ; } } gpCallHandleMap->unlock() ; return hCall;}void sipxCallObjectFree(const SIPX_CALL hCall){ SIPX_CALL_DATA* pData = sipxCallLookup(hCall, SIPX_LOCK_WRITE) ; if (pData) { const void* pRC = gpCallHandleMap->removeHandle(hCall); if (pRC) { destroyCallData(pData) ; } else { sipxCallReleaseLock(pData, SIPX_LOCK_WRITE) ; } }}SIPX_CALL_DATA* sipxCallLookup(const SIPX_CALL hCall, SIPX_LOCK_TYPE type){ SIPX_CALL_DATA* pRC ; gpCallHandleMap->lock() ; pRC = (SIPX_CALL_DATA*) gpCallHandleMap->findHandle(hCall) ; if (validCallData(pRC)) { switch (type) { case SIPX_LOCK_READ: // TODO: What happens if this fails? pRC->pMutex->acquireRead() ; break ; case SIPX_LOCK_WRITE: // TODO: What happens if this fails? pRC->pMutex->acquireWrite() ; break ; } } else { pRC = NULL ; } gpCallHandleMap->unlock() ; return pRC ;}UtlBoolean validCallData(SIPX_CALL_DATA* pData){ return (pData && pData->callId && pData->lineURI && pData->pInst && pData->pInst->pCallManager && pData->pInst->pRefreshManager && pData->pInst->pLineManager && pData->pMutex) ;}void sipxCallReleaseLock(SIPX_CALL_DATA* pData, SIPX_LOCK_TYPE type) { if ((type != SIPX_LOCK_NONE) && validCallData(pData)) { switch (type) { case SIPX_LOCK_READ: // TODO: What happens if this fails? pData->pMutex->releaseRead() ; break ; case SIPX_LOCK_WRITE: // TODO: What happens if this fails? pData->pMutex->releaseWrite() ; break ; } }}UtlBoolean sipxCallGetCommonData(SIPX_CALL hCall, SIPX_INSTANCE_DATA** pInst, UtlString* pStrCallId, UtlString* pStrRemoteAddress, UtlString* pLineId, UtlString* pGhostCallId) { UtlBoolean bSuccess = FALSE ; SIPX_CALL_DATA* pData = sipxCallLookup(hCall, SIPX_LOCK_READ); if (pData) { if (pInst) { *pInst = pData->pInst ; } if (pStrCallId) { if (pData->sessionCallId) { *pStrCallId = *pData->sessionCallId ; } else { *pStrCallId = *pData->callId ; } } if (pStrRemoteAddress) { if (pData->remoteAddress) { *pStrRemoteAddress = *pData->remoteAddress ; } else { pStrRemoteAddress->remove(0) ; } } if (pLineId) { *pLineId = *pData->lineURI ; } if (pGhostCallId) { if (pData->ghostCallId) { *pGhostCallId = *pData->ghostCallId; } } bSuccess = TRUE ; sipxCallReleaseLock(pData, SIPX_LOCK_READ) ; } return bSuccess ;}SIPX_CONF sipxCallGetConf(SIPX_CALL hCall) { SIPX_CONF hConf = 0 ; SIPX_CALL_DATA* pData = sipxCallLookup(hCall, SIPX_LOCK_READ); if (pData) { hConf = pData->hConf ; sipxCallReleaseLock(pData, SIPX_LOCK_READ) ; } return hConf ;}UtlBoolean sipxCallGetState(SIPX_CALL hCall, SIPX_CALLSTATE_EVENT& lastEvent, SIPX_CALLSTATE_CAUSE& lastCause, SIPX_INTERNAL_CALLSTATE& state) { UtlBoolean bSuccess = false ; SIPX_CALL_DATA* pData = sipxCallLookup(hCall, SIPX_LOCK_READ); if (pData) { lastEvent = pData->lastCallstateEvent ; lastCause = pData->lastCallstateCause ; state = pData->state ; sipxCallReleaseLock(pData, SIPX_LOCK_READ) ; bSuccess = true; } return bSuccess ;}UtlBoolean sipxCallSetState(SIPX_CALL hCall, SIPX_CALLSTATE_EVENT event, SIPX_CALLSTATE_CAUSE cause) { UtlBoolean bSuccess = false ; SIPX_CALL_DATA* pData = sipxCallLookup(hCall, SIPX_LOCK_WRITE); if (pData) { // Store state pData->lastCallstateEvent = event ; pData->lastCallstateCause = cause ; // Calculate internal state switch (event) { case CALLSTATE_NEWCALL: break ; case CALLSTATE_DIALTONE: pData->state = SIPX_INTERNAL_CALLSTATE_OUTBOUND_IDLE; break ; case CALLSTATE_REMOTE_OFFERING: case CALLSTATE_REMOTE_ALERTING: pData->state = SIPX_INTERNAL_CALLSTATE_OUTBOUND_ATTEMPT ; break ; case CALLSTATE_CONNECTED: switch (cause) { case CALLSTATE_CONNECTED_ACTIVE: pData->state = SIPX_INTERNAL_CALLSTATE_CONNECTED ; pData->bInFocus = true ; break ; case CALLSTATE_CONNECTED_REQUEST_NOT_ACCEPTED: pData->state = SIPX_INTERNAL_CALLSTATE_CONNECTED ; break ; case CALLSTATE_CONNECTED_ACTIVE_HELD: pData->state = SIPX_INTERNAL_CALLSTATE_BRIDGED ; pData->bInFocus = false ; case CALLSTATE_CONNECTED_INACTIVE: pData->state = SIPX_INTERNAL_CALLSTATE_HELD ; pData->bInFocus = false ; break ; } break ; case CALLSTATE_DISCONNECTED: pData->state = SIPX_INTERNAL_CALLSTATE_DISCONNECTED ; pData->bInFocus = false ; break ; case CALLSTATE_OFFERING: case CALLSTATE_ALERTING: pData->state = SIPX_INTERNAL_CALLSTATE_OUTBOUND_ATTEMPT ; break ; case CALLSTATE_DESTROYED: pData->bInFocus = false ; break ; case CALLSTATE_AUDIO_EVENT: break ; case CALLSTATE_TRANSFER: break ; } sipxCallReleaseLock(pData, SIPX_LOCK_WRITE) ; } return bSuccess ;}SIPX_CONTACT_TYPE sipxCallGetLineContactType(SIPX_CALL hCall) { SIPX_CONTACT_TYPE contactType = CONTACT_AUTO ; SIPX_CALL_DATA* pData = sipxCallLookup(hCall, SIPX_LOCK_READ); if (pData) { SIPX_LINE_DATA* pLineData = sipxLineLookup(pData->hLine, SIPX_LOCK_READ) ; if (pLineData) { contactType = pLineData->contactType ; sipxLineReleaseLock(pLineData, SIPX_LOCK_READ) ; } sipxCallReleaseLock(pData, SIPX_LOCK_READ) ; } return contactType ;}SIPX_LINE_DATA* sipxLineLookup(const SIPX_LINE hLine, SIPX_LOCK_TYPE type){ SIPX_LINE_DATA* pRC ; pRC = (SIPX_LINE_DATA*) gpLineHandleMap->findHandle(hLine) ; if (validLineData(pRC)) { switch (type) { case SIPX_LOCK_READ: // TODO: What happens if this fails? pRC->pMutex->acquireRead() ; break ; case SIPX_LOCK_WRITE: // TODO: What happens if this fails? pRC->pMutex->acquireWrite() ; break ; } } else { pRC = NULL ; } return pRC ;}SIPX_INFO_DATA* sipxInfoLookup(const SIPX_INFO hInfo, SIPX_LOCK_TYPE type){ SIPX_INFO_DATA* pRC ; pRC = (SIPX_INFO_DATA*) gpInfoHandleMap->findHandle(hInfo) ; switch (type) { case SIPX_LOCK_READ: // TODO: What happens if this fails? pRC->pMutex->acquireRead() ; break ; case SIPX_LOCK_WRITE: // TODO: What happens if this fails? pRC->pMutex->acquireWrite() ; break ; } return pRC ;}void sipxSubscribeClientSubCallback(SipSubscribeClient::SubscriptionState newState, const char* earlyDialogHandle, const char* dialogHandle, void* applicationData, int responseCode, const char* responseText, long expiration, const SipMessage* subscribeResponse){ SIPX_SUB subscriptionHandle = (SIPX_SUB)applicationData; SIPX_SUBSCRIPTION_DATA* subscriptionData = (SIPX_SUBSCRIPTION_DATA*) gpSubHandleMap->findHandle(subscriptionHandle); if(subscriptionData && subscriptionData->pInst) { SIPX_SUBSTATUS_INFO pInfo; pInfo.nSize = sizeof(SIPX_SUBSTATUS_INFO); UtlString userAgent; if(subscribeResponse) { subscribeResponse->getUserAgentField(&userAgent); } pInfo.szSubServerUserAgent = userAgent; pInfo.hSub = subscriptionHandle; // TODO: Should probably set some cause codes based upon // the response code from the sip message pInfo.cause = SUBSCRIPTION_CAUSE_NORMAL; UtlString errorState; switch(newState) { case SipSubscribeClient::SUBSCRIPTION_INITIATED: // Early dialog pInfo.state = SIPX_SUBSCRIPTION_PENDING; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -