修改三方通话功能,在发起三方通话时,先保持住主叫,然后再拉回主叫到会议

PBX.cpp 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. #include "StdAfx.h"
  2. #include "PBX.h"
  3. #include "DevDsp.h"
  4. #include "MC.h"
  5. #include "DevIpm.h"
  6. #include "DevVoip.h"
  7. #include "VoipChannel.h"
  8. #include "Config.h"
  9. #include "DevSpan.h"
  10. #include "SpanChannel.h"
  11. CPBX::CPBX(CMC* pParent, int IsxNo) : m_pParent(pParent), m_IsxNo(IsxNo), m_state(0)
  12. {
  13. }
  14. CPBX::~CPBX(void)
  15. {
  16. __free();
  17. }
  18. /*****************************************************************
  19. **【函数名称】 __free
  20. **【函数功能】 释放资源
  21. **【参数】
  22. **【返回值】
  23. ****************************************************************/
  24. void CPBX::__free( void )
  25. {
  26. if (!m_SpanList.IsEmpty())
  27. {
  28. for(int i = 0; i < m_SpanList.GetCount(); ++i)
  29. {
  30. m_SpanList[i]->close();
  31. delete m_SpanList[i];
  32. }
  33. m_SpanList.RemoveAll();
  34. }
  35. if (!m_DspList.IsEmpty())
  36. {
  37. for(int i = 0; i < m_DspList.GetCount(); ++i)
  38. {
  39. m_DspList[i]->close();
  40. delete m_DspList[i];
  41. }
  42. m_DspList.RemoveAll();
  43. }
  44. if (!m_VoipList.IsEmpty())
  45. {
  46. for(int i = 0; i < m_VoipList.GetCount(); ++i)
  47. {
  48. m_VoipList[i]->close();
  49. delete m_VoipList[i];
  50. }
  51. m_VoipList.RemoveAll();
  52. }
  53. if (!m_IpmList.IsEmpty())
  54. {
  55. for(int i = 0; i < m_IpmList.GetCount(); ++i)
  56. {
  57. m_IpmList[i]->close();
  58. delete m_IpmList[i];
  59. }
  60. m_IpmList.RemoveAll();
  61. }
  62. }
  63. /*****************************************************************
  64. **【函数名称】 __getSpan
  65. **【函数功能】 获取Span设备
  66. **【参数】
  67. **【返回值】
  68. ****************************************************************/
  69. CDevSpan* CPBX::__getSpan( int BoardNo, bool NewWhenNull /*= false*/ )
  70. {
  71. if(BoardNo == DEVICE_BRD_NO_ANY)
  72. {
  73. if(m_SpanList.IsEmpty())
  74. return NULL;
  75. else
  76. return m_SpanList[0];
  77. }
  78. else
  79. {
  80. CDevSpan* pSpan = NULL;
  81. for(int i = 0; i < m_SpanList.GetCount(); ++i)
  82. {
  83. pSpan = m_SpanList[i];
  84. ASSERT(pSpan != NULL);
  85. if(pSpan->boardNo() == BoardNo)
  86. return pSpan;
  87. }
  88. if(NewWhenNull)
  89. {
  90. // 查不到指定设备,则新建一个
  91. pSpan = new CDevSpan(m_IsxNo, BoardNo);
  92. ASSERT(pSpan != NULL);
  93. m_SpanList.Add(pSpan);
  94. return pSpan;
  95. }
  96. return NULL;
  97. }
  98. }
  99. /*****************************************************************
  100. **【函数名称】 __getDsp
  101. **【函数功能】 获取DSP设备
  102. **【参数】
  103. **【返回值】
  104. ****************************************************************/
  105. CDevDsp* CPBX::__getDsp( int BoardNo, bool NewWhenNull /*= false*/ )
  106. {
  107. if(BoardNo == DEVICE_BRD_NO_ANY)
  108. {
  109. if(m_DspList.IsEmpty())
  110. return NULL;
  111. else
  112. return m_DspList[0];
  113. }
  114. else
  115. {
  116. CDevDsp* pDsp = NULL;
  117. for(int i = 0; i < m_DspList.GetCount(); ++i)
  118. {
  119. pDsp = m_DspList[i];
  120. ASSERT(pDsp != NULL);
  121. if(pDsp->boardNo() == BoardNo)
  122. return pDsp;
  123. }
  124. if(NewWhenNull)
  125. {
  126. // 查不到指定设备,则新建一个
  127. pDsp = new CDevDsp(m_IsxNo, BoardNo);
  128. ASSERT(pDsp != NULL);
  129. m_DspList.Add(pDsp);
  130. return pDsp;
  131. }
  132. return NULL;
  133. }
  134. }
  135. /*****************************************************************
  136. **【函数名称】 __getVoip
  137. **【函数功能】 获取VOIP设备
  138. **【参数】
  139. **【返回值】
  140. ****************************************************************/
  141. CDevVoip* CPBX::__getVoip( int BoardNo, bool NewWhenNull /*= false*/ )
  142. {
  143. if(BoardNo == DEVICE_BRD_NO_ANY)
  144. {
  145. if(m_VoipList.IsEmpty())
  146. return NULL;
  147. else
  148. return m_VoipList[0];
  149. }
  150. else
  151. {
  152. CDevVoip* pVoip = NULL;
  153. for(int i = 0; i < m_VoipList.GetCount(); ++i)
  154. {
  155. pVoip = m_VoipList[i];
  156. ASSERT(pVoip != NULL);
  157. if(pVoip->boardNo() == BoardNo)
  158. return pVoip;
  159. }
  160. if(NewWhenNull)
  161. {
  162. // 查不到指定设备,则新建一个
  163. pVoip = new CDevVoip(m_IsxNo, BoardNo);
  164. ASSERT(pVoip != NULL);
  165. m_VoipList.Add(pVoip);
  166. return pVoip;
  167. }
  168. return NULL;
  169. }
  170. }
  171. /*****************************************************************
  172. **【函数名称】 __getIpm
  173. **【函数功能】 获取IPM设备
  174. **【参数】
  175. **【返回值】
  176. ****************************************************************/
  177. CDevIpm* CPBX::__getIpm( int BoardNo, bool NewWhenNull /*= false*/ )
  178. {
  179. if(BoardNo == DEVICE_BRD_NO_ANY)
  180. {
  181. if(m_IpmList.IsEmpty())
  182. return NULL;
  183. else
  184. return m_IpmList[0];
  185. }
  186. else
  187. {
  188. CDevIpm* pIpm = NULL;
  189. for(int i = 0; i < m_IpmList.GetCount(); ++i)
  190. {
  191. pIpm = m_IpmList[i];
  192. ASSERT(pIpm != NULL);
  193. if(pIpm->boardNo() == BoardNo)
  194. return pIpm;
  195. }
  196. if(NewWhenNull)
  197. {
  198. // 查不到指定设备,则新建一个
  199. pIpm = new CDevIpm(m_IsxNo, BoardNo);
  200. ASSERT(pIpm != NULL);
  201. m_IpmList.Add(pIpm);
  202. return pIpm;
  203. }
  204. return NULL;
  205. }
  206. }
  207. /*****************************************************************
  208. **【函数名称】 __isSpanOk
  209. **【函数功能】 Span设备目前是否可用
  210. **【参数】
  211. **【返回值】
  212. ****************************************************************/
  213. bool CPBX::__isSpanOk( void ) const
  214. {
  215. if(CConfig::digitalTrunkCount() <= 0)
  216. return true;
  217. if(m_SpanList.IsEmpty())
  218. return false;
  219. for(int i = 0; i < m_SpanList.GetCount(); ++i)
  220. {
  221. if(!m_SpanList[i]->isOk())
  222. return false;
  223. }
  224. return true;
  225. }
  226. /*****************************************************************
  227. **【函数名称】 __isDspOk
  228. **【函数功能】 DSP设备目前是否可用
  229. **【参数】
  230. **【返回值】
  231. ****************************************************************/
  232. bool CPBX::__isDspOk( void ) const
  233. {
  234. if(m_DspList.IsEmpty())
  235. return false;
  236. for(int i = 0; i < m_DspList.GetCount(); ++i)
  237. {
  238. if(!m_DspList[i]->isOk())
  239. return false;
  240. }
  241. return true;
  242. }
  243. /*****************************************************************
  244. **【函数名称】 __isVoipOk
  245. **【函数功能】 VOIP设备目前是否可用
  246. **【参数】
  247. **【返回值】
  248. ****************************************************************/
  249. bool CPBX::__isVoipOk( void ) const
  250. {
  251. if(m_VoipList.IsEmpty())
  252. return false;
  253. for(int i = 0; i < m_VoipList.GetCount(); ++i)
  254. {
  255. if(!m_VoipList[i]->isOk())
  256. return false;
  257. }
  258. return true;
  259. }
  260. /*****************************************************************
  261. **【函数名称】 __isIpmOk
  262. **【函数功能】 IPM设备目前是否可用
  263. **【参数】
  264. **【返回值】
  265. ****************************************************************/
  266. bool CPBX::__isIpmOk( void ) const
  267. {
  268. if(m_IpmList.IsEmpty())
  269. return false;
  270. for(int i = 0; i < m_IpmList.GetCount(); ++i)
  271. {
  272. if(!m_IpmList[i]->isOk())
  273. return false;
  274. }
  275. return true;
  276. }
  277. /*****************************************************************
  278. **【函数名称】 isOk
  279. **【函数功能】 设备目前是否可用
  280. **【参数】
  281. **【返回值】
  282. ****************************************************************/
  283. bool CPBX::isOk( void ) const
  284. {
  285. if(m_state != STATUS_WORKING)
  286. return false;
  287. if(!__isSpanOk())
  288. return false;
  289. if(!__isDspOk())
  290. return false;
  291. if(!__isVoipOk())
  292. return false;
  293. if(!__isIpmOk())
  294. return false;
  295. return true;
  296. }
  297. /*****************************************************************
  298. **【函数名称】 getVoipNetId
  299. **【函数功能】 获取VOIP卡网络标识
  300. **【参数】
  301. **【返回值】
  302. ****************************************************************/
  303. ULONG CPBX::getVoipNetId( int BoardNo )
  304. {
  305. CDevVoip* pVoip = __getVoip(BoardNo);
  306. ASSERT(pVoip != NULL);
  307. if(pVoip != NULL)
  308. return pVoip->netId();
  309. else
  310. return 0;
  311. }
  312. /*****************************************************************
  313. **【函数名称】 allocVoipCh4Exten
  314. **【函数功能】 为分机分配VOIP通道
  315. **【参数】
  316. **【返回值】
  317. ****************************************************************/
  318. CVoipChannel* CPBX::allocVoipCh4Exten( void )
  319. {
  320. CVoipChannel* pChan = NULL;
  321. for(int i = 0; i < m_VoipList.GetCount(); ++i)
  322. {
  323. CDevVoip* pVoip = m_VoipList[i];
  324. ASSERT(pVoip != NULL);
  325. if(pVoip->service4Exten())
  326. {
  327. pChan = pVoip->getFreeVoipCh();
  328. if(pChan != NULL)
  329. break;
  330. }
  331. }
  332. return pChan;
  333. }
  334. /*****************************************************************
  335. **【函数名称】 allocIpmCh
  336. **【函数功能】 根据网络标识分配IPM通道
  337. **【参数】
  338. **【返回值】
  339. ****************************************************************/
  340. CIpmChannel* CPBX::allocIpmCh( ULONG NetId )
  341. {
  342. CIpmChannel* pChan = NULL;
  343. if(m_IpmList.GetCount() == 1) // 单IPM板则直接由此板分配IPM通道
  344. {
  345. pChan = m_IpmList[0]->getFreeIpmCh();
  346. }
  347. else // 多IPM板则根据网络标识选择板子分配IPM通道
  348. {
  349. for(int i = 0; i < m_IpmList.GetCount(); ++i)
  350. {
  351. CDevIpm* pIpm = m_IpmList[i];
  352. ASSERT(pIpm != NULL);
  353. if(NetId == pIpm->netId())
  354. {
  355. pChan = pIpm->getFreeIpmCh();
  356. if(pChan != NULL)
  357. break;
  358. }
  359. }
  360. }
  361. return pChan;
  362. }
  363. /*****************************************************************
  364. **【函数名称】 allocSpanCh
  365. **【函数功能】 分配数字中继通道
  366. **【参数】
  367. **【返回值】
  368. ****************************************************************/
  369. CSpanChannel* CPBX::allocSpanCh( int BoardNo, int SpanNo )
  370. {
  371. CDevSpan* pSpan = __getSpan(BoardNo);
  372. ASSERT(pSpan != NULL);
  373. if(pSpan != NULL)
  374. return pSpan->getFreeSpanCh(SpanNo);
  375. else
  376. return NULL;
  377. }
  378. /*****************************************************************
  379. **【函数名称】 allocVoipCh
  380. **【函数功能】 分配VOIP通道
  381. **【参数】
  382. **【返回值】
  383. ****************************************************************/
  384. CVoipChannel* CPBX::allocVoipCh( int BoardNo )
  385. {
  386. CDevVoip* pVoip = __getVoip(BoardNo);
  387. ASSERT(pVoip != NULL);
  388. if(pVoip != NULL)
  389. return pVoip->getFreeVoipCh();
  390. else
  391. return NULL;
  392. }
  393. /*****************************************************************
  394. **【函数名称】 allocDspCh
  395. **【函数功能】 分配DSP通道
  396. **【参数】
  397. **【返回值】
  398. ****************************************************************/
  399. CDspChannel* CPBX::allocDspCh( int p_BoardNo )
  400. {
  401. CDspChannel* pChan = NULL;
  402. for(int i = 0; i < m_DspList.GetCount(); ++i)
  403. {
  404. CDevDsp* pDsp = m_DspList[i];
  405. ASSERT(pDsp != NULL);
  406. if(p_BoardNo == DEVICE_BRD_NO_ANY || pDsp->boardNo() == p_BoardNo)
  407. {
  408. pChan = pDsp->getFreeDspCh();
  409. if(pChan != NULL)
  410. break;
  411. }
  412. }
  413. if (pChan == NULL)
  414. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{PBX_%d}:allocDspCh,brdNo=%d,No dsp channel."), m_IsxNo, p_BoardNo);
  415. else
  416. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{PBX_%d}:allocDspCh,brdNo=%d"), m_IsxNo, p_BoardNo);
  417. return pChan;
  418. }
  419. /*****************************************************************
  420. **【函数名称】 allocFreeTrunk
  421. **【函数功能】 分配空闲中继线路
  422. **【参数】
  423. **【返回值】
  424. ****************************************************************/
  425. COneLeg* CPBX::allocFreeTrunk(int BoardNo, int SpanNo)
  426. {
  427. COneLeg* pCallLeg = NULL;
  428. // 从板子号不好确认中继类型,所以优先考虑E1数字中继
  429. if (CConfig::digitalTrunkCount() > 0 && SpanNo != INVALID_ID_DT_SPAN)
  430. pCallLeg = allocSpanCh(BoardNo, SpanNo);
  431. // 数字中继不行,使用VOIP中继
  432. if (pCallLeg == NULL && CConfig::voipTrunkCount() > 0)
  433. {
  434. pCallLeg = allocVoipCh(BoardNo);
  435. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{PBX_%d}:allocFreeTrunk,使用VOIP中继,brdNo=%d"), m_IsxNo, BoardNo);
  436. }
  437. return pCallLeg;
  438. }
  439. /*****************************************************************
  440. **【函数名称】 findLineResource
  441. **【函数功能】 查找指定的线路资源
  442. **【参数】
  443. **【返回值】
  444. ****************************************************************/
  445. COneLeg* CPBX::findLeg( CRDRID Id )
  446. {
  447. COneLeg* pLeg = NULL;
  448. if(Id.ResType == DEV_RES_TYPE_VOIP) // 搜寻VOIP通道
  449. {
  450. CDevVoip* pVoip = __getVoip(Id.BoardNo);
  451. ASSERT(pVoip != NULL);
  452. pLeg = pVoip->findChan(Id.ChanNo);
  453. }
  454. else if(Id.ResType == DEV_RES_TYPE_TRUNK) // 搜索DTI通道
  455. {
  456. CDevSpan* pSpan = __getSpan(Id.BoardNo);
  457. ASSERT(pSpan != NULL);
  458. pLeg = pSpan->findChan(Id.SpanNo, Id.ChanNo);
  459. }
  460. return pLeg;
  461. }
  462. /*****************************************************************
  463. **【函数名称】 meetingCreate
  464. **【函数功能】 创建会议
  465. **【参数】
  466. **【返回值】
  467. ****************************************************************/
  468. bool CPBX::meetingCreate( int BoardNo, MeetingInfo& MeetingId )
  469. {
  470. CDevDsp* pDsp = __getDsp(BoardNo);
  471. ASSERT(pDsp != NULL);
  472. if(pDsp != NULL)
  473. return pDsp->createMeeting(MeetingId);
  474. else
  475. return false;
  476. }
  477. /*****************************************************************
  478. **【函数名称】 meetingDelete
  479. **【函数功能】 删除会议
  480. **【参数】
  481. **【返回值】
  482. ****************************************************************/
  483. void CPBX::meetingDelete( MeetingInfo& MeetingId )
  484. {
  485. CDevDsp* pDsp = __getDsp(MeetingId.BoardNo);
  486. ASSERT(pDsp != NULL);
  487. if(pDsp != NULL)
  488. return pDsp->deleteMeeting(MeetingId);
  489. }
  490. /*****************************************************************
  491. **【函数名称】 meetingJoin
  492. **【函数功能】 加入会议
  493. **【参数】
  494. **【返回值】
  495. ****************************************************************/
  496. bool CPBX::meetingJoin( int BoardNo, COneLeg* pLeg, MeetingInfo& MeetingId, bool IsOneWay )
  497. {
  498. CDevDsp* pDsp = __getDsp(BoardNo);
  499. ASSERT(pDsp != NULL);
  500. if(pDsp != NULL)
  501. {
  502. if(pDsp->meetingAccept(MeetingId.MeetingId, pLeg, IsOneWay))
  503. {
  504. pLeg->setMeetingInfo(MeetingId.NodeNo, MeetingId.BoardNo, MeetingId.MeetingId);
  505. return true;
  506. }
  507. }
  508. return false;
  509. }
  510. /*****************************************************************
  511. **【函数名称】 meetingRemove
  512. **【函数功能】 离开会议
  513. **【参数】
  514. **【返回值】
  515. ****************************************************************/
  516. bool CPBX::meetingRemove( int BoardNo, COneLeg* pLeg, MeetingInfo& MeetingId )
  517. {
  518. CDevDsp* pDsp = __getDsp(BoardNo);
  519. ASSERT(pDsp != NULL);
  520. if(pDsp != NULL)
  521. {
  522. if(pDsp->meetingRemove(MeetingId.MeetingId, pLeg))
  523. {
  524. pLeg->setMeetingInfo(0, 0, MEETING_ID_INVALID);
  525. return true;
  526. }
  527. }
  528. return false;
  529. }
  530. /*****************************************************************
  531. **【函数名称】 meetingRecord
  532. **【函数功能】 会议录音
  533. **【参数】
  534. **【返回值】
  535. ****************************************************************/
  536. bool CPBX::meetingRecord( int BoardNo, COneLeg* pLeg, MeetingInfo& MeetingId, RecordContent* pContent, bool IsStop )
  537. {
  538. CDevDsp* pDsp = __getDsp(BoardNo);
  539. ASSERT(pDsp != NULL);
  540. if(pDsp != NULL)
  541. return pDsp->meetingRecord(MeetingId.MeetingId, pLeg, pContent, IsStop);
  542. else
  543. return false;
  544. }
  545. /*****************************************************************
  546. **【函数名称】 meetingMute
  547. **【函数功能】 静音会议中线路
  548. **【参数】
  549. **【返回值】
  550. ****************************************************************/
  551. bool CPBX::meetingMute( int BoardNo, COneLeg* pLeg, MeetingInfo& MeetingId, bool IsOff )
  552. {
  553. CDevDsp* pDsp = __getDsp(BoardNo);
  554. ASSERT(pDsp != NULL);
  555. if(pDsp != NULL)
  556. return pDsp->meetingMute(MeetingId.MeetingId, pLeg, IsOff);
  557. else
  558. return false;
  559. }
  560. /*****************************************************************
  561. **【函数名称】 onResourceStateUpdated
  562. **【函数功能】 设备资源状态更新处理函数
  563. **【参数】
  564. **【返回值】
  565. ****************************************************************/
  566. void CPBX::onResourceStateUpdated( INT EvtType, SYS_EVT_DATA* pEvtData )
  567. {
  568. ASSERT(pEvtData != NULL);
  569. LOG_LEVEL Level;
  570. CHAR State = pEvtData->u.cStatus;
  571. if(State == STATUS_WORKING)
  572. Level = LOG_LEVEL_NORMAL;
  573. else
  574. Level = LOG_LEVEL_WARNING;
  575. switch(EvtType)
  576. {
  577. case SYSEV_MB_STATUS:
  578. {
  579. if(State != STATUS_WORKING)
  580. {
  581. if(m_state == STATUS_WORKING)
  582. m_pParent->onPbxResInvalid(m_IsxNo, m_IsxNo, DEV_RES_TYPE_MB);
  583. m_state = State;
  584. }
  585. else
  586. {
  587. m_state = STATUS_WORKING;
  588. if(isOk())
  589. m_pParent->onPbxResValid(m_IsxNo);
  590. }
  591. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: MB state is updated, state = %s"), m_IsxNo, m_pParent->transState(State));
  592. }
  593. break;
  594. case SYSEV_SPAN_STATUS:
  595. {
  596. CDevSpan* pSpan = __getSpan(pEvtData->cBrdNo, true);
  597. ASSERT(pSpan != NULL);
  598. if(State == STATUS_WORKING)
  599. {
  600. pSpan->state() = STATUS_WORKING;
  601. if(CConfig::digitalTrunkCount() > 0)
  602. {
  603. if(!pSpan->open(pEvtData->cSpanNum))
  604. m_pParent->onPbxResInvalid(m_IsxNo, pSpan->boardNo(), DEV_RES_TYPE_TRUNK);
  605. }
  606. if(isOk())
  607. m_pParent->onPbxResValid(m_IsxNo);
  608. }
  609. else
  610. {
  611. if(pSpan != NULL)
  612. {
  613. if(pSpan->state() == STATUS_WORKING)
  614. {
  615. pSpan->close(pEvtData->cSpanNum);
  616. m_pParent->onPbxResInvalid(m_IsxNo, pSpan->boardNo(), DEV_RES_TYPE_TRUNK);
  617. }
  618. pSpan->state() = State;
  619. }
  620. }
  621. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: SPAN[%d] state is updated, state = %s"),
  622. m_IsxNo, pEvtData->cBrdNo, m_pParent->transState(State));
  623. }
  624. break;
  625. case SYSEV_DSP_STATUS:
  626. {
  627. CDevDsp* pDsp = __getDsp(pEvtData->cBrdNo, true);
  628. ASSERT(pDsp != NULL);
  629. if(State == STATUS_WORKING)
  630. {
  631. pDsp->state() = State;
  632. if(pDsp->capacity() > 0)
  633. {
  634. if(!pDsp->open())
  635. m_pParent->onPbxResInvalid(m_IsxNo, pDsp->boardNo(), DEV_RES_TYPE_DSP);
  636. }
  637. if(isOk())
  638. m_pParent->onPbxResValid(m_IsxNo);
  639. }
  640. else
  641. {
  642. if(pDsp != NULL)
  643. {
  644. if(pDsp->state() == STATUS_WORKING)
  645. {
  646. pDsp->close();
  647. m_pParent->onPbxResInvalid(m_IsxNo, pDsp->boardNo(), DEV_RES_TYPE_DSP);
  648. }
  649. pDsp->state() = State;
  650. }
  651. }
  652. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: DSP[%d] state is updated, state = %s"),
  653. m_IsxNo, pEvtData->cBrdNo, m_pParent->transState(State));
  654. }
  655. break;
  656. case SYSEV_SIP_STATUS:
  657. {
  658. CDevVoip* pVoip = __getVoip(pEvtData->cBrdNo, true);
  659. ASSERT(pVoip != NULL);
  660. if(State == STATUS_WORKING)
  661. {
  662. pVoip->state() = State;
  663. if(pVoip->capacity() > 0)
  664. {
  665. if(!pVoip->open())
  666. m_pParent->onPbxResInvalid(m_IsxNo, pVoip->boardNo(), DEV_RES_TYPE_VOIP);
  667. }
  668. if(isOk())
  669. m_pParent->onPbxResValid(m_IsxNo);
  670. }
  671. else
  672. {
  673. if(pVoip != NULL)
  674. {
  675. if(pVoip->state() == STATUS_WORKING)
  676. {
  677. pVoip->close();
  678. m_pParent->onPbxResInvalid(m_IsxNo, pVoip->boardNo(), DEV_RES_TYPE_VOIP);
  679. }
  680. pVoip->state() = State;
  681. }
  682. }
  683. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: SIP[%d] state is updated, state = %s"),
  684. pEvtData->cIsxNo, pEvtData->cBrdNo, m_pParent->transState(State));
  685. }
  686. break;
  687. case SYSEV_XOIP_STATUS:
  688. {
  689. CDevIpm* pIpm = __getIpm(pEvtData->cBrdNo, true);
  690. ASSERT(pIpm != NULL);
  691. if(State == STATUS_WORKING)
  692. {
  693. pIpm->state() = State;
  694. if(pIpm->capacity() > 0)
  695. {
  696. if(!pIpm->open())
  697. m_pParent->onPbxResInvalid(m_IsxNo, pIpm->boardNo(), DEV_RES_TYPE_IPM);
  698. }
  699. if(isOk())
  700. m_pParent->onPbxResValid(m_IsxNo);
  701. }
  702. else
  703. {
  704. if(pIpm != NULL)
  705. {
  706. if(pIpm->state() == STATUS_WORKING)
  707. {
  708. m_pParent->onPbxResInvalid(m_IsxNo, pIpm->boardNo(), DEV_RES_TYPE_IPM);
  709. pIpm->close();
  710. }
  711. pIpm->state() = State;
  712. }
  713. }
  714. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: XOIP[%d] state is updated, state = %s"),
  715. pEvtData->cIsxNo, pEvtData->cBrdNo, m_pParent->transState(State));
  716. }
  717. break;
  718. case SYSEV_PRI_STATUS:
  719. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: PRI[%d] state is updated, state = %s"),
  720. pEvtData->cIsxNo, pEvtData->cBrdNo, m_pParent->transState(State));
  721. break;
  722. case SYSEV_SS7_STATUS:
  723. LOGGER(LOG_CLASS_DEV, Level, _T("{PBX_%d}: SS7[%d] state is updated, state = %s"),
  724. pEvtData->cIsxNo, pEvtData->cBrdNo, m_pParent->transState(State));
  725. break;
  726. }
  727. }
  728. /*****************************************************************
  729. **【函数名称】 onResourceAlarm
  730. **【函数功能】 设备资源告警处理函数
  731. **【参数】
  732. **【返回值】
  733. ****************************************************************/
  734. void CPBX::onResourceAlarm( INT EvtType, SYS_EVT_DATA* pEvtData )
  735. {
  736. ASSERT(pEvtData != NULL);
  737. switch(EvtType)
  738. {
  739. case SYSEV_SPAN_ALARM:
  740. {
  741. if(pEvtData->u.usAlarm == 0)
  742. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{PBX_%d}: SPAN[%d-%d]告警解除"),
  743. pEvtData->cIsxNo, pEvtData->cBrdNo, pEvtData->cSpanNum);
  744. else
  745. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{PBX_%d}: SPAN[%d-%d]告警, Code = 0x%x"),
  746. pEvtData->cIsxNo, pEvtData->cBrdNo, pEvtData->cSpanNum, pEvtData->u.usAlarm);
  747. }
  748. break;
  749. case SYSEV_PRIDCH_ALARM:
  750. {
  751. if(pEvtData->u.dchAlarm.ucAlarm == 0)
  752. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{PBX_%d}: PRI[%d-%d]D通道告警解除"),
  753. pEvtData->cIsxNo, pEvtData->cBrdNo, pEvtData->u.dchAlarm.ch.spanno);
  754. else
  755. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{PBX_%d}: PRI[%d-%d]D通道告警, Code = 0x%x"),
  756. pEvtData->cIsxNo, pEvtData->cBrdNo, pEvtData->u.dchAlarm.ch.spanno, pEvtData->u.dchAlarm.ucAlarm);
  757. }
  758. break;
  759. case SYSEV_S7LINK_ALARM:
  760. {
  761. if(pEvtData->u.linkAlarm.ucAlarm == 0)
  762. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{PBX_%d}: SS7[%d]链路[%d]告警解除"),
  763. pEvtData->cIsxNo, pEvtData->cBrdNo, pEvtData->u.linkAlarm.ucStackId);
  764. else
  765. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{PBX_%d}: SS7[%d]链路[%d]告警, Code = 0x%x"),
  766. pEvtData->cIsxNo, pEvtData->cBrdNo, pEvtData->u.linkAlarm.ucStackId, pEvtData->u.linkAlarm.ucAlarm);
  767. }
  768. break;
  769. }
  770. }
  771. /*****************************************************************
  772. **【函数名称】 onResourceCapacity
  773. **【函数功能】 设备资源容量处理函数
  774. **【参数】
  775. **【返回值】
  776. ****************************************************************/
  777. void CPBX::onResourceCapacity( INT EvtType, SYS_EVT_DATA* pEvtData )
  778. {
  779. switch(EvtType)
  780. {
  781. case SYSEV_DSP_BRD_CAP:
  782. {
  783. CDevDsp* pDsp = __getDsp(pEvtData->cBrdNo, true);
  784. ASSERT(pDsp != NULL);
  785. if(pDsp->state() == STATUS_WORKING)
  786. {
  787. pDsp->capacity() = pEvtData->u.sCap;
  788. if(!pDsp->open())
  789. m_pParent->onPbxResInvalid(m_IsxNo, pDsp->boardNo(), DEV_RES_TYPE_DSP);
  790. }
  791. }
  792. break;
  793. case SYSEV_SIP_BRD_CAP:
  794. {
  795. CDevVoip* pVoip = __getVoip(pEvtData->cBrdNo, true);
  796. ASSERT(pVoip != NULL);
  797. if(pVoip->state() == STATUS_WORKING)
  798. {
  799. pVoip->capacity() = pEvtData->u.sCap;
  800. if(!pVoip->open())
  801. m_pParent->onPbxResInvalid(m_IsxNo, pVoip->boardNo(), DEV_RES_TYPE_VOIP);
  802. }
  803. }
  804. break;
  805. case SYSEV_XOIP_BRD_CAP:
  806. {
  807. CDevIpm* pIpm = __getIpm(pEvtData->cBrdNo, true);
  808. ASSERT(pIpm != NULL);
  809. if(pIpm->state() == STATUS_WORKING)
  810. {
  811. pIpm->capacity() = pEvtData->u.sCap;
  812. if(!pIpm->open())
  813. m_pParent->onPbxResInvalid(m_IsxNo, pIpm->boardNo(), DEV_RES_TYPE_IPM);
  814. }
  815. }
  816. break;
  817. }
  818. }
  819. /*****************************************************************
  820. **【函数名称】 onSipRegSent
  821. **【函数功能】 处理SIP注册发送事件
  822. **【参数】
  823. **【返回值】
  824. ****************************************************************/
  825. void CPBX::onSipRegSent( SEND_SIPREG_RET* pSent )
  826. {
  827. CDevVoip* pVoip = __getVoip(pSent->RegisterId.ucBrdNo);
  828. ASSERT(pVoip != NULL);
  829. pVoip->onSipRegSent(pSent);
  830. }
  831. /*****************************************************************
  832. **【函数名称】 onSipRegAck
  833. **【函数功能】 处理SIP注册确认事件
  834. **【参数】
  835. **【返回值】
  836. ****************************************************************/
  837. void CPBX::onSipRegAck( SIP_REGISTER_ACK* pAck )
  838. {
  839. CDevVoip* pVoip = __getVoip(pAck->RegisterId.ucBrdNo);
  840. ASSERT(pVoip != NULL);
  841. pVoip->onSipRegAck(pAck);
  842. }
  843. /*****************************************************************
  844. **【函数名称】 onSipTransaction
  845. **【函数功能】 收到SIP事务事件的处理函数
  846. **【参数】
  847. **【返回值】
  848. ****************************************************************/
  849. void CPBX::onSipTransaction( SIP_TRANSACTION_IND* pTransaction )
  850. {
  851. CDevVoip* pVoip = __getVoip(pTransaction->ucBrdNo);
  852. ASSERT(pVoip != NULL);
  853. pVoip->onSipTransaction(pTransaction);
  854. }
  855. /*****************************************************************
  856. **【函数名称】 findIpmCh
  857. **【函数功能】 查找IPM通道
  858. **【参数】
  859. **【返回值】
  860. ****************************************************************/
  861. CIpmChannel* CPBX::findIpmCh( CRDRID ResId )
  862. {
  863. CDevIpm* pIpm = __getIpm(ResId.BoardNo);
  864. ASSERT(pIpm != NULL);
  865. return pIpm->findChan(ResId.ChanNo);
  866. }
  867. /*****************************************************************
  868. **【函数名称】 findDspCh
  869. **【函数功能】 查找DSP通道
  870. **【参数】
  871. **【返回值】
  872. ****************************************************************/
  873. CDspChannel* CPBX::findDspCh( CRDRID ResId )
  874. {
  875. CDevDsp* pDsp = __getDsp(ResId.BoardNo);
  876. ASSERT(pDsp != NULL);
  877. return pDsp->findChan(ResId.ChanNo);
  878. }
  879. /*****************************************************************
  880. **【函数名称】 findVoipCh
  881. **【函数功能】 查找VOIP通道
  882. **【参数】
  883. **【返回值】
  884. ****************************************************************/
  885. CVoipChannel* CPBX::findVoipCh( CRDRID ResId )
  886. {
  887. CDevVoip* pVoip = __getVoip(ResId.BoardNo);
  888. ASSERT(pVoip != NULL);
  889. return pVoip->findChan(ResId.ChanNo);
  890. }
  891. /*****************************************************************
  892. **【函数名称】 findSpanCh
  893. **【函数功能】 查找SPAN通道
  894. **【参数】
  895. **【返回值】
  896. ****************************************************************/
  897. CSpanChannel* CPBX::findSpanCh( CRDRID ResId )
  898. {
  899. CDevSpan* pSpan = __getSpan(ResId.BoardNo);
  900. ASSERT(pSpan != NULL);
  901. return pSpan->findChan(ResId.SpanNo, ResId.ChanNo);
  902. }