中间件底层,websocket

IvrFlowHolder.cpp 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "StdAfx.h"
  2. #include "IvrFlowHolder.h"
  3. #include "IvrFlow.h"
  4. #include "CtiCore.h"
  5. #include "TaskMgr.h"
  6. #include "Inc/CallDetailInc.h"
  7. #include "StatisticsMgr.h"
  8. #include "NetworkCti.h"
  9. #include "LogicLine.h"
  10. #include "LineHolder.h"
  11. SINGLETON_IMPLEMENT(CIvrFlowHolder)
  12. CIvrFlowHolder::CIvrFlowHolder(void)
  13. {
  14. }
  15. CIvrFlowHolder::~CIvrFlowHolder(void)
  16. {
  17. }
  18. /*****************************************************************
  19. **【函数名称】 __procCallInReturn
  20. **【函数功能】 处理CallIn命令返回
  21. **【参数】 PduEntity:消息实体
  22. **【返回值】
  23. ****************************************************************/
  24. void CIvrFlowHolder::__procCallInReturn( CPduEntity &PduEntity )
  25. {
  26. // 显示日志
  27. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("IVR->CTI, CMD = return[CallIn], \
  28. IVR = %d, Line = %d, CallerNum = %s, CalleeNum = %s, IsSuccess = %d"),
  29. PduEntity.GetDataInt(1),
  30. PduEntity.GetDataUInt(5),
  31. PduEntity.GetDataString(3),
  32. PduEntity.GetDataString(4),
  33. PduEntity.GetDataBool(0));
  34. // 转发给IvrFlow
  35. __transmitToIvrFlow(PduEntity);
  36. }
  37. /*****************************************************************
  38. **【函数名称】 __procTurnIvrReturn
  39. **【函数功能】 处理转Ivr命令返回
  40. **【参数】 PduEntity: 消息实体
  41. **【返回值】
  42. ****************************************************************/
  43. void CIvrFlowHolder::__procTurnIvrReturn( CPduEntity &PduEntity )
  44. {
  45. // 显示日志
  46. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("IVR->CTI, Cmd = return[TurnIVR], \
  47. IVR = %d, Line = %d, CallerNum = %s, CalleeNum = %s, IsSuccess = %d"),
  48. PduEntity.GetDataInt(1),
  49. PduEntity.GetDataUInt(5),
  50. PduEntity.GetDataString(3),
  51. PduEntity.GetDataString(4),
  52. PduEntity.GetDataBool(0));
  53. // 如果IVR不存在,通知Task转IVR失败
  54. if(PduEntity.GetDataInt(1) == -1)
  55. CTaskMgr::GetInstance().onTaskPduMsg(PduEntity.GetDataUInt(5), PduEntity);
  56. else
  57. __transmitToIvrFlow(PduEntity);
  58. }
  59. /*****************************************************************
  60. **【函数名称】 __transmitToIvrFlow
  61. **【函数功能】 命令转发给IvrFlow
  62. **【参数】 PduEntity: 消息实体
  63. **【返回值】
  64. ****************************************************************/
  65. void CIvrFlowHolder::__transmitToIvrFlow( CPduEntity &PduEntity )
  66. {
  67. // 根据IvrId获取Ivr对象
  68. CIvrFlow *pIvrFlow = getFlowByIvrId(PduEntity.GetDataInt(1));
  69. if(pIvrFlow == NULL)
  70. {
  71. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{IvrFlowHolder}: 向IVR转发命令时定位不到IvrFlow,IVR = %d"), PduEntity.GetDataInt(1));
  72. if (PDU_CMD_CTI_IVR_CALLIN == PduEntity.GetCmdType()) // 通知IVR外线来电消息返回,注:只有该类型添加的第二个字段数据其值为CallID
  73. {
  74. // 统计找不到IVR流程资源造成的呼入失败记录
  75. T_EvtError repInfo;
  76. memset(&repInfo, 0, sizeof(repInfo));
  77. repInfo.nErrorType = REP_ERROR_IVRFLOW;
  78. CStatisticsMgr::GetInstance().onCallDetail(PduEntity.GetDataULong(2), REP_EVENT_ERROR, PduEntity.GetDataUInt(5), &repInfo);
  79. }
  80. // 命令返回失败
  81. if(PduEntity.GetIsExecReturn()) return;
  82. PduEntity.SetToExecReturn();
  83. PduEntity.SetDataBool(0, false);
  84. CNetworkCti::GetInstance().send2IVR(PduEntity);
  85. }
  86. else
  87. {
  88. PDU_CMD_TYPE CmdType = PduEntity.GetCmdType();
  89. if (PDU_CMD_IVR_WANT_AGENT == CmdType)
  90. {
  91. // 在处理ACD相关消息时,添加判断是否与ACD正常连接,若没有正常连接则与ACD相关的操作数据记录为呼损数据。
  92. if (!CNetworkCti::GetInstance().isACDConnected())
  93. {
  94. // 显示日志
  95. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("{IvrFlowHolder}: 执行来电排队操作失败,ACD未连接到系统,或ACD未启动!"));
  96. // 统计ACD未启动造成呼入失败记录
  97. T_EvtError repInfo;
  98. memset(&repInfo, 0, sizeof(repInfo));
  99. repInfo.nErrorType = REP_ERROR_ACD;
  100. CStatisticsMgr::GetInstance().onCallDetail(PduEntity.GetDataULong(2), REP_EVENT_ERROR, PduEntity.GetDataInt(5), &repInfo);
  101. }
  102. }
  103. pIvrFlow->onPduMessage(PduEntity);
  104. }
  105. }
  106. /*****************************************************************
  107. **【函数名称】 __procDevOpCallIn
  108. **【函数功能】 处理底层设备外线呼入
  109. **【参数】 DevOpInfo: 底层操作数据
  110. **【返回值】
  111. ****************************************************************/
  112. void CIvrFlowHolder::__procDevOpCallIn( EventDevOperation &DevOpInfo )
  113. {
  114. T_EvtError repInfo;
  115. memset(&repInfo, 0, sizeof(repInfo));
  116. // 获取线路类指针
  117. CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(DevOpInfo.nLineId);
  118. if(pLogicLine == NULL) return;
  119. if(pLogicLine->type() != DEV_RES_TYPE_TRUNK && pLogicLine->type() != DEV_RES_TYPE_VOIP)
  120. {
  121. repInfo.nErrorType = REP_ERROR_SYSTEM;
  122. CStatisticsMgr::GetInstance().onCallDetail(pLogicLine->callId(), REP_EVENT_ERROR, DevOpInfo.nLineId, &repInfo);
  123. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING,_T("{IvrFlowHolder}: 外线呼入通知IVR时检测到线路类型非外线, Line Id = %u, type = %u"),
  124. pLogicLine->lineId(), pLogicLine->type());
  125. }
  126. // 判断IVR是否断开连接,如果断开连接则作为外线呼入失败记录
  127. if (!CNetworkCti::GetInstance().isIVRConnected())
  128. {
  129. // 显示日志
  130. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("{IvrFlowHolder}: 外线呼入通知IVR失败,IVR未连接到系统,或IVR未启动"));
  131. // 统计IVR未启动造成呼入失败记录
  132. repInfo.nErrorType = REP_ERROR_IVR;
  133. CStatisticsMgr::GetInstance().onCallDetail(pLogicLine->callId(), REP_EVENT_ERROR, DevOpInfo.nLineId, &repInfo);
  134. }
  135. else
  136. {
  137. // 通知IVR程序外线来电
  138. CPduEntity CmdCallIn(PDU_CMD_CTI_IVR_CALLIN);
  139. CmdCallIn.SetDataULong(2, pLogicLine->callId());
  140. CmdCallIn.SetDataString(3, DevOpInfo.szCallerNum);
  141. CmdCallIn.SetDataString(4, DevOpInfo.szCalleeNum);
  142. CmdCallIn.SetDataUInt(5, DevOpInfo.nLineId);
  143. CmdCallIn.SetDataString(6, pLogicLine->UUID());
  144. CNetworkCti::GetInstance().send2IVR(CmdCallIn);
  145. }
  146. }
  147. /*****************************************************************
  148. **【函数名称】 createIvrFlow
  149. **【函数功能】 创建IvrFlow
  150. **【参数】
  151. **【返回值】
  152. ****************************************************************/
  153. void CIvrFlowHolder::createIvrFlow( int IvrFlowNum )
  154. {
  155. for(int i = 0; i < IvrFlowNum; i++)
  156. {
  157. CIvrFlow *pIvrFlow = new(std::nothrow) CIvrFlow(i);
  158. m_IvrFlowMap.SetAt(i, pIvrFlow);
  159. }
  160. }
  161. /*****************************************************************
  162. **【函数名称】 destroyIvrFlow
  163. **【函数功能】 销毁IvrFlow
  164. **【参数】
  165. **【返回值】
  166. ****************************************************************/
  167. void CIvrFlowHolder::destroyIvrFlow( void )
  168. {
  169. UINT Key = 0;
  170. CIvrFlow *pIvrFlow = NULL;
  171. POSITION pos = m_IvrFlowMap.GetStartPosition();
  172. while (pos != NULL)
  173. {
  174. m_IvrFlowMap.GetNextAssoc(pos, Key, pIvrFlow);
  175. if (pIvrFlow != NULL)
  176. {
  177. delete pIvrFlow;
  178. pIvrFlow = NULL;
  179. }
  180. } // end while
  181. m_IvrFlowMap.RemoveAll();
  182. }
  183. /*****************************************************************
  184. **【函数名称】 onPduMessage
  185. **【函数功能】 Pdu命令处理接口
  186. **【参数】 PduEntity:消息实体
  187. **【返回值】
  188. ***************************************************************/
  189. void CIvrFlowHolder::onPduMessage( CPduEntity &PduEntity )
  190. {
  191. switch(PduEntity.GetCmdType())
  192. {
  193. case PDU_CMD_CTI_IVR_CALLIN: // CallIn命令返回
  194. __procCallInReturn(PduEntity);
  195. break;
  196. case PDU_CMD_CTI_IVR_TURNIVR: // 转Ivr命令
  197. __procTurnIvrReturn(PduEntity);
  198. break;
  199. default: // 命令转发给IvrFlow
  200. __transmitToIvrFlow(PduEntity);
  201. break;
  202. }
  203. }
  204. /*****************************************************************
  205. **【函数名称】 onDevMessage
  206. **【函数功能】 底层设备事件
  207. **【参数】 EvtType 消息事件类型
  208. lpContent 消息内容
  209. **【返回值】
  210. ****************************************************************/
  211. void CIvrFlowHolder::onDevMessage( EventDevOperation &DevOpInfo )
  212. {
  213. switch(DevOpInfo.nOpType)
  214. {
  215. case DEV_OP_CALL_IN:
  216. __procDevOpCallIn(DevOpInfo);
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. /*****************************************************************
  223. **【函数名称】 onIvrDisconnect
  224. **【函数功能】 处理Ivr连接断开
  225. **【参数】
  226. **【返回值】
  227. ****************************************************************/
  228. void CIvrFlowHolder::onIvrDisconnect(void)
  229. {
  230. UINT nIndex;
  231. CIvrFlow *pIvrFlow = NULL;
  232. POSITION pos = m_IvrFlowMap.GetStartPosition();
  233. // 循环遍历结束所有Ivrflow
  234. while(pos != NULL)
  235. {
  236. m_IvrFlowMap.GetNextAssoc(pos, nIndex, pIvrFlow);
  237. if(pIvrFlow == NULL) continue;
  238. // 向关联线路发送挂机命令
  239. if(pIvrFlow->assoLineId() != -1)
  240. CCtiCore::GetInstance().getDevLink().exec(-1, LINE_OP_HANG_UP, pIvrFlow->assoLineId(), NULL);
  241. // Ivrflow重置
  242. pIvrFlow->resetFlow();
  243. }
  244. }
  245. /*****************************************************************
  246. **【函数名称】 getFlowByIvrId
  247. **【函数功能】 通过IvrId获取关联的IVR流程
  248. **【参数】 IvrId: IVR ID
  249. **【返回值】 CIvrFlow对象
  250. ****************************************************************/
  251. CIvrFlow* CIvrFlowHolder::getFlowByIvrId( int IvrId )
  252. {
  253. CIvrFlow *pIvrFlow = NULL;
  254. m_IvrFlowMap.Lookup(IvrId, pIvrFlow);
  255. return pIvrFlow;
  256. }
  257. /*****************************************************************
  258. **【函数名称】 getFlowByLineId
  259. **【函数功能】 通过线路号获取关联的IVR流程
  260. **【参数】 LineId: 线路号
  261. **【返回值】 CIvrFlow对象
  262. ****************************************************************/
  263. CIvrFlow* CIvrFlowHolder::getFlowByLineId( int LineId )
  264. {
  265. UINT nIndex;
  266. CIvrFlow *pIvrFlow = NULL;
  267. POSITION pos = m_IvrFlowMap.GetStartPosition();
  268. while(pos != NULL)
  269. {
  270. m_IvrFlowMap.GetNextAssoc(pos, nIndex, pIvrFlow);
  271. if(pIvrFlow != NULL && pIvrFlow->assoLineId() == LineId)
  272. return pIvrFlow;
  273. }
  274. return NULL;
  275. }