中间件底层,websocket

LineHolder.cpp 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "StdAfx.h"
  2. #include "LineHolder.h"
  3. #include "LogicLineExt.h"
  4. #include "LogicLineTrunk.h"
  5. #include "LogicLineVoip.h"
  6. #include "MsgCenter.h"
  7. #include "NetworkCti.h"
  8. #include <set>
  9. SINGLETON_IMPLEMENT(CLineHolder)
  10. CLineHolder::CLineHolder(void)
  11. {
  12. m_LineMap.InitHashTable(MAX_LENGTH_HASH);
  13. }
  14. CLineHolder::~CLineHolder(void)
  15. {
  16. }
  17. /*****************************************************************
  18. **【函数名称】 __deleteExten
  19. **【函数功能】 删除指定分机
  20. **【参数】
  21. **【返回值】
  22. ****************************************************************/
  23. void CLineHolder::__deleteExten( UINT ExtId )
  24. {
  25. CLogicLine* pLine = NULL;
  26. // 不存在
  27. if(!m_LineMap.Lookup(ExtId, pLine))
  28. return;
  29. // 删除IP分机类
  30. m_LineMap.RemoveKey(ExtId);
  31. delete pLine;
  32. pLine = NULL;
  33. }
  34. /*****************************************************************
  35. **【函数名称】 __procResDetail
  36. **【函数功能】 处理资源类型明细,创建相关线路实体类
  37. **【参数】 EvtInfo: 资源信息
  38. **【返回值】
  39. ****************************************************************/
  40. void CLineHolder::__procResDetail( const EventResDetail &EvtInfo )
  41. {
  42. CLogicLine* pLine = NULL;
  43. switch(EvtInfo.nResType)
  44. {
  45. case DEV_RES_TYPE_EXT: // 内线分机
  46. {
  47. UINT Ext = EvtInfo.nResID;
  48. if (Ext & DEL_EXT_DETAIL) // 删除分机
  49. {
  50. // 去掉首位
  51. Ext = Ext << 4;
  52. Ext = Ext >> 4;
  53. __deleteExten(Ext);
  54. }
  55. else
  56. {
  57. // 已存在
  58. if(m_LineMap.Lookup(EvtInfo.nResID, pLine))
  59. return;
  60. // 建立内线分机类
  61. pLine = new(std::nothrow) CLogicLineExt(EvtInfo.nResID);
  62. m_LineMap.SetAt(EvtInfo.nResID, pLine);
  63. }
  64. }
  65. break;
  66. case DEV_RES_TYPE_TRUNK: // 外线
  67. {
  68. if(m_LineMap.Lookup(EvtInfo.nResID, pLine))
  69. return;
  70. // 建立外线类
  71. pLine = new(std::nothrow) CLogicLineTrunk(EvtInfo.nResID);
  72. m_LineMap.SetAt(EvtInfo.nResID, pLine);
  73. }
  74. break;
  75. case DEV_RES_TYPE_VOIP: // VOIP线路
  76. {
  77. if(m_LineMap.Lookup(EvtInfo.nResID, pLine))
  78. return;
  79. // 建立外线类
  80. pLine = new(std::nothrow) CLogicLineVoip(EvtInfo.nResID);
  81. m_LineMap.SetAt(EvtInfo.nResID, pLine);
  82. }
  83. break;
  84. default:
  85. break;
  86. } // end switch
  87. if(pLine != NULL)
  88. pLine->pushLineData2ACD();
  89. }
  90. /*****************************************************************
  91. **【函数名称】 __procResStatus
  92. **【函数功能】 处理资源状态变化
  93. **【参数】 EvtInfo:资源状态信息
  94. **【返回值】
  95. ****************************************************************/
  96. void CLineHolder::__procResStatus( const EventResStatus &EvtInfo )
  97. {
  98. CLogicLine* pLine = NULL;
  99. if(!m_LineMap.Lookup(EvtInfo.nResID, pLine))
  100. return;
  101. ASSERT(pLine != NULL);
  102. if(pLine == NULL)
  103. return;
  104. // 计算呼入数量,空闲->通话中,说明是中继呼入
  105. static int trunkCallIn = 0; // 中继呼入数量
  106. static std::set<UINT> trunkCallInResID; // 保存中继呼入的资源id
  107. if (EvtInfo.nResType == DEV_RES_TYPE_TRUNK)
  108. {
  109. if (EvtInfo.nState == TRUNK_STATE_ALERTING) // 来电振铃,中继呼入
  110. {
  111. trunkCallInResID.emplace(EvtInfo.nResID);
  112. }
  113. else if (EvtInfo.nState == TRUNK_STATE_FREE) // 变空闲,中继释放
  114. {
  115. auto it = trunkCallInResID.find(EvtInfo.nResID);
  116. if (it != trunkCallInResID.end())
  117. trunkCallInResID.erase(it);
  118. }
  119. }
  120. trunkCallIn = trunkCallInResID.size();
  121. //外呼数量计算
  122. static int makeCallCount = 0; // 外呼数量
  123. static std::set<UINT> extCallResID;
  124. static int extRingCount = 0; // 来电振铃数量
  125. static std::set<UINT> extRingResID; // 振铃数量
  126. if (EvtInfo.nResType == DEV_RES_TYPE_EXT)
  127. {
  128. if (EvtInfo.nState == INNER_STATE_RING_BACK || EvtInfo.nState == INNER_STATE_INIT || EvtInfo.nState == INNER_STATE_DIALING) // 外呼
  129. {
  130. extCallResID.emplace(EvtInfo.nResID);
  131. }
  132. else if (EvtInfo.nState == INNER_STATE_FREE || EvtInfo.nState == INNER_STATE_REMOVE)
  133. {
  134. auto it = extCallResID.find(EvtInfo.nResID);
  135. if (it != extCallResID.end())
  136. extCallResID.erase(it);
  137. }
  138. // 来电振铃
  139. if (EvtInfo.nState == INNER_STATE_ALERTING)
  140. {
  141. extRingResID.emplace(EvtInfo.nResID);
  142. }
  143. else
  144. {
  145. auto it = extRingResID.find(EvtInfo.nResID);
  146. if (it != extRingResID.end())
  147. extRingResID.erase(it);
  148. }
  149. }
  150. makeCallCount = extCallResID.size();
  151. extRingCount = extRingResID.size();
  152. // 发给相关线路类处理
  153. pLine->onLineStatusUpdated(EvtInfo);
  154. if(EvtInfo.nState == INNER_STATE_REMOVE)
  155. __deleteExten(EvtInfo.nResID);
  156. __procTrunkNum(trunkCallIn, makeCallCount, extRingCount);
  157. }
  158. void CLineHolder::__procTrunkNum(int trunkCallIn,int makeCallCount,int extRingCount)
  159. {
  160. UINT key = 0;
  161. CLogicLine* value = NULL;
  162. int CurrTrunkUseNum = 0;
  163. POSITION pos = m_LineMap.GetStartPosition();
  164. while (pos)
  165. {
  166. m_LineMap.GetNextAssoc(pos, key, value);
  167. if (value->type() == DEV_RES_TYPE_TRUNK)
  168. {
  169. if (value->status() == TRUNK_STATE_TALKING)
  170. {
  171. CurrTrunkUseNum += 1;
  172. }
  173. }
  174. }
  175. static int m_CurrTrunkUseNum = 0;
  176. //if (CurrTrunkUseNum == m_CurrTrunkUseNum) return;
  177. m_CurrTrunkUseNum = CurrTrunkUseNum;
  178. CPduEntity pdu(PDU_CMD_CTI_TRUNKUSE_COUNT);
  179. pdu.SetDataUInt(0, CurrTrunkUseNum);
  180. pdu.SetDataUInt(1, trunkCallIn);
  181. pdu.SetDataUInt(2, makeCallCount);
  182. pdu.SetDataUInt(3, extRingCount);
  183. CNetworkCti::GetInstance().send2ACD(pdu);
  184. }
  185. /*****************************************************************
  186. **【函数名称】 onAcdConnected
  187. **【函数功能】 ACD连接成功后的处理
  188. **【参数】
  189. **【返回值】
  190. ****************************************************************/
  191. void CLineHolder::onAcdConnected(void)
  192. {
  193. CLogicLine* pLogicLine = NULL;
  194. POSITION pos = m_LineMap.GetStartPosition();
  195. while(pos != NULL)
  196. {
  197. UINT nKey;
  198. m_LineMap.GetNextAssoc(pos, nKey, pLogicLine);
  199. // 发送线路初始信息到ACD
  200. pLogicLine->pushLineData2ACD();
  201. } // end while
  202. }
  203. /*****************************************************************
  204. **【函数名称】 getLogicLine
  205. **【函数功能】 获取逻辑线路实体类指针
  206. **【参数】 LineId: 线路ID
  207. **【返回值】
  208. ****************************************************************/
  209. CLogicLine* CLineHolder::getLogicLine( UINT LineId )
  210. {
  211. CLogicLine* pLogicLine = NULL;
  212. m_LineMap.Lookup(LineId, pLogicLine);
  213. return pLogicLine;
  214. }
  215. /*****************************************************************
  216. **【函数名称】 getLineAssoAgentId
  217. **【函数功能】 读取内线关联的座席工号
  218. **【参数】 nLineId: 线路ID
  219. **【返回值】 座席工号
  220. ****************************************************************/
  221. UINT CLineHolder::getLineAssoAgentId( UINT nLineId )
  222. {
  223. CLogicLine* pLine = getLogicLine(nLineId);
  224. return pLine == NULL ? 0 : pLine->getAgentNum();
  225. }
  226. /*****************************************************************
  227. **【函数名称】 onMessage
  228. **【函数功能】 消息事件处理函数
  229. **【参数】 MsgType: 消息事件类型
  230. lpContent: 消息内容
  231. **【返回值】
  232. ****************************************************************/
  233. void CLineHolder::onMessage( UINT MsgType, const PARAM lpContent )
  234. {
  235. if(lpContent == NULL) return;
  236. switch(MsgType)
  237. {
  238. case DEV_EVENT_RES_DETAIL: // 设备资源明显
  239. {
  240. __procResDetail(*(EventResDetail*)lpContent);
  241. }
  242. break;
  243. case DEV_EVENT_RES_STATUS: // 设备资源状态
  244. {
  245. __procResStatus(*(EventResStatus*)lpContent);
  246. }
  247. break;
  248. default:
  249. break;
  250. }
  251. }
  252. /*****************************************************************
  253. **【函数名称】 init
  254. **【函数功能】 初始化
  255. **【参数】
  256. **【返回值】
  257. ****************************************************************/
  258. void CLineHolder::init(void)
  259. {
  260. // 注册底层设备消息
  261. CMsgCenter& MsgCenter = CMsgCenter::GetInstance();
  262. MsgCenter.regist(DEV_EVENT_RES_DETAIL, this);
  263. MsgCenter.regist(DEV_EVENT_RES_STATUS, this);
  264. }
  265. void CLineHolder::uninit(void)
  266. {
  267. // 注册底层设备消息
  268. CMsgCenter& MsgCenter = CMsgCenter::GetInstance();
  269. MsgCenter.unregist(DEV_EVENT_RES_DETAIL, this);
  270. MsgCenter.unregist(DEV_EVENT_RES_STATUS, this);
  271. }