中间件标准版5.1git,去除基础模块

TapiControl.cpp 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. #include "StdAfx.h"
  2. #include "TapiControl.h"
  3. #include "DevControl.h"
  4. #include "TapiLine.h"
  5. #include "LineFactory.h"
  6. #include "TapiLineIvr.h"
  7. #include "TapiLineExten.h"
  8. #include "TapiLineFax.h"
  9. #include "TrunkBase.h"
  10. #include "TrunkContainer.h"
  11. SINGLETON_IMPLEMENT(CTapiControl)
  12. CTapiControl::CTapiControl(void) : m_hLineApp(NULL)
  13. {
  14. }
  15. CTapiControl::~CTapiControl(void)
  16. {
  17. }
  18. /*****************************************************************
  19. **【函数名称】 __tapiLineCallback
  20. **【函数功能】 TAPI应用主控回调函数
  21. **【参数】
  22. **【返回值】
  23. ****************************************************************/
  24. void CALLBACK CTapiControl::__tapiLineCallback( DWORD dwDevice, DWORD nMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3 )
  25. {
  26. switch(nMsg)
  27. {
  28. case LINE_CREATE:
  29. break;
  30. case LINE_REQUEST:
  31. break;
  32. default:
  33. {
  34. // 得到线路指针,将事件委托给线路实体类
  35. CTapiLine* pLine = CTapiControl::GetInstance().getLine(dwInstance);
  36. if(NULL != pLine)
  37. {
  38. pLine->onTapiEvent(dwDevice, nMsg, dwParam1, dwParam2, dwParam3);
  39. }
  40. }
  41. break;
  42. } // end switch
  43. }
  44. /*****************************************************************
  45. **【函数名称】 __openValidLines
  46. **【函数功能】 打开所有可控线路
  47. **【参数】 DevCounts 设备资源总数
  48. **【返回值】 设备可控线路数
  49. ****************************************************************/
  50. UINT CTapiControl::__openValidLines( int DevCounts )
  51. {
  52. UINT ExtCount = 0; // 可控分机总数
  53. for(int i = 0; i < DevCounts; ++i)
  54. {
  55. // 版本号协商(每个设备资源都有一个可用版本号)
  56. LINEEXTENSIONID lineExtID;
  57. DWORD ApiVersion = 0; // 设备资源版本号
  58. HRESULT hRet = ::lineNegotiateAPIVersion(m_hLineApp, (DWORD)i, TAPI_LO_VERSION, TAPI_HI_VERSION, &ApiVersion, &lineExtID);
  59. DWORD ExtVersion = 0;
  60. hRet = lineNegotiateExtVersion(m_hLineApp, (DWORD)i, ApiVersion, TAPI_LO_VERSION, TAPI_LO_VERSION, &ExtVersion);
  61. // 得到当前资源Caps
  62. LINEDEVCAPS* pDevCaps = NULL;
  63. hRet = __loopLineGetDevCaps(i, ApiVersion, ExtVersion, pDevCaps);
  64. // 如果设备可用
  65. if( (S_OK == hRet) &&
  66. (pDevCaps->dwBearerModes & LINEBEARERMODE_VOICE) &&
  67. (pDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) &&
  68. (pDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL) )
  69. {
  70. // 得到设备提供者
  71. CString strProvider = __getTapiString(pDevCaps, pDevCaps->dwProviderInfoSize, pDevCaps->dwProviderInfoOffset);
  72. // 只处理AVAYA设备
  73. if(strProvider.CompareNoCase(CONST_TAPI_DEST_DEVICE) == 0)
  74. {
  75. // 打开设备并得到设备分机号
  76. CString ExtID;
  77. HLINE LineHandle = __openDev(ExtID, i, ApiVersion, ExtVersion, pDevCaps);
  78. if(LineHandle != CONST_DEV_ID_INVALID) // 打开设备成功
  79. {
  80. CTapiLine* pLine = CLineFactory::makeTapiLine(i, LineHandle, ApiVersion, m_hLineApp, ExtID);
  81. if(pLine != NULL)
  82. {
  83. ExtCount++;
  84. m_MapLineByDevID.SetAt(i, pLine); // 添加到哈希表
  85. m_MapLineByExtID.SetAt(ExtID, pLine);
  86. pLine->regist(); // 线路注册
  87. }
  88. } // end if(打开设备)
  89. } // end if(Is Avaya)
  90. } // end if
  91. delete[] pDevCaps; // 释放内存
  92. } // end for
  93. return ExtCount;
  94. }
  95. /*****************************************************************
  96. **【函数名称】 __openDev
  97. **【函数功能】 打开TAPI设备并返回设备句柄
  98. **【参数】 DevID 设备ID
  99. Version 设备API版本号
  100. **【返回值】 HLINE 设备句柄
  101. ExtID 设备分机号
  102. ****************************************************************/
  103. HLINE CTapiControl::__openDev( CString& ExtID, DWORD DevID, DWORD ApiVersion, DWORD ExtVersion, LINEDEVCAPS* pDevCaps )
  104. {
  105. HLINE LineHandle = CONST_DEV_ID_INVALID;
  106. // 对设备执行打开操作,得到线路句柄
  107. HRESULT hRet = ::lineOpen(m_hLineApp, DevID, &LineHandle, ApiVersion, 0, DevID, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_INTERACTIVEVOICE, 0);
  108. if(hRet != S_OK)
  109. return CONST_DEV_ID_INVALID;
  110. // 得到线路分机号
  111. for(DWORD i=0; i<pDevCaps->dwNumAddresses; i++)
  112. {
  113. // 得到线路的Caps
  114. LINEADDRESSCAPS *pAddressCaps = NULL;
  115. __loopLineGetAddressCaps(DevID, i, ApiVersion, pAddressCaps);
  116. // 得到线路分机号
  117. ExtID = __getTapiString(pAddressCaps, pAddressCaps->dwAddressSize, pAddressCaps->dwAddressOffset);
  118. // 释放内存
  119. delete[] pAddressCaps;
  120. } // end if
  121. return LineHandle;
  122. }
  123. /*****************************************************************
  124. **【函数名称】 __loopLineGetDevCaps
  125. **【函数功能】 得到设备功能
  126. **【参数】 DevID 设备ID
  127. ApiVersion 设备API版本号
  128. **【返回值】 操作结果
  129. pDevCaps 设备功能指针
  130. ****************************************************************/
  131. HRESULT CTapiControl::__loopLineGetDevCaps( DWORD DevID, DWORD ApiVersion, DWORD ExtVersion, LINEDEVCAPS* &pDevCaps )
  132. {
  133. HRESULT hRet = S_OK;
  134. size_t nCurrentSize = 512; // Starting value - usually big enough
  135. for(;;)
  136. {
  137. // Allocate some memory for the call
  138. pDevCaps = (LINEDEVCAPS *) new BYTE[nCurrentSize];
  139. ZeroMemory(&pDevCaps[0], nCurrentSize);
  140. pDevCaps->dwTotalSize = nCurrentSize;
  141. // Ask TAPI for some information
  142. hRet = ::lineGetDevCaps(m_hLineApp, DevID, ApiVersion, ExtVersion, pDevCaps);
  143. // Cope with variable length structures
  144. if(hRet == LINEERR_STRUCTURETOOSMALL)
  145. {
  146. if(pDevCaps->dwNeededSize <= 0) break;
  147. nCurrentSize = pDevCaps->dwNeededSize;
  148. delete [] pDevCaps;
  149. pDevCaps = NULL;
  150. }
  151. else
  152. {
  153. break; // 获取成功,退出循环
  154. }
  155. } // end for
  156. return hRet;
  157. }
  158. /*****************************************************************
  159. **【函数名称】 __loopLineGetAddressCaps
  160. **【函数功能】 得到线路控制能力
  161. **【参数】 DevID 设备ID
  162. AddressID 设备Address ID
  163. ApiVersion 设备API版本号
  164. **【返回值】 操作结果
  165. pAddressCaps 设备Address能力
  166. ****************************************************************/
  167. HRESULT CTapiControl::__loopLineGetAddressCaps( DWORD DevID, DWORD AddressID, DWORD ApiVersion, LINEADDRESSCAPS*& pAddressCaps )
  168. {
  169. HRESULT hRet = S_OK;
  170. size_t nCurrentSize = 512; // Starting value - usually big enough
  171. for (;;)
  172. {
  173. // Allocate some memory for the call
  174. pAddressCaps = (LINEADDRESSCAPS *) new BYTE[nCurrentSize];
  175. ZeroMemory(&pAddressCaps[0], nCurrentSize);
  176. pAddressCaps->dwTotalSize = nCurrentSize;
  177. // Ask TAPI for some information
  178. hRet = ::lineGetAddressCaps(m_hLineApp, DevID, AddressID, ApiVersion, 0, pAddressCaps);
  179. // Cope with variable length structures
  180. if (hRet == LINEERR_STRUCTURETOOSMALL)
  181. {
  182. if (pAddressCaps->dwNeededSize <= 0) break;
  183. nCurrentSize = pAddressCaps->dwNeededSize;
  184. delete [] pAddressCaps;
  185. pAddressCaps = NULL;
  186. }
  187. else
  188. {
  189. break; // 获取成功,退出循环
  190. }
  191. } // end form
  192. return hRet;
  193. }
  194. /*****************************************************************
  195. **【函数名称】 __getTapiString
  196. **【函数功能】 从TAPI数据结构中得到相关信息
  197. **【参数】 pInfo TAPI数据指针
  198. Size 数据长度
  199. Offset 偏移量
  200. **【返回值】 已获取的信息内容
  201. ****************************************************************/
  202. CString CTapiControl::__getTapiString( void *pInfo, DWORD Size, DWORD Offset )
  203. {
  204. CString Result;
  205. if(Size > 0)
  206. {
  207. char *buffer = Result.GetBufferSetLength(Size + 1);
  208. memcpy(buffer, &((BYTE *) pInfo)[Offset], Size);
  209. buffer[Size] = 0;
  210. Result.ReleaseBuffer();
  211. }
  212. return Result;
  213. }
  214. /*****************************************************************
  215. **【函数名称】 init
  216. **【函数功能】 初始化TAPI控制
  217. **【参数】
  218. **【返回值】 TRUE: 初始化成功
  219. FALSE: 初始化失败
  220. ****************************************************************/
  221. bool CTapiControl::init( void )
  222. {
  223. // 连接IPO
  224. DWORD dwDevCount = 0; // 保存可用设备资源总数
  225. DWORD dwAPIVersion = TAPI_HI_VERSION;
  226. LINEINITIALIZEEXPARAMS params = { sizeof(LINEINITIALIZEEXPARAMS) };
  227. params.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW;
  228. HINSTANCE hInst = ::AfxGetInstanceHandle();
  229. LPCTSTR pszAppName = ::AfxGetAppName();
  230. HRESULT hRet = ::lineInitializeEx(&m_hLineApp, hInst, __tapiLineCallback, pszAppName, &dwDevCount, &dwAPIVersion, &params);
  231. if(hRet != S_OK) // 连接设备失败
  232. {
  233. CDevControl::GetInstance().onEventLog(LOG_LEVEL_WARNING, _T("{TapiCtrl}: IPO设备连接失败"));
  234. return false;
  235. } // end if
  236. // 打开所有可用线路(内线)
  237. int ExtCount = __openValidLines((int)dwDevCount);
  238. // 设备初始化完成
  239. CDevControl::GetInstance().onEventLog(LOG_LEVEL_NORMAL, _T("{TapiCtrl}: IPO设备连接成功, 可用分机总数 = %d, TAPI版本号 = %08X"), ExtCount, dwAPIVersion);
  240. return true;
  241. }
  242. /*****************************************************************
  243. **【函数名称】 release
  244. **【函数功能】 释放TAPI连接
  245. **【参数】
  246. **【返回值】
  247. ****************************************************************/
  248. void CTapiControl::release( void )
  249. {
  250. m_MapLineByExtID.RemoveAll();
  251. DWORD DevId = 0;
  252. CTapiLine* pLine = NULL;
  253. POSITION Pos = m_MapLineByDevID.GetStartPosition();
  254. while(Pos != NULL)
  255. {
  256. m_MapLineByDevID.GetNextAssoc(Pos, DevId, pLine);
  257. ASSERT(pLine != NULL);
  258. delete pLine;
  259. }
  260. m_MapLineByDevID.RemoveAll();
  261. }
  262. /*****************************************************************
  263. **【函数名称】 getLine
  264. **【函数功能】 根据设备编号查找线路
  265. **【参数】 DevID 设备ID
  266. **【返回值】 指定的CTapiLine指针
  267. ****************************************************************/
  268. CTapiLine* CTapiControl::getLine( DWORD DevID )
  269. {
  270. CTapiLine* pLine = NULL;
  271. m_MapLineByDevID.Lookup(DevID, pLine);
  272. return pLine;
  273. }
  274. /*****************************************************************
  275. **【函数名称】 getLine
  276. **【函数功能】 根据分机号查找线路
  277. **【参数】 ExtID 线路分机号
  278. **【返回值】 指定的CTapiLine指针
  279. ****************************************************************/
  280. CTapiLine* CTapiControl::getLine( LPCTSTR ExtID )
  281. {
  282. ASSERT(ExtID != NULL);
  283. CTapiLine* pLine = NULL;
  284. m_MapLineByExtID.Lookup(ExtID, pLine);
  285. return pLine;
  286. }
  287. /*****************************************************************
  288. **【函数名称】 getLineByCallId
  289. **【函数功能】 根据DevLink CallId 查找线路
  290. **【参数】 DevLinkCallId
  291. **【返回值】 指定的CTapiLine指针
  292. ****************************************************************/
  293. CTapiLine* CTapiControl::getLineByCallId( int DevLinkCallId )
  294. {
  295. DWORD DevId = 0;
  296. CTapiLine* pLine = NULL;
  297. POSITION pos = m_MapLineByDevID.GetStartPosition();
  298. while(pos != NULL)
  299. {
  300. m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
  301. if(pLine->isAssoDevLinkCallId(DevLinkCallId))
  302. return pLine;
  303. } // end while
  304. return NULL;
  305. }
  306. /*****************************************************************
  307. **【函数名称】 getIvrLineByAssoTrunk
  308. **【函数功能】 根据中继ID查找其当前关联的IVR分机
  309. **【参数】 TrunkId
  310. **【返回值】 指定的CTapiLine指针
  311. ****************************************************************/
  312. CTapiLine* CTapiControl::getIvrLineByAssoTrunk( UINT TrunkId )
  313. {
  314. DWORD DevId = 0;
  315. CTapiLine* pLine = NULL;
  316. POSITION pos = m_MapLineByDevID.GetStartPosition();
  317. while(pos != NULL)
  318. {
  319. m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
  320. CTapiLineIvr* pIvrLine = dynamic_cast<CTapiLineIvr*>(pLine);
  321. if(pIvrLine != NULL && pIvrLine->getAssoTrunkId() == TrunkId)
  322. return pIvrLine;
  323. } // end while
  324. return NULL;
  325. }
  326. /*****************************************************************
  327. **【函数名称】 getFaxLineByAssoTrunk
  328. **【函数功能】 根据中继ID查找其当前关联的传真分机
  329. **【参数】 TrunkId
  330. **【返回值】 指定的CTapiLine指针
  331. ****************************************************************/
  332. CTapiLine* CTapiControl::getFaxLineByAssoTrunk( UINT TrunkId )
  333. {
  334. bool HasFaxLine = false;
  335. DWORD DevId = 0;
  336. CTapiLine* pLine = NULL;
  337. POSITION pos = m_MapLineByDevID.GetStartPosition();
  338. while(pos != NULL)
  339. {
  340. m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
  341. CTapiLineFax* pFaxLine = dynamic_cast<CTapiLineFax*>(pLine);
  342. if(pFaxLine == NULL)
  343. continue;
  344. HasFaxLine = true;
  345. if(pFaxLine->getAssoTrunkId() == TrunkId)
  346. return pFaxLine;
  347. } // end while
  348. if(!HasFaxLine)
  349. return getIvrLineByAssoTrunk(TrunkId);
  350. else
  351. return NULL;
  352. }
  353. /*****************************************************************
  354. **【函数名称】 getFreeIvrLine
  355. **【函数功能】 查找一条空闲的IVR线路
  356. **【参数】
  357. **【返回值】 空闲的IVR线路指针
  358. ****************************************************************/
  359. CTapiLine* CTapiControl::getFreeIvrLine( void )
  360. {
  361. // 当前轮循到的索引
  362. static POSITION PosStaticIvr = m_MapLineByDevID.GetStartPosition();
  363. // 保证遍历一轮
  364. for(int i = 0; i < m_MapLineByDevID.GetCount(); ++i)
  365. {
  366. DWORD DevId = 0;
  367. CTapiLine* pLine = NULL;
  368. m_MapLineByDevID.GetNextAssoc(PosStaticIvr, DevId, pLine);
  369. // 保证POS是有效的
  370. if(PosStaticIvr == NULL)
  371. PosStaticIvr = m_MapLineByDevID.GetStartPosition();
  372. // 当前线路是IVR线路且空闲
  373. if(pLine->isFree() && dynamic_cast<CTapiLineIvr*>(pLine) != NULL)
  374. return pLine;
  375. } // end if
  376. return NULL;
  377. }
  378. /*****************************************************************
  379. **【函数名称】 getFreeFaxLine
  380. **【函数功能】 查找一条空闲的Fax线路
  381. **【参数】
  382. **【返回值】 空闲的Fax线路指针
  383. ****************************************************************/
  384. CTapiLine* CTapiControl::getFreeFaxLine( void )
  385. {
  386. CTapiLine* pLine = NULL;
  387. pLine = getFreeFaxLineOnly();
  388. if(pLine != NULL)
  389. return pLine;
  390. // 如果没有找到传真线路,直接查找IVR线路
  391. pLine = getFreeIvrLine();
  392. return pLine;
  393. }
  394. /*****************************************************************
  395. **【函数名称】 getFreeFaxLineOnly
  396. **【函数功能】 查找一条空闲的Fax线路,不查找IVR线路
  397. **【参数】
  398. **【返回值】 空闲的Fax线路指针
  399. ****************************************************************/
  400. CTapiLine* CTapiControl::getFreeFaxLineOnly( void )
  401. {
  402. CTapiLine* pLine = NULL;
  403. // 当前轮循到的索引
  404. static POSITION PosStaticFax = m_MapLineByDevID.GetStartPosition();
  405. // 保证遍历一轮
  406. for(int i=0; i<m_MapLineByDevID.GetCount(); i++)
  407. {
  408. DWORD DevId = 0;
  409. m_MapLineByDevID.GetNextAssoc(PosStaticFax, DevId, pLine);
  410. // 保证POS是有效的
  411. if(PosStaticFax == NULL)
  412. PosStaticFax = m_MapLineByDevID.GetStartPosition();
  413. // 当前线路是FAX线路且空闲
  414. if(pLine->isFree() && dynamic_cast<CTapiLineFax*>(pLine) != NULL)
  415. return pLine;
  416. } // end if
  417. return NULL;
  418. }
  419. /*****************************************************************
  420. **【函数名称】 getErrorIvrLine
  421. **【函数功能】 获取正在执行任务,并且未关联外线成功的线路
  422. **【参数】
  423. **【返回值】 线路地址
  424. ****************************************************************/
  425. CTapiLine* CTapiControl::getErrorIvrLine( void )
  426. {
  427. POSITION pos = m_MapLineByDevID.GetStartPosition();
  428. while(pos != NULL)
  429. {
  430. DWORD DevId = 0;
  431. CTapiLine* pLine = NULL;
  432. m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
  433. CTapiLineIvr* pIvrLine = dynamic_cast<CTapiLineIvr*>(pLine);
  434. CTapiLineFax* pFaxLine = dynamic_cast<CTapiLineFax*>(pLine);
  435. if(pIvrLine == NULL && pFaxLine == NULL) // 排除坐席分机线路
  436. continue;
  437. int Status = pLine->status();
  438. UINT AssoTrunkId = pIvrLine == NULL ? pFaxLine->getAssoTrunkId() : pIvrLine->getAssoTrunkId();
  439. if(AssoTrunkId == 0 && Status !=INNER_STATE_DISABLED)
  440. return pLine;
  441. } // end while
  442. return NULL;
  443. }
  444. /*****************************************************************
  445. **【函数名称】 getTrunkAssoIvrId
  446. **【函数功能】 得到当前外线关联的IVR线路ID
  447. **【参数】 TrunkId 外线ID
  448. **【返回值】
  449. ****************************************************************/
  450. UINT CTapiControl::getTrunkAssoIvrId( UINT TrunkId )
  451. {
  452. UINT IvrLineId = 0;
  453. CTapiLine* pLine = getIvrLineByAssoTrunk(TrunkId);
  454. if(pLine != NULL)
  455. sscanf_s(pLine->extenID(), _T("%lu"), &IvrLineId);
  456. return IvrLineId;
  457. }
  458. /*****************************************************************
  459. **【函数名称】 getTrunkAssoFaxId
  460. **【函数功能】 得到当前外线关联的IVR线路ID
  461. **【参数】 TrunkId 外线ID
  462. **【返回值】
  463. ****************************************************************/
  464. UINT CTapiControl::getTrunkAssoFaxId( UINT TrunkId )
  465. {
  466. UINT IvrLineId = 0;
  467. CTapiLine* pLine = getFaxLineByAssoTrunk(TrunkId);
  468. if(pLine != NULL)
  469. sscanf_s(pLine->extenID(), _T("%lu"), &IvrLineId);
  470. return IvrLineId;
  471. }
  472. /*****************************************************************
  473. **【函数名称】 onDevLinkEventS
  474. **【函数功能】 DEV Link S 事件响应
  475. **【参数】 pInfoS S事件消息内容
  476. **【返回值】
  477. ****************************************************************/
  478. void CTapiControl::onDevLinkEventS( DevLinkInfoS* pInfoS )
  479. {
  480. // 根据触发事件的设备类型进行分类处理
  481. if(pInfoS->nResType == DEV_RES_TYPE_EXT) // 分机
  482. {
  483. CTapiLine* pLine = getLine(pInfoS->szResId);
  484. ASSERT(pLine != NULL);
  485. if(pLine != NULL)
  486. {
  487. if (pInfoS->nFlag == CONST_DEVLINK_HANGUP_BY_B) // 被动端
  488. {
  489. CTapiLine* pPeerLine = getLine(pInfoS->szPeerResId);
  490. if (pPeerLine != NULL)
  491. {
  492. // 如果对端线路是监听线路(主动挂机方),不响应事件
  493. if (pPeerLine->listenerFlag())
  494. {
  495. if(pPeerLine->status() == INNER_STATE_FREE && pLine->status() == INNER_STATE_TALKING)
  496. {
  497. pPeerLine->listenerFlag() = false; // 监听线路已挂机,取消线路监听标志
  498. }
  499. return;
  500. }
  501. }
  502. pLine->onDevLinkEventS(pInfoS);
  503. }
  504. else
  505. {
  506. pLine->onDevLinkEventS(pInfoS);
  507. }
  508. }
  509. }
  510. else if(pInfoS->nResType == DEV_RES_TYPE_TRUNK) // 外线
  511. {
  512. UINT TrunkId = 0;
  513. sscanf_s(pInfoS->szResId, "%lu", &TrunkId);
  514. CTrunkBase* pTrunk = CTrunkContainer::getTrunk(TrunkId);
  515. ASSERT(pTrunk != NULL);
  516. if(pTrunk!= NULL)
  517. pTrunk->onDevLinkEventS(pInfoS);
  518. } // end if
  519. }
  520. /*****************************************************************
  521. **【函数名称】 onDevLinkEventA
  522. **【函数功能】 DEV Link A 事件响应
  523. **【参数】 DevLinkCallId DevLink CallId
  524. **【返回值】
  525. ****************************************************************/
  526. void CTapiControl::onDevLinkEventA( int DevLinkCallId )
  527. {
  528. // 通知关随的分机
  529. POSITION pos = m_MapLineByDevID.GetStartPosition();
  530. while(pos != NULL)
  531. {
  532. CTapiLine* pLine = NULL;
  533. DWORD DevId = 0;
  534. m_MapLineByDevID.GetNextAssoc(pos, DevId, pLine);
  535. if(pLine->isAssoDevLinkCallId(DevLinkCallId))
  536. pLine->onDevLinkEventA(DevLinkCallId);
  537. } // end while
  538. // 通知关联的外线
  539. CTrunkBase* pTrunk = CTrunkContainer::getTrunkByCallId(DevLinkCallId);
  540. if(pTrunk != NULL)
  541. pTrunk->onDevLinkEventA(DevLinkCallId);
  542. }
  543. /*****************************************************************
  544. **【函数名称】 onDevLinkEventD
  545. **【函数功能】 DEV Link D 事件响应
  546. **【参数】 DevLinkCallId DevLink CallId
  547. **【返回值】
  548. ****************************************************************/
  549. void CTapiControl::onDevLinkEventD( int DevLinkCallId )
  550. {
  551. // 通知关联的分机
  552. POSITION pos = m_MapLineByDevID.GetStartPosition();
  553. while(pos != NULL)
  554. {
  555. CTapiLine* pLine = NULL;
  556. DWORD nDevId = 0;
  557. m_MapLineByDevID.GetNextAssoc(pos, nDevId, pLine);
  558. if(pLine->isAssoDevLinkCallId(DevLinkCallId))
  559. pLine->onDevLinkEventD(DevLinkCallId);
  560. } // end while
  561. // 通知关联的外线
  562. CTrunkBase* pTrunk = CTrunkContainer::getTrunkByCallId(DevLinkCallId);
  563. if(pTrunk != NULL)
  564. pTrunk->onDevLinkEventD(DevLinkCallId);
  565. }