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

IvrFlowHolder.cpp 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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. CNetworkCti::GetInstance().send2IVR(CmdCallIn);
  144. }
  145. }
  146. /*****************************************************************
  147. **【函数名称】 createIvrFlow
  148. **【函数功能】 创建IvrFlow
  149. **【参数】
  150. **【返回值】
  151. ****************************************************************/
  152. void CIvrFlowHolder::createIvrFlow( int IvrFlowNum )
  153. {
  154. for(int i = 0; i < IvrFlowNum; i++)
  155. {
  156. CIvrFlow *pIvrFlow = new CIvrFlow(i);
  157. m_IvrFlowMap.SetAt(i, pIvrFlow);
  158. }
  159. }
  160. /*****************************************************************
  161. **【函数名称】 destroyIvrFlow
  162. **【函数功能】 销毁IvrFlow
  163. **【参数】
  164. **【返回值】
  165. ****************************************************************/
  166. void CIvrFlowHolder::destroyIvrFlow( void )
  167. {
  168. UINT Key = 0;
  169. CIvrFlow *pIvrFlow = NULL;
  170. POSITION pos = m_IvrFlowMap.GetStartPosition();
  171. while (pos != NULL)
  172. {
  173. m_IvrFlowMap.GetNextAssoc(pos, Key, pIvrFlow);
  174. if (pIvrFlow != NULL)
  175. {
  176. delete pIvrFlow;
  177. pIvrFlow = NULL;
  178. }
  179. } // end while
  180. m_IvrFlowMap.RemoveAll();
  181. }
  182. /*****************************************************************
  183. **【函数名称】 onPduMessage
  184. **【函数功能】 Pdu命令处理接口
  185. **【参数】 PduEntity:消息实体
  186. **【返回值】
  187. ***************************************************************/
  188. void CIvrFlowHolder::onPduMessage( CPduEntity &PduEntity )
  189. {
  190. switch(PduEntity.GetCmdType())
  191. {
  192. case PDU_CMD_CTI_IVR_CALLIN: // CallIn命令返回
  193. __procCallInReturn(PduEntity);
  194. break;
  195. case PDU_CMD_CTI_IVR_TURNIVR: // 转Ivr命令
  196. __procTurnIvrReturn(PduEntity);
  197. break;
  198. default: // 命令转发给IvrFlow
  199. __transmitToIvrFlow(PduEntity);
  200. break;
  201. }
  202. }
  203. /*****************************************************************
  204. **【函数名称】 onDevMessage
  205. **【函数功能】 底层设备事件
  206. **【参数】 EvtType 消息事件类型
  207. lpContent 消息内容
  208. **【返回值】
  209. ****************************************************************/
  210. void CIvrFlowHolder::onDevMessage( EventDevOperation &DevOpInfo )
  211. {
  212. switch(DevOpInfo.nOpType)
  213. {
  214. case DEV_OP_CALL_IN:
  215. __procDevOpCallIn(DevOpInfo);
  216. break;
  217. default:
  218. break;
  219. }
  220. }
  221. /*****************************************************************
  222. **【函数名称】 onIvrDisconnect
  223. **【函数功能】 处理Ivr连接断开
  224. **【参数】
  225. **【返回值】
  226. ****************************************************************/
  227. void CIvrFlowHolder::onIvrDisconnect(void)
  228. {
  229. UINT nIndex;
  230. CIvrFlow *pIvrFlow = NULL;
  231. POSITION pos = m_IvrFlowMap.GetStartPosition();
  232. // 循环遍历结束所有Ivrflow
  233. while(pos != NULL)
  234. {
  235. m_IvrFlowMap.GetNextAssoc(pos, nIndex, pIvrFlow);
  236. if(pIvrFlow == NULL) continue;
  237. // 向关联线路发送挂机命令
  238. if(pIvrFlow->assoLineId() != -1)
  239. CCtiCore::GetInstance().getDevLink().exec(-1, LINE_OP_HANG_UP, pIvrFlow->assoLineId(), NULL);
  240. // Ivrflow重置
  241. pIvrFlow->resetFlow();
  242. }
  243. }
  244. /*****************************************************************
  245. **【函数名称】 getFlowByIvrId
  246. **【函数功能】 通过IvrId获取关联的IVR流程
  247. **【参数】 IvrId: IVR ID
  248. **【返回值】 CIvrFlow对象
  249. ****************************************************************/
  250. CIvrFlow* CIvrFlowHolder::getFlowByIvrId( int IvrId )
  251. {
  252. CIvrFlow *pIvrFlow = NULL;
  253. m_IvrFlowMap.Lookup(IvrId, pIvrFlow);
  254. return pIvrFlow;
  255. }
  256. /*****************************************************************
  257. **【函数名称】 getFlowByLineId
  258. **【函数功能】 通过线路号获取关联的IVR流程
  259. **【参数】 LineId: 线路号
  260. **【返回值】 CIvrFlow对象
  261. ****************************************************************/
  262. CIvrFlow* CIvrFlowHolder::getFlowByLineId( int LineId )
  263. {
  264. UINT nIndex;
  265. CIvrFlow *pIvrFlow = NULL;
  266. POSITION pos = m_IvrFlowMap.GetStartPosition();
  267. while(pos != NULL)
  268. {
  269. m_IvrFlowMap.GetNextAssoc(pos, nIndex, pIvrFlow);
  270. if(pIvrFlow != NULL && pIvrFlow->assoLineId() == LineId)
  271. return pIvrFlow;
  272. }
  273. return NULL;
  274. }