mod_counterconnector.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. /////////////////////////////////
  2. ///// 连线服务
  3. /////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ListEntry.h"
  6. #include "Event.h"
  7. #include "mod_counterconnector.h"
  8. #include "CounterConnector_msg_g.h"
  9. using namespace CounterConnector;
  10. #define EVT_CONVERTER "EventConverter"
  11. void CCounterConnectorEntity ::OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  12. {
  13. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  14. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  15. Error = spFunction->SubscribeBroadcast("LivenessDetection", NULL, this, m_uidlivenessListener);
  16. if (Error != Error_Succeed)
  17. {
  18. LOG_TRACE("subscribe LivenessDetection evt failed!");
  19. pTransactionContext->SendAnswer(Error);
  20. return;
  21. }
  22. pTransactionContext->SendAnswer(Error);
  23. }
  24. void CCounterConnectorEntity ::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  25. {
  26. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  27. pTransactionContext->SendAnswer(Error);
  28. }
  29. void CCounterConnectorEntity ::OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  30. {
  31. if (Test_ShakeHand == eTestType)
  32. {
  33. pTransactionContext->SendAnswer(Error_Succeed);
  34. }
  35. }
  36. ErrorCodeEnum CCounterConnectorEntity ::__OnStart(ErrorCodeEnum preOperationError)
  37. {
  38. if (preOperationError != Error_Succeed)
  39. return preOperationError;
  40. //MessageBoxA(0, 0, 0, 0);
  41. //is Pad Version
  42. m_pCurrentSession = NULL;
  43. m_bIsSalesRecord = FALSE;
  44. m_bIsRemoteRecord = FALSE;
  45. m_bIsRemoteRecordBroadCast = FALSE;
  46. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  47. CSystemStaticInfo stStaticinfo;
  48. spFunction->GetSystemStaticInfo(stStaticinfo);
  49. if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0)
  50. {
  51. m_bIsPadType = TRUE;
  52. }
  53. else
  54. {
  55. m_bIsPadType = FALSE;
  56. }
  57. m_IsStand2SType = TRUE;
  58. if (stricmp(stStaticinfo.strMachineType,"RVC.Stand2S")!=0){
  59. m_IsStand2SType = FALSE;
  60. }
  61. ErrorCodeEnum Error;
  62. m_pCounterConnectorChannel = new ChannelCounterConnectorClient(this);
  63. Error = m_pCounterConnectorChannel->Connect();
  64. if (Error != Error_Succeed)
  65. {
  66. m_pCounterConnectorChannel->SafeDelete();
  67. Dbg("ChannelCounterConnectorClient connect fail!");
  68. return Error;
  69. }
  70. {
  71. ChannelService_BeginState_Sub Sub;
  72. Error = m_pCounterConnectorChannel->BeginState(Sub);
  73. if (Error != Error_Succeed)
  74. {
  75. LOG_TRACE("BeginState biz channel failed!");
  76. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  77. m_pCounterConnectorChannel->SafeDelete();
  78. m_pCounterConnectorChannel = NULL;
  79. return Error;
  80. }
  81. }
  82. {
  83. ChannelService_BeginRecv_Sub Sub;
  84. Sub.type = ACM_TYPE_DEVICE;
  85. Error = m_pCounterConnectorChannel->BeginRecv(Sub);
  86. if (Error != Error_Succeed)
  87. {
  88. Dbg("Begin BeginRecv ACM_TYPE_DEVICE failed!");
  89. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  90. m_pCounterConnectorChannel->SafeDelete();
  91. m_pCounterConnectorChannel = NULL;
  92. return Error;
  93. }
  94. }
  95. {
  96. ChannelService_BeginRecv_Sub Sub;
  97. Sub.type = ACM_TYPE_AGENTVIDEOTYPE;
  98. Error = m_pCounterConnectorChannel->BeginRecv(Sub);
  99. if (Error != Error_Succeed)
  100. {
  101. Dbg("Begin BeginRecv ACM_TYPE_AGENTVIDEOTYPE failed!");
  102. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  103. m_pCounterConnectorChannel->SafeDelete();
  104. m_pCounterConnectorChannel = NULL;
  105. return Error;
  106. }
  107. }
  108. {
  109. ChannelService_BeginRecv_Sub Sub;
  110. Sub.type = ACM_TYPE_CALLTRANS;
  111. Error = m_pCounterConnectorChannel->BeginRecv(Sub);
  112. if (Error != Error_Succeed)
  113. {
  114. Dbg("Begin BeginRecv ACM_TYPE_CALLTRANS failed!");
  115. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  116. m_pCounterConnectorChannel->SafeDelete();
  117. m_pCounterConnectorChannel = NULL;
  118. return Error;
  119. }
  120. }
  121. m_fsm.Init(this);
  122. int i = 0;
  123. m_arrListener.Init(24);
  124. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_CALL,NULL,false);
  125. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_CALL,NULL,false);
  126. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_TO_PICKUP);
  127. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_TO_HANDFREE);
  128. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP);
  129. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_CONNECTING);
  130. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_AGENT);
  131. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_PICKUP);
  132. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_HANDFREE);
  133. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP);
  134. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE);
  135. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE);
  136. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_SIPPHONE_IDLE);
  137. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORD,NULL,false);
  138. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPRECORD,NULL,false);
  139. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU,NULL,false);
  140. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTPHOTOGRAPH,NULL,false);
  141. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_DISTRIBUTE_ASSISTANTCHANNEL_IDLE);
  142. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE);
  143. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST,NULL,false);
  144. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL,NULL,false);
  145. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTREMOTERECORD,NULL,false);
  146. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPREMOTERECORD,NULL,false);
  147. spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORDPREVIEW,NULL,false);
  148. return Error_Succeed;
  149. }
  150. ErrorCodeEnum CCounterConnectorEntity ::__OnClose(ErrorCodeEnum preOperationError)
  151. {
  152. if (preOperationError != Error_Succeed)
  153. return preOperationError;
  154. int i;
  155. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  156. for (i = 0; i < m_arrListener.GetCount(); ++i) {
  157. spFunction->UnsubscribeLog(m_arrListener[i]);
  158. }
  159. m_arrListener.Clear();
  160. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_EXIT));
  161. return Error_Succeed;
  162. }
  163. void CCounterConnectorEntity ::OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  164. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  165. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage)
  166. {
  167. LOG_TRACE("user_code = %08x", dwUserCode);
  168. switch (dwUserCode)
  169. {
  170. case EVENT_MOD_CONNECT_GPIO_PICKUP:
  171. {
  172. m_fsm.m_bHandFree = FALSE;
  173. if (!m_fsm.m_bIsAgentControl)
  174. {
  175. m_fsm.m_bAgentHandFree = FALSE;
  176. }
  177. CSimpleStringA strValue;
  178. GetFunction()->GetSysVar("CallState", strValue);
  179. Dbg("摘机,and CallState is %s.", strValue);
  180. }
  181. break;
  182. case EVENT_MOD_CONNECT_GPIO_HANDFREE:
  183. {
  184. m_fsm.m_bHandFree = TRUE;
  185. if (!m_fsm.m_bIsAgentControl)
  186. {
  187. m_fsm.m_bAgentHandFree = TRUE;
  188. }
  189. CSimpleStringA strValue;
  190. GetFunction()->GetSysVar("CallState", strValue);
  191. Dbg("挂机,and CallState is %s.", strValue);
  192. }
  193. break;
  194. case EVENT_MOD_CONNECT_PICKUP_CALL: // 提机呼叫
  195. if (!m_bIsRemoteRecordBroadCast){
  196. Dbg("提机呼叫");
  197. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_PICKUP_CALL));
  198. }
  199. else{
  200. Dbg("remote recording broadcast time, ignore mod connect pickup call event, and hand free flag is %s.",m_fsm.m_bHandFree?"true": "false");
  201. }
  202. break;
  203. case EVENT_MOD_CONNECT_HANDFREE_CALL: // 免提呼叫
  204. if (m_fsm.m_bHandFree)
  205. {
  206. LogEvent(Severity_Middle,EVENT_MOD_CONNECT_SLV_HANDFREECALL,"handfree call");
  207. Dbg("界面拨号,免提呼叫");
  208. if (pszMessage && strlen(pszMessage) > 0 && isdigit(pszMessage[0]))
  209. {
  210. char tmp[32];
  211. int i = 0;
  212. const char *p = pszMessage;
  213. while (isdigit(*p) && i < 30) {
  214. tmp[i++] = *p++;
  215. }
  216. tmp[i] = 0;
  217. m_fsm.m_strHintCallNum = tmp;
  218. }
  219. else
  220. {
  221. m_fsm.m_strHintCallNum = "";
  222. }
  223. Dbg("recv UI call num = %s",m_fsm.m_strHintCallNum);
  224. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANDFREE_CALL));
  225. }
  226. else
  227. {
  228. LogEvent(Severity_Middle,EVENT_MOD_CONNECT_SLV_PICKUPCALL,"from handfree to pickup call because pickup");
  229. Dbg("界面拨号,话筒呼叫");
  230. if (pszMessage && strlen(pszMessage) > 0 && isdigit(pszMessage[0]))
  231. {
  232. char tmp[32];
  233. int i = 0;
  234. const char *p = pszMessage;
  235. while (isdigit(*p) && i < 30) {
  236. tmp[i++] = *p++;
  237. }
  238. tmp[i] = 0;
  239. m_fsm.m_strHintCallNum = tmp;
  240. }
  241. else
  242. {
  243. m_fsm.m_strHintCallNum = "";
  244. }
  245. Dbg("recv call num = %s",m_fsm.m_strHintCallNum);
  246. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_PICKUP_CALL));
  247. }
  248. break;
  249. case EVENT_MOD_CONNECT_HANDFREE_TO_PICKUP: // 免提->提机
  250. if (!m_bIsRemoteRecordBroadCast){
  251. Dbg("免提->提机");
  252. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_PICKUP));
  253. if (strcmp(m_fsm.GetCurrStateName(),"HandFree")==0){
  254. m_fsm.m_bAgentHandFree = FALSE;
  255. }
  256. SendCurAudioDevice();
  257. }
  258. else{
  259. Dbg("remote recording broadcast time, ignore mod connect hand free to pickup event,and hand free flag is %s.",m_fsm.m_bHandFree?"true": "false");
  260. }
  261. break;
  262. case EVENT_MOD_CONNECT_PICKUP_TO_HANDFREE: // 提机->免提
  263. if (!m_bIsRemoteRecordBroadCast){
  264. Dbg("提机->免提");
  265. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_HANDFREE));
  266. if (strcmp(m_fsm.GetCurrStateName(),"Pickup")==0){
  267. m_fsm.m_bAgentHandFree = TRUE;
  268. }
  269. SendCurAudioDevice();
  270. }
  271. else{
  272. Dbg("remote recording broadcast time, ignore mod connect pickup to hand free event,and hand free flag is %s.",m_fsm.m_bHandFree?"true": "false");
  273. }
  274. break;
  275. case EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP: // 坐席控制免提->提机
  276. Dbg("免提->提机");
  277. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_PICKUP));
  278. SendCurAudioDevice();
  279. break;
  280. case EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE: // 坐席控制提机->免提
  281. Dbg("提机->免提");
  282. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_HANDFREE));
  283. SendCurAudioDevice();
  284. break;
  285. case EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL:
  286. {
  287. Dbg("开始远程双录呼叫.");
  288. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_DOUBLE_RECORD_CALL));
  289. if (TRUE == m_fsm.m_bHandFree){
  290. LogEvent(Severity_Middle,LOG_EVT_HANDFREE_MODE_REMOTE_CALL,"remote double call start with hand free mode.");
  291. }
  292. else{
  293. LogEvent(Severity_Middle,LOG_EVT_PICKUP_MODE_REMOTE_CALL,"remote double call start with pick up mode.");
  294. }
  295. }
  296. break;
  297. case EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST:
  298. Dbg("双录播报完结束,重置电话状态");
  299. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOP_RECORD_BROADCAST));
  300. m_bIsRemoteRecordBroadCast = FALSE;
  301. break;
  302. case EVENT_MOD_CONNECT_HANNUP: // 挂机
  303. {
  304. Dbg("断开呼叫");
  305. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP));
  306. m_fsm.m_bHangup=TRUE;
  307. }
  308. break;
  309. case EVENT_MOD_CONNECT_HANNUP_BY_CONNECTING: // 话筒未接通时挂机
  310. Dbg("话筒未接通时断开呼叫");
  311. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP));
  312. //m_fsm.m_bHandFree = TRUE;
  313. m_fsm.m_bHangup=TRUE;
  314. break;
  315. case EVENT_MOD_CONNECT_HANNUP_BY_AGENT: // 授权操作
  316. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_AGENT_WRITABLE));
  317. case LOG_EVT_DISTRIBUTE_ASSISTANTCHANNEL_IDLE:
  318. case LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE: //若assistchannel重启
  319. Dbg("user_code = %08x", dwUserCode);
  320. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_ASSISTCHAN_IDEL));
  321. if(m_pCounterConnectorChannel != NULL)
  322. {
  323. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  324. m_pCounterConnectorChannel->SafeDelete();
  325. m_pCounterConnectorChannel = NULL;
  326. Dbg("Close AssistChannel Session ");
  327. }
  328. if(m_pCounterConnectorChannel == NULL)
  329. {
  330. Dbg("ReConnection AssistChannel Session");
  331. ErrorCodeEnum Error;
  332. m_pCounterConnectorChannel = new ChannelCounterConnectorClient(this);
  333. Error = m_pCounterConnectorChannel->Connect();
  334. if (Error != Error_Succeed)
  335. {
  336. m_pCounterConnectorChannel->SafeDelete();
  337. m_pCounterConnectorChannel = NULL;
  338. Dbg("ChannelCounterConnectorClient connect fail!");
  339. }
  340. if (Error == Error_Succeed)
  341. {
  342. ChannelService_BeginState_Sub Sub;
  343. Error = m_pCounterConnectorChannel->BeginState(Sub);
  344. if (Error != Error_Succeed)
  345. {
  346. Dbg("BeginState biz channel failed!");
  347. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  348. m_pCounterConnectorChannel->SafeDelete();
  349. m_pCounterConnectorChannel = NULL;
  350. }
  351. }
  352. if (Error == Error_Succeed)
  353. {
  354. ChannelService_BeginRecv_Sub Sub;
  355. Sub.type = ACM_TYPE_DEVICE;
  356. Error = m_pCounterConnectorChannel->BeginRecv(Sub);
  357. if (Error != Error_Succeed)
  358. {
  359. Dbg("Begin BeginRecv ACM_TYPE_DEVICE failed!");
  360. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  361. m_pCounterConnectorChannel->SafeDelete();
  362. m_pCounterConnectorChannel = NULL;
  363. }
  364. }
  365. if (Error == Error_Succeed)
  366. {
  367. ChannelService_BeginRecv_Sub Sub;
  368. Sub.type = ACM_TYPE_CALLTRANS;
  369. Error = m_pCounterConnectorChannel->BeginRecv(Sub);
  370. if (Error != Error_Succeed)
  371. {
  372. Dbg("Begin BeginRecv ACM_TYPE_CALLTRANS failed!");
  373. m_pCounterConnectorChannel->GetFunction()->CloseSession();
  374. m_pCounterConnectorChannel->SafeDelete();
  375. m_pCounterConnectorChannel = NULL;
  376. }
  377. }
  378. }
  379. break;
  380. case LOG_EVT_SELFCHECK_SIPPHONE_IDLE: //sip话机重启
  381. Dbg("recv LOG_EVT_SELFCHECK_SIPPHONE_IDLE");
  382. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_SIPPHONE_IDEL));
  383. break;
  384. case LOG_EVT_UI_STARTRECORD:
  385. case LOG_EVT_UI_STARTRECORDPREVIEW:
  386. Dbg("start sales record video,get pos = %s",pszMessage);
  387. Handle_StartRecord(pszMessage);
  388. break;
  389. case LOG_EVT_UI_STARTREMOTERECORD:
  390. {
  391. Dbg("start sales remote record video,get pos = %s",pszMessage);
  392. Handle_StartRemoteRecord(pszMessage);
  393. }
  394. break;
  395. case LOG_EVT_UI_STOPRECORD:
  396. Dbg("begin stop sales record video.");
  397. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOCALVIDEO));
  398. m_bIsSalesRecord = FALSE;
  399. break;
  400. case LOG_EVT_UI_STOPREMOTERECORD:
  401. Dbg("begin stop double record video,and cur state name is %s.",m_fsm.GetCurrStateName());
  402. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOACALREMOTEVIDEO));
  403. m_bIsRemoteRecord = FALSE;
  404. m_bIsRemoteRecordBroadCast = FALSE;
  405. break;
  406. case LOG_EVT_UI_RETURNMENU:
  407. if (m_bIsSalesRecord)
  408. {
  409. Dbg("stop sales record video by return menu");
  410. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOCALVIDEO));
  411. m_bIsSalesRecord = FALSE;
  412. }
  413. if (m_bIsRemoteRecord)
  414. {
  415. Dbg("stop remote record video by return menu.");
  416. if (m_fsm.m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE){
  417. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOACALREMOTEVIDEO));
  418. }
  419. else{
  420. Dbg("hangup call by return menu, CurrStateName is %s.", m_fsm.GetCurrStateName());
  421. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP));
  422. m_fsm.m_bHangup=TRUE;
  423. }
  424. m_bIsRemoteRecord = FALSE;
  425. }
  426. break;
  427. case LOG_EVT_UI_STARTPHOTOGRAPH:
  428. if (stricmp(m_fsm.GetCurrStateName(),"Offline")!=0)
  429. {
  430. LogEvent(Severity_Middle,EVENT_MOD_CONNECT_HANNUP,"UI start photograrh, hangup!");
  431. }
  432. else
  433. {
  434. Dbg("offline state,ignore UI_STARTPHOTOGRAPH hangup event");
  435. }
  436. break;
  437. case LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE: //sip话机状态重置
  438. Dbg("recv LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE");
  439. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_SIPPHONE_IDEL));
  440. break;
  441. default:
  442. break;
  443. }
  444. }
  445. CServerSessionBase*CCounterConnectorEntity::OnNewSession(const char* /*pszRemoteEntityName*/, const char* /*pszClass*/)
  446. {
  447. LOG_FUNCTION();
  448. m_pCurrentSession = new CCounterConnectorSession(this);
  449. return m_pCurrentSession;
  450. }
  451. bool CCounterConnectorEntity ::IsService() const
  452. {
  453. return true;
  454. }
  455. //change audio device message
  456. void CCounterConnectorEntity ::OnReceivePkt(int type, int sub_type, const char *buffer, int size)
  457. {
  458. Dbg("recv pkt type=%d,subtype=%d",type,sub_type);
  459. if ((type == ACM_TYPE_DEVICE)&&!m_bIsPadType)
  460. {
  461. switch (sub_type)
  462. {
  463. //设备切换
  464. //change to handfree
  465. case ACM_CHANGE_HANDFREE:
  466. Dbg("recv change audiodevice to handfree");
  467. if (!m_fsm.m_bAgentHandFree)
  468. {
  469. LogEvent(Severity_Middle,EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE,"agent change audio device to handfree");
  470. m_fsm.m_bAgentHandFree = TRUE;
  471. }
  472. else
  473. {
  474. Dbg("agent want change audiodevice to handfree,but the device is handfree now");
  475. }
  476. break;
  477. //change to pickup
  478. case ACM_CHANGE_PICKUP:
  479. Dbg("recv change audiodevice to pickup");
  480. if (m_fsm.m_bAgentHandFree)
  481. {
  482. LogEvent(Severity_Middle,EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP,"agent change audio device to pickup");
  483. m_fsm.m_bAgentHandFree = FALSE;
  484. }
  485. else
  486. {
  487. Dbg("agent want change audiodevice to pickup,but the device is pickup now");
  488. }
  489. break;
  490. default:
  491. LOG_TRACE("unknown sub_type %d from agent!", sub_type);
  492. break;
  493. }
  494. }
  495. else if (type == ACM_TYPE_CALLTRANS)
  496. {
  497. Dbg("recv ACM_TYPE_CALLTRANS");
  498. if (sub_type == ACM_CALLTRANS_NUM)
  499. {
  500. //CALL transfer
  501. CallTransferInfo Callnum;
  502. SpBuffer buf;
  503. buf.OpenRead(buffer,size);
  504. Callnum.Serialize(buf);
  505. Dbg("recv ACM_CALLTRANS_NUM = %s",Callnum.CallNum);
  506. //广播,业务中台接收
  507. SpSendBroadcast(GetFunction(), SP_MSG_OF(CallTransferInfo), SP_MSG_SIG_OF(CallTransferInfo), Callnum);
  508. }
  509. }
  510. else if (type == ACM_TYPE_AGENTVIDEOTYPE)
  511. {
  512. if (sub_type == ACM_AGENTVIDEOTYPE_ONEWAY)
  513. {
  514. //广播单向视频
  515. AgentVideoType agentvideotype;
  516. agentvideotype.VideoType = 0;
  517. Dbg("Broadcast Oneway video");
  518. SpSendBroadcast(GetFunction(), SP_MSG_OF(AgentVideoType), SP_MSG_SIG_OF(AgentVideoType), agentvideotype);
  519. }
  520. else if (sub_type == ACM_AGENTVIDEOTYPE_TWOWAY)
  521. {
  522. //广播双向视频
  523. AgentVideoType agentvideotype;
  524. agentvideotype.VideoType = 1;
  525. Dbg("Broadcast Twoway Video");
  526. SpSendBroadcast(GetFunction(), SP_MSG_OF(AgentVideoType), SP_MSG_SIG_OF(AgentVideoType), agentvideotype);
  527. }
  528. }
  529. }
  530. CSimpleStringA CCounterConnectorEntity ::BuildVideoDesc(int local_view_x, int local_view_y, int local_view_cx, int local_view_cy)
  531. {
  532. char param[512];
  533. sprintf(param,
  534. "remote_ip:0\r\n"
  535. "remote_video_rtp:0\r\n"
  536. "remote_video_width:0\r\n"
  537. "remote_video_height:0\r\n"
  538. "remote_video_fps:0\r\n"
  539. "local_view_x:%d\r\n"
  540. "local_view_y:%d\r\n"
  541. "local_view_cx:%d\r\n"
  542. "local_view_cy:%d\r\n"
  543. "remote_view_x:0\r\n"
  544. "remote_view_y:0\r\n"
  545. "remote_view_cx:0\r\n"
  546. "remote_view_cy:0\r\n\r\n",
  547. local_view_x, local_view_y, local_view_cx, local_view_cy);
  548. return CSimpleStringA(param);
  549. }
  550. CSimpleStringA CCounterConnectorEntity ::BuildDoubleVideoDesc(int local_view_x, int local_view_y, int local_view_cx, int local_view_cy, int remote_view_x, int remote_view_y, int remote_view_cx, int remote_view_cy)
  551. {
  552. char param[512];
  553. sprintf(param,
  554. "remote_ip:0\r\n"
  555. "remote_video_rtp:0\r\n"
  556. "remote_video_width:0\r\n"
  557. "remote_video_height:0\r\n"
  558. "remote_video_fps:0\r\n"
  559. "local_view_x:%d\r\n"
  560. "local_view_y:%d\r\n"
  561. "local_view_cx:%d\r\n"
  562. "local_view_cy:%d\r\n"
  563. "remote_view_x:%d\r\n"
  564. "remote_view_y:%d\r\n"
  565. "remote_view_cx:%d\r\n"
  566. "remote_view_cy:%d\r\n\r\n",
  567. local_view_x, local_view_y, local_view_cx, local_view_cy,
  568. remote_view_x, remote_view_y, remote_view_cx, remote_view_cy);
  569. return CSimpleStringA(param);
  570. }
  571. CSimpleStringA CCounterConnectorEntity ::ConstructVideoParam(CSimpleStringA strMsg, bool bDoubleVideo)
  572. {
  573. int lxPos,lyPos,lwidth,lheight,rxPos,ryPos,rwidth,rheight;
  574. CSimpleStringA strVideoParam;
  575. CSimpleStringA str;
  576. if (false == bDoubleVideo){
  577. sscanf(strMsg.GetData(), "%d@%d@%d@%d@%d@%s", &lxPos, &lyPos, &lwidth, &lheight, &str);
  578. Dbg("local video param : (x=%d,y=%d,width=%d,height=%d).",lxPos,lyPos,lwidth,lheight);
  579. strVideoParam = BuildVideoDesc(lxPos,lyPos,lwidth,lheight);
  580. }
  581. else{
  582. int iPostionArr[4][2] = {0};
  583. if (strMsg.GetLength() >0)
  584. {
  585. CAutoArray<CSimpleStringA> arrstr = strMsg.Split('@');
  586. if (arrstr.GetCount() >= 4)
  587. {
  588. for(int i=0; i<4; i++)
  589. {
  590. sscanf(arrstr[i].GetData(), "%d|%d", &iPostionArr[i][0], &iPostionArr[i][1]);
  591. }
  592. }
  593. }
  594. Dbg("remote record local video param : (x=%d,y=%d,width=%d,height=%d), remote video param : (x=%d,y=%d,width=%d,height=%d)",
  595. iPostionArr[0][0], iPostionArr[1][0],iPostionArr[2][0], iPostionArr[3][0],iPostionArr[0][1], iPostionArr[1][1],iPostionArr[2][1], iPostionArr[3][1]);
  596. strVideoParam = BuildDoubleVideoDesc(iPostionArr[0][0], iPostionArr[1][0],iPostionArr[2][0], iPostionArr[3][0],iPostionArr[0][1], iPostionArr[1][1],iPostionArr[2][1], iPostionArr[3][1]);
  597. }
  598. return strVideoParam;
  599. }
  600. void CCounterConnectorEntity::Handle_StartRecord(const char* pszMessage)
  601. {
  602. // edit by ly@2019/04/18
  603. CSimpleStringA strMsg = pszMessage;
  604. if (strMsg.IsStartWith("ews|",true)){
  605. strMsg = strMsg.SubString(4,strMsg.GetLength()-4);
  606. }
  607. CSimpleStringA strVideo;
  608. strVideo = ConstructVideoParam(strMsg, false);
  609. m_fsm.PostEventFIFO(new ShowLocalVideoEvent(strVideo)); // 非连坐席双录
  610. m_bIsSalesRecord = TRUE;
  611. }
  612. void CCounterConnectorEntity::Handle_StartRemoteRecord(const char* pszMessage)
  613. {
  614. // edit by ly@2019/04/18
  615. CSimpleStringA strMsg = pszMessage;
  616. CSimpleStringA strVideo = ConstructVideoParam(strMsg, true);
  617. m_fsm.PostEventFIFO(new ShowLocalAndRemoteVideoEvent(strVideo)); // 连坐席双录
  618. m_bIsRemoteRecord = TRUE;
  619. m_bIsRemoteRecordBroadCast = TRUE;
  620. m_bIsRemoteRecordStopSpeakerCapture = FALSE;
  621. }
  622. void CCounterConnectorEntity::StopRemoteRecordSpeakerAudioCapture()
  623. {
  624. if(DOUBLERECORD_CALLTYPE == m_fsm.m_CallingParam.nCallType){
  625. if (TRUE == m_IsStand2SType){
  626. if (FALSE == m_bIsRemoteRecordStopSpeakerCapture){
  627. if (Error_Succeed == m_fsm.StopSpeakerAudioCapture()){
  628. m_bIsRemoteRecordStopSpeakerCapture = TRUE;
  629. }
  630. }
  631. else{
  632. Dbg("remote record has stop speaker capture.");
  633. }
  634. }
  635. }
  636. }
  637. void CCounterConnectorEntity::Handle_StartRecordPreview(const char* pszMessage)
  638. {
  639. CSimpleStringA strMsg = pszMessage;
  640. if (strMsg.IsStartWith("ews|",true)){
  641. strMsg = strMsg.SubString(4,strMsg.GetLength()-4);
  642. }
  643. CSimpleStringA strVideo;
  644. strVideo = ConstructVideoParam(strMsg, false);
  645. m_fsm.PostEventFIFO(new ShowLocalVideoEvent(strVideo)); // 非连坐席双录
  646. m_bIsSalesRecord = TRUE;
  647. }
  648. //send cur audio device to agent
  649. void CCounterConnectorEntity ::SendCurAudioDevice()
  650. {
  651. if (m_fsm.m_nSysCallType == 0)
  652. {
  653. ChannelService_Send_Info Info;
  654. Info.compress = false;
  655. Info.encrypt = false;
  656. Info.type = ACM_TYPE_DEVICE;
  657. Info.id = 0;
  658. Info.sub_type = ACM_AUDIO_DEVICE;
  659. Info.data.Alloc(sizeof(int));
  660. SpBuffer buf;
  661. buf.OpenWrite();
  662. int nDevice = 0;
  663. if (m_fsm.m_bIsAgentControl)
  664. {
  665. if (m_fsm.m_bAgentHandFree)
  666. {
  667. nDevice = 0;
  668. }
  669. else
  670. {
  671. nDevice = 1;
  672. }
  673. }
  674. else
  675. {
  676. if (m_fsm.m_bHandFree)
  677. {
  678. nDevice = 0;
  679. }
  680. else
  681. {
  682. nDevice = 1;
  683. }
  684. }
  685. buf & nDevice;
  686. Info.data = buf.ToBlob();
  687. m_pCounterConnectorChannel->Send(Info);
  688. Dbg("send cur Audio device = %d",nDevice);
  689. }
  690. else
  691. {
  692. Dbg("cur call type cannot send pkt");
  693. }
  694. }
  695. void CCounterConnectorEntity::SetCallType(CallingTypeEnum eType)
  696. {
  697. m_fsm.SetCallingType(eType);
  698. }
  699. void CCounterConnectorEntity::OnLivenessDetectionStarted(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, LivenessDetection::ActiveDetectionStarted &evt)
  700. {
  701. Dbg("LiveDetectionStarted %s", (LPCTSTR)evt.Param);
  702. LogEvent(Severity_Middle,LOG_EVT_STARTLIVEDETECTDISPLAY,"start live detection");
  703. Sleep(400);
  704. int rxPos,ryPos,rwidth,rheight,xPos,yPos,width,height;
  705. CSimpleStringA str;
  706. sscanf((LPCTSTR)evt.Param, "%d@%d@%d@%d@%d@%d@%d@%d", &rxPos, &ryPos, &rwidth, &rheight,&xPos, &yPos, &width, &height);
  707. Dbg("live detection display window x=%d,y=%d,width=%d,height=%d",xPos,yPos,width,height);
  708. CSimpleStringA strVideo = BuildVideoDesc(xPos,yPos,width,height);
  709. m_fsm.PostEventFIFO(new StartVideoDisplayEvent(strVideo));
  710. }
  711. void CCounterConnectorEntity::OnLivenessDetectionStopped(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, LivenessDetection::ActiveDetectionStopped &evt)
  712. {
  713. Dbg("LiveDetectionStopped %s", (LPCTSTR)evt.Param);
  714. LogEvent(Severity_Middle,LOG_EVT_STOPLIVEDETECTDISPLAY,"stop live detection");
  715. m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPVIDEODISPLAY));
  716. }
  717. void CCounterConnectorEntity::OnActiveDetectionDone(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, LivenessDetection::ActiveDetectionDone &evt)
  718. {
  719. }
  720. void CCounterConnectorEntity::OnAutoSnapshotRemind(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, LivenessDetection::AutoSnapshotRemind &evt)
  721. {
  722. }
  723. void CCounterConnectorEntity::OnLivenessDetectionHeartBeat(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, LivenessDetection::LivenessDetectionHeartBeat &evt)
  724. {
  725. }
  726. void CCounterConnectorEntity::OnDetectionStopUnExpected(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, LivenessDetection::DetectionStopUnExpected &evt)
  727. {
  728. }
  729. ChannelCounterConnectorClient::ChannelCounterConnectorClient( CCounterConnectorEntity *pEntity ) : ChannelService_ClientBase(pEntity)
  730. {
  731. }
  732. void ChannelCounterConnectorClient::OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData)
  733. {
  734. if (Error == Error_Succeed)
  735. {
  736. CCounterConnectorEntity *pEntity = static_cast<CCounterConnectorEntity*>(m_pEntityBase);
  737. if (Msg.state == eChannelState_Idle)
  738. {
  739. pEntity->m_fsm.m_bIsAgentControl = FALSE;
  740. }
  741. else if (Msg.state == eChannelState_Connected)
  742. {
  743. pEntity->m_fsm.m_bIsAgentControl = TRUE;
  744. pEntity->SendCurAudioDevice();
  745. }
  746. }
  747. }
  748. void ChannelCounterConnectorClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
  749. {
  750. LOG_FUNCTION();
  751. if (Error == Error_Succeed)
  752. {
  753. CCounterConnectorEntity *pEntity = static_cast<CCounterConnectorEntity*>(m_pEntityBase);
  754. pEntity->OnReceivePkt(Msg.type, Msg.sub_type, (const char*)Msg.data.m_pData, Msg.data.m_iLength);
  755. }
  756. }
  757. void CCounterConnectorSession::Handle_StartCall(SpReqAnsContext<ConnectService_StartCall_Req, ConnectService_StartCall_Ans>::Pointer ctx)
  758. {
  759. LOG_FUNCTION();
  760. ErrorCodeEnum rc = Error_Succeed;
  761. m_pEntity->m_fsm.m_CallingParam.connect_ip = ctx->Req.connect_ip;
  762. m_pEntity->m_fsm.m_CallingParam.connect_port = ctx->Req.connect_port;
  763. m_pEntity->m_fsm.m_CallingParam.nCallType = (CallingTypeEnum)ctx->Req.callingtype;
  764. m_pEntity->m_fsm.m_CallingParam.connect_session = ctx->Req.connect_session;
  765. m_pEntity->m_fsm.m_CallingParam.assistant_port = ctx->Req.assistant_port;
  766. m_pEntity->m_fsm.m_CallingParam.subid = ctx->Req.subid;
  767. m_pEntity->m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_COMMAND_CALL));
  768. ctx->Answer((ErrorCodeEnum)rc);
  769. }
  770. void CCounterConnectorSession::Handle_StartCallExternal(SpReqAnsContext<ConnectService_StartCallExternal_Req, ConnectService_StartCallExternal_Ans>::Pointer ctx)
  771. {
  772. LOG_FUNCTION();
  773. ErrorCodeEnum rc = Error_Succeed;
  774. RVCCallingParam* callparam = (RVCCallingParam*)ctx->Req.CommandParam.m_pData;
  775. if (callparam)
  776. {
  777. m_pEntity->m_fsm.m_CallingParam.connect_ip = callparam->strConnectIp ;
  778. m_pEntity->m_fsm.m_CallingParam.connect_port = callparam->nSipPort;
  779. m_pEntity->m_fsm.m_CallingParam.nCallType = (CallingTypeEnum)callparam->nCallType;
  780. m_pEntity->m_fsm.m_CallingParam.connect_session = callparam->strConnectSession;
  781. m_pEntity->m_fsm.m_CallingParam.subid = callparam->strSubid;
  782. m_pEntity->m_fsm.m_CallingParam.assistant_port = callparam->nAsisstPort;
  783. Dbg("Handle_StartCallExternal strConnectIp=%s, nSipPort=%d, nCallType=%d, strConnectSession=%s, strSubid=%s, nAsisstPort=%d", callparam->strConnectIp,
  784. callparam->nSipPort, callparam->nCallType, callparam->strConnectSession, callparam->strSubid, callparam->nAsisstPort);
  785. }
  786. else
  787. {
  788. Dbg("Get RVCCallingParam Failed!\n");
  789. }
  790. m_pEntity->m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_COMMAND_CALL));
  791. ctx->Answer((ErrorCodeEnum)rc);
  792. }
  793. void CCounterConnectorSession::Handle_StopCall(SpReqAnsContext<ConnectService_StopCall_Req, ConnectService_StopCall_Ans>::Pointer ctx)
  794. {
  795. LOG_FUNCTION();
  796. ErrorCodeEnum rc = Error_Succeed;
  797. RVCCallingParam* callparam = (RVCCallingParam*)ctx->Req.SessionParam.m_pData;
  798. if (callparam){
  799. m_pEntity->m_fsm.m_SessionParam.connect_ip = callparam->strConnectIp ;
  800. m_pEntity->m_fsm.m_SessionParam.connect_session = callparam->strConnectSession;
  801. m_pEntity->m_fsm.m_SessionParam.event_port = callparam->nInstructPort;
  802. Dbg("Handle_StopCall strConnectIp=%s, strConnectSession=%s,event_port=%d", m_pEntity->m_fsm.m_SessionParam.connect_ip.GetData(),
  803. m_pEntity->m_fsm.m_SessionParam.connect_session.GetData(), m_pEntity->m_fsm.m_SessionParam.event_port);
  804. }
  805. else
  806. {
  807. Dbg("Get SessionParam Failed!\n");
  808. }
  809. Dbg("holder hangup call!");
  810. m_pEntity->m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP));
  811. ctx->Answer((ErrorCodeEnum)rc);
  812. }
  813. void CCounterConnectorSession::OnClose( ErrorCodeEnum eErrorCode )
  814. {
  815. LOG_FUNCTION();
  816. }
  817. SP_BEGIN_ENTITY_MAP()
  818. SP_ENTITY(CCounterConnectorEntity)
  819. SP_END_ENTITY_MAP()