中航光电的中间件仓库

NetworkCti.cpp 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #include "StdAfx.h"
  2. #include "NetworkCti.h"
  3. #include "LineHolder.h"
  4. #include "IvrFlowHolder.h"
  5. #include "Logger.h"
  6. #include "MsgCenter.h"
  7. #include "Config.h"
  8. #include "CtiDataDef.h"
  9. #include "TaskMgr.h"
  10. SINGLETON_IMPLEMENT(CNetworkCti)
  11. CNetworkCti::CNetworkCti(void) : m_IsAcdConnected(FALSE), m_IsIvrConnected(FALSE)
  12. {
  13. }
  14. CNetworkCti::~CNetworkCti(void)
  15. {
  16. }
  17. /*****************************************************************
  18. **【函数名称】 __procRegMsg
  19. **【函数功能】 处理注册命令
  20. **【参数】 a_PduEntity:注册命令
  21. **【返回值】
  22. ****************************************************************/
  23. void CNetworkCti::__procRegMsg( CPduEntity& a_PduEntity )
  24. {
  25. bool RegResult = false;
  26. switch(a_PduEntity.GetLocalDevType())
  27. {
  28. case PDU_DEV_TYPE_ACD:
  29. RegResult = m_DevAcd.DevId == -1 ? true : false;
  30. break;
  31. case PDU_DEV_TYPE_IVR:
  32. RegResult = m_DevIvr.DevId == -1 ? true : false;
  33. break;
  34. default:
  35. ASSERT(FALSE);
  36. break;
  37. }
  38. // 发送注册结果
  39. a_PduEntity.SetToExecReturn();
  40. a_PduEntity.SetDataBool(0, RegResult);
  41. CInterfaceWindow::getIocpCommInstance()->Send(&a_PduEntity, a_PduEntity.GetLocalDevType(), a_PduEntity.GetLocalDevId());
  42. }
  43. /*****************************************************************
  44. **【函数名称】 __onRegSuccess
  45. **【函数功能】 设备注册成功处理函数
  46. **【参数】 linkContent:注册段信息
  47. **【返回值】
  48. ****************************************************************/
  49. void CNetworkCti::__onRegSuccess( const PduLinkContent& linkContent )
  50. {
  51. switch(linkContent.nFarType)
  52. {
  53. case PDU_DEV_TYPE_ACD:
  54. {
  55. // 保存设备信息
  56. m_DevAcd.DevId = linkContent.nLocalId;
  57. lstrcpy(m_DevAcd.szIpAddress, linkContent.szFarIp);
  58. m_DevAcd.Port = linkContent.nFarPort;
  59. m_IsAcdConnected = TRUE;
  60. // 通知线路类Acd连接成功
  61. CLineHolder::GetInstance().onAcdConnected();
  62. }
  63. break;
  64. case PDU_DEV_TYPE_IVR:
  65. {
  66. // 保存设备信息
  67. m_DevIvr.DevId = linkContent.nLocalId;
  68. lstrcpy(m_DevIvr.szIpAddress, linkContent.szFarIp);
  69. m_DevIvr.Port = linkContent.nFarPort;
  70. m_IsIvrConnected = TRUE;
  71. }
  72. break;
  73. default:
  74. ASSERT(FALSE);
  75. break;
  76. }
  77. }
  78. /*****************************************************************
  79. **【函数名称】 __onDisconnect
  80. **【函数功能】 设备连接断开处理函数
  81. **【参数】 linkContent:连接断开端信息
  82. **【返回值】
  83. ****************************************************************/
  84. void CNetworkCti::__onDisconnect( const PduLinkContent& linkContent )
  85. {
  86. switch(linkContent.nFarType)
  87. {
  88. case PDU_DEV_TYPE_ACD:
  89. {
  90. if(m_DevAcd.DevId != linkContent.nLocalId) return;
  91. if(strcmp(m_DevAcd.szIpAddress, linkContent.szFarIp) != 0) return;
  92. if(m_DevAcd.Port != linkContent.nFarPort) return;
  93. memset(&m_DevAcd, 0, sizeof(m_DevAcd));
  94. m_DevAcd.DevId = -1;
  95. m_IsAcdConnected = FALSE;
  96. }
  97. break;
  98. case PDU_DEV_TYPE_IVR:
  99. {
  100. if(m_DevIvr.DevId != linkContent.nLocalId) return;
  101. if(strcmp(m_DevIvr.szIpAddress, linkContent.szFarIp) != 0) return;
  102. if(m_DevIvr.Port != linkContent.nFarPort) return;
  103. memset(&m_DevIvr, 0, sizeof(m_DevIvr));
  104. m_DevIvr.DevId = -1;
  105. // 通知IvrFlow IVR连接断开
  106. CIvrFlowHolder::GetInstance().onIvrDisconnect();
  107. m_IsIvrConnected = FALSE;
  108. }
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114. /*****************************************************************
  115. **【函数名称】 OnLinkStateChanged
  116. **【函数功能】 连接状态信息变化
  117. **【参数】
  118. **【返回值】
  119. ****************************************************************/
  120. void CNetworkCti::OnLinkStateChanged( const PduLinkContent& linkContent )
  121. {
  122. // 连接信息日志显示
  123. LOG_LEVEL nLogLevel = LOG_LEVEL_WARNING;
  124. CString Msg;
  125. switch(linkContent.nLinkState)
  126. {
  127. case PDU_LINK_STATE_ACCEPTED:
  128. {
  129. Msg = _T("{Net}: Far End Accepted, ");
  130. nLogLevel = LOG_LEVEL_NORMAL;
  131. }
  132. break;
  133. case PDU_LINK_STATE_DISCONNECTED:
  134. {
  135. Msg = _T("{Net}: Far End Disconnected, ");
  136. nLogLevel = LOG_LEVEL_WARNING;
  137. __onDisconnect(linkContent);
  138. }
  139. break;
  140. case PDU_LINK_STATE_REG_OK:
  141. {
  142. Msg = _T("{Net}: Far End Reg OK, ");
  143. nLogLevel = LOG_LEVEL_NORMAL;
  144. __onRegSuccess(linkContent);
  145. }
  146. break;
  147. case PDU_LINK_STATE_REG_FAILED:
  148. {
  149. Msg = _T("{Net}: Far End Reg Failed, ");
  150. nLogLevel = LOG_LEVEL_WARNING;
  151. }
  152. break;
  153. default:
  154. {
  155. ASSERT(FALSE);
  156. Msg = _T("{Net}: Unknown Netlink State, ");
  157. nLogLevel = LOG_LEVEL_WARNING;
  158. }
  159. break;
  160. }
  161. // 判断设备类型
  162. switch(linkContent.nFarType)
  163. {
  164. case PDU_DEV_TYPE_ACD:
  165. {
  166. CString Temp;
  167. Temp.Format(_T(" Far End[Type = ACD, Id = %d, Addr = %s:%d]"), linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort);
  168. Msg += Temp;
  169. }
  170. break;
  171. case PDU_DEV_TYPE_IVR:
  172. {
  173. CString Temp;
  174. Temp.Format(_T(" Far End[Type = IVR, Id = %d, Addr = %s:%d]"), linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort);
  175. Msg += Temp;
  176. }
  177. break;
  178. default:
  179. CString Temp;
  180. Temp.Format(_T(" Far End[Type = UnKnown, Id = %d, Addr = %s:%d]"), linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort);
  181. Msg += Temp;
  182. break;
  183. }
  184. // 通知日志
  185. ILogger::getInstance().log(LOG_CLASS_SOCKET, nLogLevel, _T("%s"), Msg);
  186. }
  187. /*****************************************************************
  188. **【函数名称】 OnRecvCommand
  189. **【函数功能】 Pdu命令处理接口
  190. **【参数】 a_pPduEntity:消息实体
  191. **【返回值】
  192. ****************************************************************/
  193. void CNetworkCti::OnRecvCommand( CPduEntity* a_pPduEntity )
  194. {
  195. ASSERT(a_pPduEntity != NULL);
  196. switch(a_pPduEntity->GetCmdType())
  197. {
  198. case PDU_CMD_REG: // 注册命令
  199. __procRegMsg(*a_pPduEntity);
  200. break;
  201. case PDU_CMD_CTI_IVR_CALLIN: // CallIn返回命令
  202. case PDU_CMD_CTI_IVR_TURNIVR: // 转IVR返回命令
  203. case PDU_CMD_IVR_HANGUP: // IVR通知CTI挂机
  204. case PDU_CMD_IVR_END: // IVR通知CTI流程结束
  205. case PDU_CMD_IVR_WANT_AGENT: // IVR通知CTI请求排队(包括ACD返回)
  206. case PDU_CMD_IVR_QUEUE_CONTINUE: // IVR通知CTI继续排队(包括ACD返回)
  207. case PDU_CMD_IVR_QUEUE_CANCEL: // IVR通知CTI取消排队
  208. case PDU_CMD_IVR_TURN_AGENT: // IVR通知CTI转坐席
  209. case PDU_CMD_IVR_PLAY_DTMF: // IVR通知CTI放音收按键
  210. case PDU_CMD_IVR_CALL_OUT: // IVR通知CTI自动呼叫某个号码
  211. case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移
  212. case PDU_CMD_IVR_FAX: // IVR通知收发传真
  213. case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言
  214. CIvrFlowHolder::GetInstance().onPduMessage(*a_pPduEntity);
  215. break;
  216. case PDU_CMD_LISTEN:
  217. return;
  218. case PDU_CMD_IVR_WAITER_COUNT: //2019 - 9 - 6 配合4.0acd返回排队人数
  219. {
  220. send2ACD(*a_pPduEntity); //发送至ACD
  221. int WaiterCount = a_pPduEntity->GetDataUInt(0);
  222. // m_WaiterCount.onWaiterCount(WaiterCount);
  223. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{NetWorkCti}:收到排队数量%d",WaiterCount);
  224. }
  225. break;
  226. default:
  227. {
  228. __try {
  229. CTaskMgr::GetInstance().onPduMessage(*a_pPduEntity);
  230. }
  231. __except (EXCEPTION_EXECUTE_HANDLER)
  232. {
  233. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{CNetworkCti}:OnRecvCommand,CTaskMgr异常,CmdType=%d,mdw5.1.19.1"), a_pPduEntity->GetCmdType());
  234. }
  235. break;
  236. }
  237. break;
  238. }
  239. }
  240. /*****************************************************************
  241. **【函数名称】 init
  242. **【函数功能】 初始化
  243. **【参数】
  244. **【返回值】 成功TRUE,失败FALSE
  245. ****************************************************************/
  246. BOOL CNetworkCti::init()
  247. {
  248. // 初始化客户端设备信息
  249. memset(&m_DevAcd, 0, sizeof(m_DevAcd));
  250. memset(&m_DevIvr, 0, sizeof(m_DevIvr));
  251. m_DevAcd.DevId = -1;
  252. m_DevIvr.DevId = -1;
  253. // 初始化命令配置
  254. CPduDataFormat::getInstance()->UnLoad();
  255. #ifdef _DEBUG
  256. CPduDataFormat::getInstance()->Load("../NetLib/PDUFormat.ini"); //../NetLib/PDUFormat.ini
  257. #else
  258. CPduDataFormat::getInstance()->Load("./PDUFormat.ini");
  259. #endif
  260. CInterfaceWindow::getIocpLinkInstance()->RegistPduLinkProc(this, FALSE);
  261. CInterfaceWindow::getIocpCommInstance()->RegistPduCommProc(this, FALSE);
  262. // 注册Pdu消息接口
  263. CInterfaceWindow::getIocpLinkInstance()->RegistPduLinkProc(this, TRUE);
  264. CInterfaceWindow::getIocpCommInstance()->RegistPduCommProc(this, TRUE);
  265. //创建Socket服务器端
  266. UINT ListenPort = CConfig::GetInstance().listenPort();
  267. if (CInterfaceWindow::getIocpLinkInstance()->CreatePduServer(ListenPort, PDU_DEV_TYPE_CTI, 0))
  268. {
  269. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{Net}: 创建网络服务端成功,ListenPort = %d", ListenPort);
  270. return TRUE;
  271. }
  272. else
  273. {
  274. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "{Net}: 创建网络服务端失败,ListenPort = %d", ListenPort);
  275. return FALSE;
  276. }
  277. }
  278. /*****************************************************************
  279. **【函数名称】 release
  280. **【函数功能】 释放资源
  281. **【参数】
  282. **【返回值】 成功TRUE,失败FALSE
  283. ****************************************************************/
  284. void CNetworkCti::release( void )
  285. {
  286. CInterfaceWindow::getIocpLinkInstance()->StopAll();
  287. }
  288. /*****************************************************************
  289. **【函数名称】 send2ACD
  290. **【函数功能】 发送PDU到ACD
  291. **【参数】 a_PduEntity:待发送的PDU
  292. **【返回值】
  293. ****************************************************************/
  294. BOOL CNetworkCti::send2ACD( CPduEntity& a_PduEntity )
  295. {
  296. return CInterfaceWindow::getIocpCommInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_ACD, m_DevAcd.DevId);
  297. }
  298. /*****************************************************************
  299. **【函数名称】 send2IVR
  300. **【函数功能】 发送PDU到IVR
  301. **【参数】 a_PduEntity:待发送的PDU
  302. **【返回值】
  303. ****************************************************************/
  304. BOOL CNetworkCti::send2IVR( CPduEntity& a_PduEntity )
  305. {
  306. return CInterfaceWindow::getIocpCommInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_IVR, m_DevIvr.DevId);
  307. }