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

DeviceMgr.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. #include "StdAfx.h"
  2. #include "DeviceMgr.h"
  3. #include "DevFax.h"
  4. #include "NetworkVs.h"
  5. #include "LineAudio.h"
  6. #include "LineRecordAna.h"
  7. #include "LineRecordDig.h"
  8. #include "LineRecordIpra.h"
  9. #include "LineRecordIprr.h"
  10. #include "Config.h"
  11. #include "IprControl.h"
  12. SINGLETON_IMPLEMENT(CDeviceMgr)
  13. CDeviceMgr::CDeviceMgr(void)
  14. {
  15. }
  16. CDeviceMgr::~CDeviceMgr(void)
  17. {
  18. __release();
  19. }
  20. /*****************************************************************
  21. **【函数名称】 __release
  22. **【函数功能】 释放资源
  23. **【参数】
  24. **【返回值】
  25. ****************************************************************/
  26. void CDeviceMgr::__release( void )
  27. {
  28. for(int i = 0; i < m_LineArray.GetCount(); ++i)
  29. {
  30. ASSERT(m_LineArray[i] != NULL);
  31. delete m_LineArray[i];
  32. }
  33. m_LineArray.RemoveAll();
  34. while(!m_FaxList.IsEmpty())
  35. delete m_FaxList.RemoveHead();
  36. }
  37. /*****************************************************************
  38. **【函数名称】 __initLineObject
  39. **【函数功能】 初始化线路对象
  40. **【参数】
  41. **【返回值】
  42. ****************************************************************/
  43. void CDeviceMgr::__initLineObject( void )
  44. {
  45. // 初始化线路对象
  46. int nTotalCH = SsmGetMaxCh(); // 系统通道总数
  47. for (int i = 0; i < nTotalCH; ++i)
  48. {
  49. int nType = SsmGetChType(i);
  50. switch(nType)
  51. {
  52. case CONST_CH_AUDIO_ANA: //模拟放音线路
  53. {
  54. CLineAudio * pLine = new CLineAudio(i);
  55. m_LineArray.Add(pLine);
  56. CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast<const PARAM>(i));
  57. }
  58. break;
  59. case CONST_CH_REC_ANA: //模拟录音线路
  60. {
  61. CLineRecordAna* pLine = new CLineRecordAna(i);
  62. m_LineArray.Add(pLine);
  63. CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast<const PARAM>(i));
  64. }
  65. break;
  66. case CONST_CH_REC_DIG: //数字录音线路
  67. {
  68. int nCicID = SpyChToCic(i);
  69. if (-1 == nCicID)
  70. break;
  71. if (NULL == __findLineByCicID(nCicID))
  72. {
  73. CLineRecordDig *pLine = new CLineRecordDig(i);
  74. m_LineArray.Add(pLine);
  75. CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast<const PARAM>(i));
  76. }
  77. }
  78. break;
  79. case CONST_CH_FAX: // 传真资源
  80. {
  81. CDevFax * pDevFax = new CDevFax(i);
  82. m_FaxList.AddTail(pDevFax);
  83. CMsgCenter::GetInstance().pushMsg(VS_MSG_DEV_FAX_STATE_UPDAET, reinterpret_cast<const PARAM>(i));
  84. }
  85. break;
  86. case CONST_CH_REC_IPR:
  87. {
  88. CIprControl::GetInstance().newIprrLine(i);
  89. }
  90. break;
  91. case CONST_CH_REC_IPA:
  92. {
  93. CIprControl::GetInstance().newIpraLine(i);
  94. }
  95. break;
  96. }
  97. } // end for
  98. }
  99. /*****************************************************************
  100. **【函数名称】 __findLineByCicID
  101. **【函数功能】 根据数字线路的逻辑编号查找指定数字中继线路
  102. **【参数】 int nCic 数字中继线路的逻辑编号
  103. **【返回值】
  104. ****************************************************************/
  105. CLine* CDeviceMgr::__findLineByCicID( int CicId )
  106. {
  107. int Count = m_LineArray.GetCount();
  108. for (int i = 0; i < Count; ++i)
  109. {
  110. CLine* pLine = m_LineArray[i];
  111. ASSERT(pLine != NULL);
  112. if(pLine->type() == DEV_VS_TYPE_RECDIG && pLine->cicId() == CicId)
  113. return pLine;
  114. }
  115. return NULL;
  116. }
  117. /*****************************************************************
  118. **【函数名称】 __findLineByIPOLineID
  119. **【函数功能】 根据IPO的线路ID查找线路
  120. **【参数】
  121. **【返回值】
  122. ****************************************************************/
  123. CLine* CDeviceMgr::__findLineByIPOLineID( int IpoLineID )
  124. {
  125. int Count = m_LineArray.GetCount();
  126. for (int i = 0; i < Count; ++i)
  127. {
  128. CLine* pLine = m_LineArray[i];
  129. ASSERT(pLine != NULL);
  130. if (pLine->assoIpoId() == IpoLineID)
  131. return pLine;
  132. }
  133. return CIprControl::GetInstance().findLineByIPOLineID(IpoLineID);
  134. }
  135. /*****************************************************************
  136. **【函数名称】 __callBackProc
  137. **【函数功能】 回调函数
  138. **【参数】 wEvent:系统当前触发的事件,nReference:通道逻辑号,dwParam:事件输出参数dwUser:用户自定义参数
  139. **【返回值】
  140. ****************************************************************/
  141. void CDeviceMgr::__callBackProc( PSSM_EVENT pEvent )
  142. {
  143. CLine* pLine = NULL;
  144. switch(pEvent->wEventCode)
  145. {
  146. case E_CHG_ChState: //通道状态发生变化
  147. case E_PROC_PlayEnd: //放音任务完成
  148. case E_CHG_BusyTone: //检测到忙音,即挂机
  149. case E_PROC_WaitDTMF: //WaitDTMF任务完成
  150. case E_PROC_RecordEnd: //录音任务终止
  151. pLine = findLineByID(pEvent->nReference);
  152. break;
  153. case E_CHG_FaxPages:
  154. {
  155. int FaxEnd = SsmFaxCheckEnd(pEvent->nReference);
  156. if (FaxEnd == 3) // 已经完成全部传真的接收与发送,正在断开
  157. {
  158. CDevFax* pDevFax = getFaxByID(pEvent->nReference);
  159. ASSERT(pDevFax != NULL);
  160. pLine = pDevFax->getAssoLine();
  161. pEvent->dwParam = 1;
  162. }
  163. ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevMgr}: 传真设备[%d]结束第%d页收发, Result = %d"), pEvent->nReference, pEvent->dwParam, FaxEnd);
  164. }
  165. break;
  166. case E_PROC_FaxEnd: //传真操作结束事件
  167. {
  168. CDevFax * pDevFax = getFaxByID(pEvent->nReference);
  169. pLine = pDevFax->getAssoLine();
  170. ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevMgr}: 传真设备[%d]结束传真收发, Result = %d"), pEvent->nReference, pEvent->dwParam);
  171. }
  172. break;
  173. case E_CHG_SpyState:
  174. {
  175. pLine = __findLineByCicID(pEvent->nReference);
  176. }
  177. break;
  178. case E_IPR_LINK_REC_SLAVER_CONNECTED:
  179. CIprControl::GetInstance().onEventSlaverConnected(pEvent);
  180. break;
  181. case E_IPR_LINK_REC_SLAVER_DISCONNECTED:
  182. CIprControl::GetInstance().onEventSlaverDisconnected(pEvent);
  183. break;
  184. case E_IPR_START_SLAVER_CB:
  185. CIprControl::GetInstance().onEventStartSlaverCb(pEvent);
  186. break;
  187. case E_IPR_CLOSE_SLAVER_CB:
  188. CIprControl::GetInstance().onEventCloseSlaverCb(pEvent);
  189. break;
  190. // IP录音相关
  191. case E_IPR_START_REC_CB:
  192. case E_IPR_STOP_REC_CB:
  193. case E_IPR_PAUSE_REC_CB:
  194. case E_IPR_RESTART_REC_CB:
  195. case E_IPR_ACTIVE_SESSION_CB:
  196. case E_IPR_DEACTIVE_SESSION_CB:
  197. case E_IPR_ACTIVE_AND_REC_CB:
  198. case E_IPR_DEACTIVE_AND_STOPREC_CB:
  199. case E_RCV_IPR_MEDIA_SESSION_STARTED:
  200. case E_RCV_IPR_MEDIA_SESSION_STOPED:
  201. case E_RCV_IPR_AUX_MEDIA_SESSION_STARTED:
  202. case E_RCV_IPR_AUX_MEDIA_SESSION_STOPED:
  203. pLine = findLineByID(pEvent->nReference);
  204. break;
  205. case E_RCV_IPR_DONGLE_REMOVED:
  206. case E_RCV_IPA_DONGLE_REMOVED:
  207. CIprControl::GetInstance().onEventUsbKeyRemoved(pEvent);
  208. break;
  209. case E_RCV_IPR_AUTH_OVERFLOW:
  210. CIprControl::GetInstance().onEventAuthOverflow(pEvent);
  211. break;
  212. case E_RCV_IPR_STATION_ADDED:
  213. CIprControl::GetInstance().onEventStationAdd(pEvent);
  214. break;
  215. case E_RCV_IPR_STATION_REMOVED:
  216. CIprControl::GetInstance().onEventStationRemoved(pEvent);
  217. break;
  218. case E_CHG_CIDExBuf: //收到主叫号码
  219. case E_CHG_RcvDTMF:
  220. case E_SYS_ActualPickup: //摘机命令执行完毕
  221. break;
  222. }
  223. if(pLine != NULL)
  224. pLine->procDevMsg(pEvent);
  225. }
  226. /*****************************************************************
  227. **【函数名称】 __eventCallBackProc
  228. **【函数功能】 回调函数
  229. **【参数】 wEvent:系统当前触发的事件,nReference:通道逻辑号,dwParam:事件输出参数dwUser:用户自定义参数
  230. **【返回值】
  231. ****************************************************************/
  232. int CALLBACK CDeviceMgr::__eventCallBackProc( PSSM_EVENT pEvent )
  233. {
  234. CDeviceMgr* pDevManager = (CDeviceMgr*)pEvent->dwUser;
  235. pDevManager->__callBackProc(pEvent);
  236. return 1;
  237. }
  238. /*****************************************************************
  239. **【函数名称】 getFreeDevFax
  240. **【函数功能】 获取一空闲传真资源
  241. **【参数】
  242. **【返回值】
  243. ****************************************************************/
  244. CDevFax* CDeviceMgr::getFreeDevFax( void )
  245. {
  246. static POSITION posFaxStatic = m_FaxList.GetHeadPosition();
  247. for(int i= 0; i< m_FaxList.GetCount(); i++)
  248. {
  249. CDevFax * pDevFax = m_FaxList.GetNext(posFaxStatic);
  250. if(posFaxStatic == NULL)
  251. posFaxStatic = m_FaxList.GetHeadPosition();
  252. if(!pDevFax->isBusy())
  253. return pDevFax;
  254. }
  255. return NULL;
  256. }
  257. /*****************************************************************
  258. **【函数名称】 getFaxByID
  259. **【函数功能】 通过传真资源ID获取传真资源对象
  260. **【参数】
  261. **【返回值】
  262. ****************************************************************/
  263. CDevFax* CDeviceMgr::getFaxByID( int DevID )
  264. {
  265. POSITION pos = m_FaxList.GetHeadPosition();
  266. while(pos != NULL)
  267. {
  268. CDevFax * pDevFax = m_FaxList.GetNext(pos);
  269. if(pDevFax->id() == DevID)
  270. return pDevFax;
  271. }
  272. return NULL;
  273. }
  274. /*****************************************************************
  275. **【函数名称】 getDevType
  276. **【函数功能】 获取设备类型
  277. **【参数】
  278. **【返回值】
  279. ****************************************************************/
  280. int CDeviceMgr::getDevType( void )
  281. {
  282. int type = 0;
  283. int Count = m_LineArray.GetCount();
  284. for (int i = 0; i < Count; ++i)
  285. {
  286. CLine* pLine = m_LineArray[i];
  287. ASSERT(pLine != NULL);
  288. if (pLine->type() == DEV_VS_TYPE_AUDIO) //包含有放音模块
  289. {
  290. type = type | PDU_DEV_TYPE_VS_PLAY;
  291. }
  292. if ((pLine->type() == DEV_VS_TYPE_RECANA) ||
  293. (pLine->type() == DEV_VS_TYPE_RECDIG)) //包含的是录音模块
  294. {
  295. type = type | PDU_DEV_TYPE_VS_REC;
  296. }
  297. }
  298. if(CIprControl::GetInstance().getIprrLineCount() > 0)
  299. type = type | PDU_DEV_TYPE_VS_REC;
  300. return type;
  301. }
  302. /*****************************************************************
  303. **【函数名称】 findLineByID
  304. **【函数功能】 根据通道逻辑号查找线路对象
  305. **【参数】 LineID:通道逻辑号
  306. **【返回值】 线路对象
  307. ****************************************************************/
  308. CLine* CDeviceMgr::findLineByID( int LineID )
  309. {
  310. int Count = m_LineArray.GetCount();
  311. for (int i = 0; i < Count; ++i)
  312. {
  313. CLine* pLine = m_LineArray[i];
  314. ASSERT(pLine != NULL);
  315. if (pLine->id() == LineID)
  316. return pLine;
  317. }
  318. return CIprControl::GetInstance().findLineByID(LineID);
  319. }
  320. /*****************************************************************
  321. **【函数名称】 initDev
  322. **【函数功能】 设备初始化
  323. **【参数】
  324. **【返回值】 初始化成功或失败
  325. ****************************************************************/
  326. bool CDeviceMgr::initDev( void )
  327. {
  328. //设置事件回调类型
  329. EVENT_SET_INFO EventSet;
  330. EventSet.dwWorkMode = EVENT_CALLBACKA;
  331. EventSet.lpHandlerParam = __eventCallBackProc;
  332. EventSet.dwUser = (DWORD)this;
  333. // 系统初始化
  334. int IsSsmStartCtiOK = SsmStartCtiEx(SH_SSM_CFG_FILE, SH_IDX_CFG_FILE, TRUE, &EventSet);
  335. if(IsSsmStartCtiOK != 0)
  336. {
  337. char szErrMsg[DEV_OP_BUF_LEN];
  338. SsmGetLastErrMsg(szErrMsg);
  339. AfxMessageBox(szErrMsg, MB_OK, 0);
  340. return false;
  341. }
  342. // 是否所有板卡都初始化成功
  343. if(SsmGetMaxUsableBoard() != SsmGetMaxCfgBoard())
  344. {
  345. char szErrMsg[DEV_OP_BUF_LEN];
  346. SsmGetLastErrMsg(szErrMsg);
  347. CString ErrContent;
  348. ErrContent.Format(_T("警告:板卡总数=%d, 初始化成功板卡数=%d!\n 错误信息=\"%s\""), SsmGetMaxCfgBoard(), SsmGetMaxUsableBoard(), szErrMsg);
  349. AfxMessageBox(szErrMsg, MB_OK, 0);
  350. SsmCloseCti();
  351. return false;
  352. }
  353. //初始化线路对象
  354. __initLineObject();
  355. CIprControl::GetInstance().init();
  356. //设置回调事件 初始化已由SsmStartCti改为SsmStartCtiEx,后者包含了事件输出的设定,故该函数调用暂被注释
  357. //if(SsmSetEvent(0xffff, -1, TRUE, &EventSet) == -1) //Designates event
  358. //{
  359. // char szErrMsg[DEV_OP_BUF_LEN];
  360. // SsmGetLastErrMsg(szErrMsg); //Get wrong message
  361. // AfxMessageBox(szErrMsg, MB_OK, 0);
  362. // closeDev();
  363. // return false;
  364. //}
  365. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{DevMgr}: 设备初始化成功"));
  366. return true;
  367. }
  368. /*****************************************************************
  369. **【函数名称】 closeDev
  370. **【函数功能】 关闭设备
  371. **【参数】
  372. **【返回值】
  373. ****************************************************************/
  374. void CDeviceMgr::closeDev( void )
  375. {
  376. CIprControl::GetInstance().release();
  377. if (SsmCloseCti() != 1)
  378. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 关闭设备时出错"));
  379. __release();
  380. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 设备关闭"));
  381. }
  382. /*****************************************************************
  383. **【函数名称】 procCmd
  384. **【函数功能】 处理网络命令
  385. **【参数】
  386. **【返回值】
  387. ****************************************************************/
  388. void CDeviceMgr::procCmd( CPduEntity* a_pPduEntity )
  389. {
  390. CLine* pLine = NULL;
  391. switch(a_pPduEntity->GetCmdType())
  392. {
  393. case PDU_CMD_IVR_PLAY_DTMF: // 放音收号
  394. {
  395. pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(3));
  396. if(pLine == NULL)
  397. {
  398. a_pPduEntity->SetToExecReturn();
  399. a_pPduEntity->SetDataBool(0, false);
  400. CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
  401. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到放音收号命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
  402. a_pPduEntity->GetDataUInt(3));
  403. }
  404. }
  405. break;
  406. case PDU_CMD_IVR_LEAVE_WORD: // 留言
  407. {
  408. pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(3));
  409. if(pLine == NULL)
  410. {
  411. a_pPduEntity->SetToExecReturn();
  412. a_pPduEntity->SetDataBool(0, false);
  413. CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
  414. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到留言命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
  415. a_pPduEntity->GetDataUInt(3));
  416. }
  417. }
  418. break;
  419. case PDU_CMD_IVR_FAX: // 传真
  420. {
  421. pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(3));
  422. if(pLine == NULL)
  423. {
  424. a_pPduEntity->SetToExecReturn();
  425. a_pPduEntity->SetDataBool(0, false);
  426. CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
  427. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到传真命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
  428. a_pPduEntity->GetDataUInt(3));
  429. }
  430. }
  431. break;
  432. case PDU_CMD_CTI_VS_RECORD: // 录音
  433. {
  434. pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(1));
  435. if(pLine == NULL)
  436. {
  437. a_pPduEntity->SetToExecReturn();
  438. a_pPduEntity->SetDataBool(0, false);
  439. CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
  440. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到录音命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
  441. a_pPduEntity->GetDataUInt(1));
  442. }
  443. }
  444. break;
  445. case PDU_CMD_CTI_VS_LINECONTROL:
  446. {
  447. pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(0));
  448. if(pLine == NULL)
  449. {
  450. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到线路控制命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
  451. a_pPduEntity->GetDataUInt(0));
  452. }
  453. }
  454. break;
  455. }
  456. if(pLine != NULL)
  457. pLine->procCmd(a_pPduEntity);
  458. }
  459. /*****************************************************************
  460. **【函数名称】 hangupAllLine
  461. **【函数功能】 对所有线路进行挂机操作
  462. **【参数】
  463. **【返回值】
  464. ****************************************************************/
  465. void CDeviceMgr::hangupAllLine( void )
  466. {
  467. int Count = m_LineArray.GetCount();
  468. for (int i = 0; i < Count; ++i)
  469. {
  470. CLine* pLine = m_LineArray[i];
  471. ASSERT(pLine != NULL);
  472. CPduEntity cmd(PDU_CMD_CTI_VS_LINECONTROL);
  473. cmd.SetDataInt(1, IVR_LINE_HANG_UP);
  474. pLine->procCmd(&cmd);
  475. }
  476. }