| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- #include "StdAfx.h"
- #include "TapiControl.h"
- #include "DevControl.h"
- #include "TapiLine.h"
- #include "LineFactory.h"
- #include "TapiLineIvr.h"
- #include "TapiLineExten.h"
- #include "TapiLineFax.h"
- #include "TrunkBase.h"
- #include "TrunkContainer.h"
- SINGLETON_IMPLEMENT(CTapiControl)
- CTapiControl::CTapiControl(void) : m_hLineApp(NULL)
- {
- }
- CTapiControl::~CTapiControl(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __tapiLineCallback
- **【函数功能】 TAPI应用主控回调函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CALLBACK CTapiControl::__tapiLineCallback( DWORD dwDevice, DWORD nMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3 )
- {
- switch(nMsg)
- {
- case LINE_CREATE:
- break;
- case LINE_REQUEST:
- break;
- default:
- {
- // 得到线路指针,将事件委托给线路实体类
- CTapiLine* pLine = CTapiControl::GetInstance().getLine(dwInstance);
- if(NULL != pLine)
- {
- pLine->onTapiEvent(dwDevice, nMsg, dwParam1, dwParam2, dwParam3);
- }
- }
- break;
- } // end switch
- }
- /*****************************************************************
- **【函数名称】 __openValidLines
- **【函数功能】 打开所有可控线路
- **【参数】 DevCounts 设备资源总数
- **【返回值】 设备可控线路数
- ****************************************************************/
- UINT CTapiControl::__openValidLines( int DevCounts )
- {
- UINT ExtCount = 0; // 可控分机总数
- for(int i = 0; i < DevCounts; ++i)
- {
- // 版本号协商(每个设备资源都有一个可用版本号)
- LINEEXTENSIONID lineExtID;
- DWORD ApiVersion = 0; // 设备资源版本号
- HRESULT hRet = ::lineNegotiateAPIVersion(m_hLineApp, (DWORD)i, TAPI_LO_VERSION, TAPI_HI_VERSION, &ApiVersion, &lineExtID);
- DWORD ExtVersion = 0;
- hRet = lineNegotiateExtVersion(m_hLineApp, (DWORD)i, ApiVersion, TAPI_LO_VERSION, TAPI_LO_VERSION, &ExtVersion);
- // 得到当前资源Caps
- LINEDEVCAPS* pDevCaps = NULL;
- hRet = __loopLineGetDevCaps(i, ApiVersion, ExtVersion, pDevCaps);
- // 如果设备可用
- if( (S_OK == hRet) &&
- (pDevCaps->dwBearerModes & LINEBEARERMODE_VOICE) &&
- (pDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) &&
- (pDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL) )
- {
- // 得到设备提供者
- CString strProvider = __getTapiString(pDevCaps, pDevCaps->dwProviderInfoSize, pDevCaps->dwProviderInfoOffset);
- // 只处理AVAYA设备
- if(strProvider.CompareNoCase(CONST_TAPI_DEST_DEVICE) == 0)
- {
- // 打开设备并得到设备分机号
- CString ExtID;
- HLINE LineHandle = __openDev(ExtID, i, ApiVersion, ExtVersion, pDevCaps);
- if(LineHandle != CONST_DEV_ID_INVALID) // 打开设备成功
- {
- CTapiLine* pLine = CLineFactory::makeTapiLine(i, LineHandle, ApiVersion, m_hLineApp, ExtID);
- if(pLine != NULL)
- {
- ExtCount++;
- m_MapLineByDevID.SetAt(i, pLine); // 添加到哈希表
- m_MapLineByExtID.SetAt(ExtID, pLine);
- pLine->regist(); // 线路注册
- }
- } // end if(打开设备)
- } // end if(Is Avaya)
- } // end if
- delete[] pDevCaps; // 释放内存
- } // end for
- return ExtCount;
- }
- /*****************************************************************
- **【函数名称】 __openDev
- **【函数功能】 打开TAPI设备并返回设备句柄
- **【参数】 DevID 设备ID
- Version 设备API版本号
- **【返回值】 HLINE 设备句柄
- ExtID 设备分机号
- ****************************************************************/
- HLINE CTapiControl::__openDev( CString& ExtID, DWORD DevID, DWORD ApiVersion, DWORD ExtVersion, LINEDEVCAPS* pDevCaps )
- {
- HLINE LineHandle = CONST_DEV_ID_INVALID;
- // 对设备执行打开操作,得到线路句柄
- HRESULT hRet = ::lineOpen(m_hLineApp, DevID, &LineHandle, ApiVersion, 0, DevID, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_INTERACTIVEVOICE, 0);
- if(hRet != S_OK)
- return CONST_DEV_ID_INVALID;
- // 得到线路分机号
- for(DWORD i=0; i<pDevCaps->dwNumAddresses; i++)
- {
- // 得到线路的Caps
- LINEADDRESSCAPS *pAddressCaps = NULL;
- __loopLineGetAddressCaps(DevID, i, ApiVersion, pAddressCaps);
- // 得到线路分机号
- ExtID = __getTapiString(pAddressCaps, pAddressCaps->dwAddressSize, pAddressCaps->dwAddressOffset);
- // 释放内存
- delete[] pAddressCaps;
- } // end if
- return LineHandle;
- }
- /*****************************************************************
- **【函数名称】 __loopLineGetDevCaps
- **【函数功能】 得到设备功能
- **【参数】 DevID 设备ID
- ApiVersion 设备API版本号
- **【返回值】 操作结果
- pDevCaps 设备功能指针
- ****************************************************************/
- HRESULT CTapiControl::__loopLineGetDevCaps( DWORD DevID, DWORD ApiVersion, DWORD ExtVersion, LINEDEVCAPS* &pDevCaps )
- {
- HRESULT hRet = S_OK;
- size_t nCurrentSize = 512; // Starting value - usually big enough
- for(;;)
- {
- // Allocate some memory for the call
- pDevCaps = (LINEDEVCAPS *) new BYTE[nCurrentSize];
- ZeroMemory(&pDevCaps[0], nCurrentSize);
- pDevCaps->dwTotalSize = nCurrentSize;
- // Ask TAPI for some information
- hRet = ::lineGetDevCaps(m_hLineApp, DevID, ApiVersion, ExtVersion, pDevCaps);
- // Cope with variable length structures
- if(hRet == LINEERR_STRUCTURETOOSMALL)
- {
- if(pDevCaps->dwNeededSize <= 0) break;
- nCurrentSize = pDevCaps->dwNeededSize;
- delete [] pDevCaps;
- pDevCaps = NULL;
- }
- else
- {
- break; // 获取成功,退出循环
- }
- } // end for
- return hRet;
- }
- /*****************************************************************
- **【函数名称】 __loopLineGetAddressCaps
- **【函数功能】 得到线路控制能力
- **【参数】 DevID 设备ID
- AddressID 设备Address ID
- ApiVersion 设备API版本号
- **【返回值】 操作结果
- pAddressCaps 设备Address能力
- ****************************************************************/
- HRESULT CTapiControl::__loopLineGetAddressCaps( DWORD DevID, DWORD AddressID, DWORD ApiVersion, LINEADDRESSCAPS*& pAddressCaps )
- {
- HRESULT hRet = S_OK;
- size_t nCurrentSize = 512; // Starting value - usually big enough
- for (;;)
- {
- // Allocate some memory for the call
- pAddressCaps = (LINEADDRESSCAPS *) new BYTE[nCurrentSize];
- ZeroMemory(&pAddressCaps[0], nCurrentSize);
- pAddressCaps->dwTotalSize = nCurrentSize;
- // Ask TAPI for some information
- hRet = ::lineGetAddressCaps(m_hLineApp, DevID, AddressID, ApiVersion, 0, pAddressCaps);
- // Cope with variable length structures
- if (hRet == LINEERR_STRUCTURETOOSMALL)
- {
- if (pAddressCaps->dwNeededSize <= 0) break;
- nCurrentSize = pAddressCaps->dwNeededSize;
- delete [] pAddressCaps;
- pAddressCaps = NULL;
- }
- else
- {
- break; // 获取成功,退出循环
- }
- } // end form
- return hRet;
- }
- /*****************************************************************
- **【函数名称】 __getTapiString
- **【函数功能】 从TAPI数据结构中得到相关信息
- **【参数】 pInfo TAPI数据指针
- Size 数据长度
- Offset 偏移量
- **【返回值】 已获取的信息内容
- ****************************************************************/
- CString CTapiControl::__getTapiString( void *pInfo, DWORD Size, DWORD Offset )
- {
- CString Result;
- if(Size > 0)
- {
- char *buffer = Result.GetBufferSetLength(Size + 1);
- memcpy(buffer, &((BYTE *) pInfo)[Offset], Size);
- buffer[Size] = 0;
- Result.ReleaseBuffer();
- }
- return Result;
- }
- /*****************************************************************
- **【函数名称】 init
- **【函数功能】 初始化TAPI控制
- **【参数】
- **【返回值】 TRUE: 初始化成功
- FALSE: 初始化失败
- ****************************************************************/
- bool CTapiControl::init( void )
- {
- // 连接IPO
- DWORD dwDevCount = 0; // 保存可用设备资源总数
- DWORD dwAPIVersion = TAPI_HI_VERSION;
- LINEINITIALIZEEXPARAMS params = { sizeof(LINEINITIALIZEEXPARAMS) };
- params.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW;
- HINSTANCE hInst = ::AfxGetInstanceHandle();
- LPCTSTR pszAppName = ::AfxGetAppName();
- HRESULT hRet = ::lineInitializeEx(&m_hLineApp, hInst, __tapiLineCallback, pszAppName, &dwDevCount, &dwAPIVersion, ¶ms);
- if(hRet != S_OK) // 连接设备失败
- {
- CDevControl::GetInstance().onEventLog(LOG_LEVEL_WARNING, _T("{TapiCtrl}: IPO设备连接失败"));
- return false;
- } // end if
- // 打开所有可用线路(内线)
- int ExtCount = __openValidLines((int)dwDevCount);
- // 设备初始化完成
- CDevControl::GetInstance().onEventLog(LOG_LEVEL_NORMAL, _T("{TapiCtrl}: IPO设备连接成功, 可用分机总数 = %d, TAPI版本号 = %08X"), ExtCount, dwAPIVersion);
- return true;
- }
- /*****************************************************************
- **【函数名称】 release
- **【函数功能】 释放TAPI连接
- **【参数】
- **【返回值】
- ****************************************************************/
- void CTapiControl::release( void )
- {
- m_MapLineByExtID.RemoveAll();
- DWORD DevId = 0;
- CTapiLine* pLine = NULL;
- POSITION Pos = m_MapLineByDevID.GetStartPosition();
- while(Pos != NULL)
- {
- m_MapLineByDevID.GetNextAssoc(Pos, DevId, pLine);
- ASSERT(pLine != NULL);
- delete pLine;
- }
- m_MapLineByDevID.RemoveAll();
- }
- /*****************************************************************
- **【函数名称】 getLine
- **【函数功能】 根据设备编号查找线路
- **【参数】 DevID 设备ID
- **【返回值】 指定的CTapiLine指针
- ****************************************************************/
- CTapiLine* CTapiControl::getLine( DWORD DevID )
- {
- CTapiLine* pLine = NULL;
- m_MapLineByDevID.Lookup(DevID, pLine);
- return pLine;
- }
- /*****************************************************************
- **【函数名称】 getLine
- **【函数功能】 根据分机号查找线路
- **【参数】 ExtID 线路分机号
- **【返回值】 指定的CTapiLine指针
- ****************************************************************/
- CTapiLine* CTapiControl::getLine( LPCTSTR ExtID )
- {
- ASSERT(ExtID != NULL);
- CTapiLine* pLine = NULL;
- m_MapLineByExtID.Lookup(ExtID, pLine);
- return pLine;
- }
- /*****************************************************************
- **【函数名称】 getLineByCallId
- **【函数功能】 根据DevLink CallId 查找线路
- **【参数】 DevLinkCallId
- **【返回值】 指定的CTapiLine指针
- ****************************************************************/
- CTapiLine* CTapiControl::getLineByCallId( int DevLinkCallId )
- {
- DWORD DevId = 0;
- CTapiLine* pLine = NULL;
- POSITION pos = m_MapLineByDevID.GetStartPosition();
- while(pos != NULL)
- {
- m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
- if(pLine->isAssoDevLinkCallId(DevLinkCallId))
- return pLine;
- } // end while
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getIvrLineByAssoTrunk
- **【函数功能】 根据中继ID查找其当前关联的IVR分机
- **【参数】 TrunkId
- **【返回值】 指定的CTapiLine指针
- ****************************************************************/
- CTapiLine* CTapiControl::getIvrLineByAssoTrunk( UINT TrunkId )
- {
- DWORD DevId = 0;
- CTapiLine* pLine = NULL;
- POSITION pos = m_MapLineByDevID.GetStartPosition();
- while(pos != NULL)
- {
- m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
- CTapiLineIvr* pIvrLine = dynamic_cast<CTapiLineIvr*>(pLine);
- if(pIvrLine != NULL && pIvrLine->getAssoTrunkId() == TrunkId)
- return pIvrLine;
- } // end while
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getFaxLineByAssoTrunk
- **【函数功能】 根据中继ID查找其当前关联的传真分机
- **【参数】 TrunkId
- **【返回值】 指定的CTapiLine指针
- ****************************************************************/
- CTapiLine* CTapiControl::getFaxLineByAssoTrunk( UINT TrunkId )
- {
- bool HasFaxLine = false;
- DWORD DevId = 0;
- CTapiLine* pLine = NULL;
- POSITION pos = m_MapLineByDevID.GetStartPosition();
- while(pos != NULL)
- {
- m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
- CTapiLineFax* pFaxLine = dynamic_cast<CTapiLineFax*>(pLine);
- if(pFaxLine == NULL)
- continue;
- HasFaxLine = true;
- if(pFaxLine->getAssoTrunkId() == TrunkId)
- return pFaxLine;
- } // end while
- if(!HasFaxLine)
- return getIvrLineByAssoTrunk(TrunkId);
- else
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getFreeIvrLine
- **【函数功能】 查找一条空闲的IVR线路
- **【参数】
- **【返回值】 空闲的IVR线路指针
- ****************************************************************/
- CTapiLine* CTapiControl::getFreeIvrLine( void )
- {
- // 当前轮循到的索引
- static POSITION PosStaticIvr = m_MapLineByDevID.GetStartPosition();
- // 保证遍历一轮
- for(int i = 0; i < m_MapLineByDevID.GetCount(); ++i)
- {
- DWORD DevId = 0;
- CTapiLine* pLine = NULL;
- m_MapLineByDevID.GetNextAssoc(PosStaticIvr, DevId, pLine);
- // 保证POS是有效的
- if(PosStaticIvr == NULL)
- PosStaticIvr = m_MapLineByDevID.GetStartPosition();
- // 当前线路是IVR线路且空闲
- if(pLine->isFree() && dynamic_cast<CTapiLineIvr*>(pLine) != NULL)
- return pLine;
- } // end if
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getFreeFaxLine
- **【函数功能】 查找一条空闲的Fax线路
- **【参数】
- **【返回值】 空闲的Fax线路指针
- ****************************************************************/
- CTapiLine* CTapiControl::getFreeFaxLine( void )
- {
- CTapiLine* pLine = NULL;
- pLine = getFreeFaxLineOnly();
- if(pLine != NULL)
- return pLine;
- // 如果没有找到传真线路,直接查找IVR线路
- pLine = getFreeIvrLine();
- return pLine;
- }
- /*****************************************************************
- **【函数名称】 getFreeFaxLineOnly
- **【函数功能】 查找一条空闲的Fax线路,不查找IVR线路
- **【参数】
- **【返回值】 空闲的Fax线路指针
- ****************************************************************/
- CTapiLine* CTapiControl::getFreeFaxLineOnly( void )
- {
- CTapiLine* pLine = NULL;
- // 当前轮循到的索引
- static POSITION PosStaticFax = m_MapLineByDevID.GetStartPosition();
- // 保证遍历一轮
- for(int i=0; i<m_MapLineByDevID.GetCount(); i++)
- {
- DWORD DevId = 0;
- m_MapLineByDevID.GetNextAssoc(PosStaticFax, DevId, pLine);
- // 保证POS是有效的
- if(PosStaticFax == NULL)
- PosStaticFax = m_MapLineByDevID.GetStartPosition();
- // 当前线路是FAX线路且空闲
- if(pLine->isFree() && dynamic_cast<CTapiLineFax*>(pLine) != NULL)
- return pLine;
- } // end if
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getErrorIvrLine
- **【函数功能】 获取正在执行任务,并且未关联外线成功的线路
- **【参数】
- **【返回值】 线路地址
- ****************************************************************/
- CTapiLine* CTapiControl::getErrorIvrLine( void )
- {
- POSITION pos = m_MapLineByDevID.GetStartPosition();
- while(pos != NULL)
- {
- DWORD DevId = 0;
- CTapiLine* pLine = NULL;
- m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
- CTapiLineIvr* pIvrLine = dynamic_cast<CTapiLineIvr*>(pLine);
- CTapiLineFax* pFaxLine = dynamic_cast<CTapiLineFax*>(pLine);
- if(pIvrLine == NULL && pFaxLine == NULL) // 排除坐席分机线路
- continue;
- int Status = pLine->status();
- UINT AssoTrunkId = pIvrLine == NULL ? pFaxLine->getAssoTrunkId() : pIvrLine->getAssoTrunkId();
- if(AssoTrunkId == 0 && Status !=INNER_STATE_DISABLED)
- return pLine;
- } // end while
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getTrunkAssoIvrId
- **【函数功能】 得到当前外线关联的IVR线路ID
- **【参数】 TrunkId 外线ID
- **【返回值】
- ****************************************************************/
- UINT CTapiControl::getTrunkAssoIvrId( UINT TrunkId )
- {
- UINT IvrLineId = 0;
- CTapiLine* pLine = getIvrLineByAssoTrunk(TrunkId);
- if(pLine != NULL)
- sscanf_s(pLine->extenID(), _T("%lu"), &IvrLineId);
- return IvrLineId;
- }
- /*****************************************************************
- **【函数名称】 getTrunkAssoFaxId
- **【函数功能】 得到当前外线关联的IVR线路ID
- **【参数】 TrunkId 外线ID
- **【返回值】
- ****************************************************************/
- UINT CTapiControl::getTrunkAssoFaxId( UINT TrunkId )
- {
- UINT IvrLineId = 0;
- CTapiLine* pLine = getFaxLineByAssoTrunk(TrunkId);
- if(pLine != NULL)
- sscanf_s(pLine->extenID(), _T("%lu"), &IvrLineId);
- return IvrLineId;
- }
- /*****************************************************************
- **【函数名称】 onDevLinkEventS
- **【函数功能】 DEV Link S 事件响应
- **【参数】 pInfoS S事件消息内容
- **【返回值】
- ****************************************************************/
- void CTapiControl::onDevLinkEventS( DevLinkInfoS* pInfoS )
- {
- // 根据触发事件的设备类型进行分类处理
- if(pInfoS->nResType == DEV_RES_TYPE_EXT) // 分机
- {
- CTapiLine* pLine = getLine(pInfoS->szResId);
- ASSERT(pLine != NULL);
- if(pLine != NULL)
- {
- if (pInfoS->nFlag == CONST_DEVLINK_HANGUP_BY_B) // 被动端
- {
- CTapiLine* pPeerLine = getLine(pInfoS->szPeerResId);
- if (pPeerLine != NULL)
- {
- // 如果对端线路是监听线路(主动挂机方),不响应事件
- if (pPeerLine->listenerFlag())
- {
- if(pPeerLine->status() == INNER_STATE_FREE && pLine->status() == INNER_STATE_TALKING)
- {
- pPeerLine->listenerFlag() = false; // 监听线路已挂机,取消线路监听标志
- }
- return;
- }
- }
- pLine->onDevLinkEventS(pInfoS);
- }
- else
- {
- pLine->onDevLinkEventS(pInfoS);
- }
- }
- }
- else if(pInfoS->nResType == DEV_RES_TYPE_TRUNK) // 外线
- {
- UINT TrunkId = 0;
- sscanf_s(pInfoS->szResId, "%lu", &TrunkId);
- CTrunkBase* pTrunk = CTrunkContainer::getTrunk(TrunkId);
- ASSERT(pTrunk != NULL);
- if(pTrunk!= NULL)
- pTrunk->onDevLinkEventS(pInfoS);
- } // end if
- }
- /*****************************************************************
- **【函数名称】 onDevLinkEventA
- **【函数功能】 DEV Link A 事件响应
- **【参数】 DevLinkCallId DevLink CallId
- **【返回值】
- ****************************************************************/
- void CTapiControl::onDevLinkEventA( int DevLinkCallId )
- {
- // 通知关随的分机
- POSITION pos = m_MapLineByDevID.GetStartPosition();
- while(pos != NULL)
- {
- CTapiLine* pLine = NULL;
- DWORD DevId = 0;
- m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
- if(pLine->isAssoDevLinkCallId(DevLinkCallId))
- pLine->onDevLinkEventA(DevLinkCallId);
- } // end while
- // 通知关联的外线
- CTrunkBase* pTrunk = CTrunkContainer::getTrunkByCallId(DevLinkCallId);
- if(pTrunk != NULL)
- pTrunk->onDevLinkEventA(DevLinkCallId);
- }
- /*****************************************************************
- **【函数名称】 onDevLinkEventD
- **【函数功能】 DEV Link D 事件响应
- **【参数】 DevLinkCallId DevLink CallId
- **【返回值】
- ****************************************************************/
- void CTapiControl::onDevLinkEventD( int DevLinkCallId )
- {
- // 通知关联的分机
- POSITION pos = m_MapLineByDevID.GetStartPosition();
- while(pos != NULL)
- {
- CTapiLine* pLine = NULL;
- DWORD nDevId = 0;
- m_MapLineByDevID.GetNextAssoc(pos, nDevId, pLine);
- if(pLine->isAssoDevLinkCallId(DevLinkCallId))
- pLine->onDevLinkEventD(DevLinkCallId);
- } // end while
- // 通知关联的外线
- CTrunkBase* pTrunk = CTrunkContainer::getTrunkByCallId(DevLinkCallId);
- if(pTrunk != NULL)
- pTrunk->onDevLinkEventD(DevLinkCallId);
- }
|