HolderContextFSM.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. #pragma once
  2. #include "SpBase.h"
  3. #include "SpFSM.h"
  4. #include "SpSecureClient.h"
  5. #include "HolderContext_msg_g.h"
  6. #include "..\mod_counterconnector\CounterConnector_client_g.h"
  7. #include <list.h>
  8. #include<string.h>
  9. #include<vector>
  10. #include<iostream>
  11. #include <sstream>
  12. #include<stack>
  13. using namespace std;
  14. using namespace HolderContext;
  15. using namespace CounterConnector;
  16. #define USER_EVT_JMP_IDENTIFIED EVT_USER+1
  17. #define USER_EVT_JMP_STANDBY EVT_USER+2
  18. #define USER_EVT_JMP_RINGING EVT_USER+3
  19. #define USER_EVT_JMP_ONLINE EVT_USER+4
  20. #define USER_EVT_JMP_DEALING EVT_USER+5
  21. #define USER_EVT_JMP_EDIT EVT_USER+6
  22. #define USER_EVT_JMP_DISCONNECT EVT_USER+7
  23. #define USER_EVT_JMP_LOCAL EVT_USER+8
  24. #define USER_EVT_JMP_WORKING EVT_USER+9
  25. #define USER_EVT_JMP_UNSERVICE EVT_USER+10
  26. #define USER_EVT_JMP_NOTHELD EVT_USER+11
  27. #define USER_EVT_JMP_BUSY EVT_USER+12
  28. #define USER_EVT_JMP_EDITEND EVT_USER+13
  29. #define USER_EVT_JMP_NONE EVT_USER+14
  30. #define USER_EVT_HOLDERSTATE_ANS EVT_USER+15
  31. #define USER_EVT_MESSAGE_ANS EVT_USER+16
  32. #define USER_EVT_HOLDERSKILL_ANS EVT_USER+17
  33. //用户类型
  34. #define USER_TYPE_MAINTAIN 00 //维护用户
  35. #define USER_TYPE_MATERIAL_MANAGER 01 //物料管理用户
  36. #define USER_TYPE_CUSTOMER_MANAGER 02 //客户经理
  37. #define USER_TYPE_AGENT3 03 //Agent3用户
  38. #define USER_TYPE_FINANCING_MANAGER 04 //理财经理
  39. //机型
  40. #define MACHINETYPE_STAND2S "RVC.Stand2S" //站立式双屏
  41. #define MACHINETYPE_STAND1S "RVC.Stand1S" //站立式单屏
  42. #define MACHINETYPE_WALL "RVC.Wall" //挂墙式
  43. #define MACHINETYPE_EMBED2S "RVC.Embed2S" //嵌墙式双屏
  44. #define MACHINETYPE_EMBED1S "RVC.Embed1S" //嵌墙式单屏
  45. #define MACHINETYPE_PAD "RVC.PAD" //携带式移动终端
  46. //场所
  47. #define SIT_LIB "cmb.LIB" //银行大堂内
  48. #define SIT_SSB "cmb.SSB" //自助营业网点
  49. #define SIT_FLB "cmb.FLB" //离行机器,银行业务为主界面,如企业,商场
  50. #define SIT_LSS "cmb.LSS" //面向生活销售机,一般部署在小区,面向销售广告
  51. #define SIT_SMM "cmb.SMM" //商场销售门户,放置在商场,多商户门户
  52. #define ERR_NO_CONNECTRIGHT 901 //没有远程服务权限
  53. #define ERR_CONNECTSERVICE_FROM_CENTER 902 //根据集中配置连接指令服务失败
  54. #define ERR_CONNECT 903 //网络异常,无法连接指令服务
  55. #define ERR_SEND_REQ 904
  56. #define ERR_RECIEVE_ANS 905
  57. #define ERR_INVALID_ANS 906
  58. //add code by @wb
  59. #define FIX_UPLOAD_TIMER 17000 //固定上报时间
  60. #define FIX_CHECK_LIST_TIMER 2000 //固定状态list检查时间
  61. #define FIX_DWTICK_TIMER 6000 // 固定超时检测时间
  62. #define FIX_SETSTATE_TIMER 1000 //固定设置状态后的等待时间
  63. #define FIX_SETSTATE_TIMER_1 2000
  64. //定义list中package最大数量
  65. #define PACKAGE_MAX_NUM 3
  66. //定义recvState最大数量
  67. #define RECV_MAX_NUM 600
  68. // [StructName("HolderState")]
  69. struct HolderState
  70. {
  71. CSimpleStringA HolderID; //持有者AgentID
  72. CSimpleStringA TerminalNo; //终端号
  73. CSimpleStringA State; //持有者状态
  74. //CSimpleStringA HolderPosition; //持有者位置
  75. //CSimpleStringA HolderSkill; //持有者技能
  76. };
  77. // [StructName("HolderStateReqEx")]
  78. struct HolderStateReqEx
  79. {
  80. char HolderID[16];
  81. char TerminalNo[10];
  82. char State[1];
  83. char BranceNo[4];
  84. char IP[16];
  85. char Port[8];
  86. //add code by @wb
  87. char nSkillSets[1];
  88. char SerialNumber[64]; //确认序列号(唯一标识)
  89. char SerialID[1]; //确认ID
  90. char dwNow[16]; //时间戳
  91. };
  92. //add code by @wb
  93. //用于状态上报
  94. //struct HandleReqState
  95. //{
  96. // //struct list_head entry;
  97. // //CSmartPointer<IPackage> package;
  98. // HolderStateReqEx *hsReq;
  99. //};
  100. //extern struct list_head hdStateList_head;
  101. // [StructName("HolderStateAnsEx")]
  102. struct HolderStateAnsEx
  103. {
  104. int nRet;
  105. //add code by @wb
  106. char SerialNumber[64]; //确认序列号(唯一标识)
  107. char SerialID[1]; //确认ID
  108. char dwNow[16]; //时间戳
  109. };
  110. //[StructName("StateAnsEx")]
  111. //新增用于总行状态的确认回复
  112. struct HdStaAns
  113. {
  114. int nRet;
  115. char HolderID[16];
  116. char TerminalNo[10];
  117. char State[1];
  118. char SerialNumber[64]; //确认序列号(唯一标识)
  119. char SerialID[1]; //确认ID
  120. char dwNow[16]; //时间戳
  121. };
  122. //add code by @wb
  123. //[StructName("InsReqEx")]
  124. struct InstrReqEx
  125. {
  126. char InstrucID[64]; //指令唯一标识
  127. char InstrucCSeq[64];
  128. char InstrucGenarateTime[32];
  129. char InstrucLastSendTime[32];
  130. char HolderID[16]; //持有人ID
  131. int EvtCode; //指令序列号
  132. char InstrType[1]; //指令类型,连线指令为"O"
  133. unsigned char CommandParam[256]; //指令内容
  134. };
  135. //add code by @wb
  136. //[StructName("InstrPushAns")]
  137. struct InstrAnsEx
  138. {
  139. char InstrucID[64]; //指令唯一标识
  140. int EvtCode; //指令序列号
  141. int Errmsg; //错误消息
  142. };
  143. struct HolderStateAnsEvent : public FSMEvent
  144. {
  145. HolderStateAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_HOLDERSTATE_ANS)
  146. {
  147. memcpy(&m_reply, pBuf, sizeof(HolderStateAnsEx));
  148. }
  149. virtual ~HolderStateAnsEvent() {}
  150. HolderStateAnsEx m_reply;
  151. };
  152. // [StructName("MessageReq")]
  153. struct MessageReq
  154. {
  155. char AgentID[16]; //用户号
  156. char MessageID[8]; //消息号,上个最大号,如果都要就填0
  157. };
  158. // [StructName("MessageAns")]
  159. struct MessageAns
  160. {
  161. char MessageID[8]; //当前消息编号s
  162. char ExpireTime[20]; //消息失效时间,如果当前时间大于失效时间,消息丢弃
  163. char MessageType[1]; //消息类型
  164. char ImportantLevel[1]; //重要级别
  165. char Competitive[1]; //是否竞争性任务
  166. char ContinuinglyFlag[1]; //续传标志位
  167. char ServiceCode[32]; //业务类型码
  168. char Data[1024]; //消息内容,可以是信息,流程入口和参数,变长数据
  169. };
  170. struct MessageAnsEvent : public FSMEvent
  171. {
  172. MessageAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_MESSAGE_ANS)
  173. {
  174. memcpy(&m_reply, pBuf, sizeof(MessageAns));
  175. }
  176. virtual ~MessageAnsEvent() {}
  177. MessageAns m_reply;
  178. };
  179. // [StructName("HolderSkillReq")]
  180. struct HolderSkillReq
  181. {
  182. char AgentID[10]; //用户号
  183. };
  184. // [StructName("HolderSkillAns")]
  185. struct HolderSkillAns
  186. {
  187. char HolderSkill[128]; //持有者技能
  188. };
  189. struct HolderSkillAnsEvent : public FSMEvent
  190. {
  191. HolderSkillAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_HOLDERSKILL_ANS)
  192. {
  193. memcpy(&m_reply, pBuf, sizeof(HolderSkillAns));
  194. }
  195. virtual ~HolderSkillAnsEvent() {}
  196. HolderSkillAns m_reply;
  197. };
  198. class instructionsServerConnection;
  199. class HolderContextFSM : public FSMImpl<HolderContextFSM>, public IFSMStateHooker
  200. {
  201. public:
  202. enum {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12};
  203. BEGIN_FSM_STATE(HolderContextFSM)
  204. FSM_STATE_ENTRY(s0,"None",s0_on_entry,s0_on_exit,s0_on_event)
  205. FSM_STATE_ENTRY(s1,"Identified",s1_on_entry,s1_on_exit,s1_on_event)
  206. FSM_STATE_ENTRY(s2,"Unservice",s2_on_entry,s2_on_exit,s2_on_event)
  207. FSM_STATE_ENTRY(s3,"Standby",s3_on_entry,s3_on_exit,s3_on_event)
  208. FSM_STATE_ENTRY(s4,"NotHeld",s4_on_entry,s4_on_exit,s4_on_event)
  209. FSM_STATE_ENTRY(s5,"Busy",s5_on_entry,s5_on_exit,s5_on_event)
  210. FSM_STATE_ENTRY(s6,"Local",s6_on_entry,s6_on_exit,s6_on_event)
  211. FSM_STATE_ENTRY(s7,"Working",s7_on_entry,s7_on_exit,s7_on_event)
  212. FSM_STATE_ENTRY(s8,"Ringing",s8_on_entry,s8_on_exit,s8_on_event)
  213. FSM_STATE_ENTRY(s9,"Online",s9_on_entry,s9_on_exit,s9_on_event)
  214. FSM_STATE_ENTRY(s10,"Dealing",s10_on_entry,s10_on_exit,s10_on_event)
  215. FSM_STATE_ENTRY(s11,"Edit",s11_on_entry,s11_on_exit,s11_on_event)
  216. FSM_STATE_ENTRY(s12,"Disconnect",s12_on_entry,s12_on_exit,s12_on_event)
  217. END_FSM_STATE()
  218. BEGIN_FSM_RULE(HolderContextFSM,s0)
  219. FSM_RULE_ENTRY_ANY(s0, s1, USER_EVT_JMP_IDENTIFIED)
  220. FSM_RULE_ENTRY_ANY(s0, s2, USER_EVT_JMP_UNSERVICE)
  221. FSM_RULE_ENTRY_ANY(s0, s3, USER_EVT_JMP_STANDBY)
  222. //add s0转s5
  223. FSM_RULE_ENTRY_ANY(s0, s5, USER_EVT_JMP_BUSY)
  224. FSM_RULE_ENTRY_ANY(s1, s0, EVT_TIMER)
  225. FSM_RULE_ENTRY_ANY(s2, s0, EVT_TIMER)
  226. FSM_RULE_ENTRY_ANY(s3, s4, USER_EVT_JMP_NOTHELD)//待确认
  227. FSM_RULE_ENTRY_ANY(s3, s12, USER_EVT_JMP_DISCONNECT)
  228. FSM_RULE_ENTRY_ANY(s3, s5, USER_EVT_JMP_BUSY)//界面点示忙
  229. FSM_RULE_ENTRY_ANY(s3, s6, USER_EVT_JMP_LOCAL)
  230. FSM_RULE_ENTRY_ANY(s3, s8, USER_EVT_JMP_RINGING)
  231. FSM_RULE_ENTRY_ANY(s3, s0, EVT_TIMER)
  232. FSM_RULE_ENTRY_ANY(s3, s0, USER_EVT_JMP_NONE)//点签出
  233. FSM_RULE_ENTRY_ANY(s4, s0, EVT_TIMER)
  234. FSM_RULE_ENTRY_ANY(s5, s0, EVT_TIMER)
  235. //add by zl 2017.12.08
  236. FSM_RULE_ENTRY_ANY(s5, s0, USER_EVT_JMP_NONE)
  237. FSM_RULE_ENTRY_ANY(s5, s3, USER_EVT_JMP_STANDBY)
  238. FSM_RULE_ENTRY_ANY(s6, s3, USER_EVT_JMP_STANDBY)
  239. FSM_RULE_ENTRY_ANY(s6, s0, EVT_TIMER)
  240. FSM_RULE_ENTRY_ANY(s8, s3, USER_EVT_JMP_STANDBY)//待确认
  241. FSM_RULE_ENTRY_ANY(s8, s5, USER_EVT_JMP_BUSY)
  242. FSM_RULE_ENTRY_ANY(s8, s9, USER_EVT_JMP_ONLINE)
  243. FSM_RULE_ENTRY_ANY(s8, s10, USER_EVT_JMP_DEALING)
  244. FSM_RULE_ENTRY_ANY(s8, s0, EVT_TIMER)
  245. FSM_RULE_ENTRY_ANY(s9, s10, USER_EVT_JMP_DEALING)
  246. FSM_RULE_ENTRY_ANY(s9, s11, USER_EVT_JMP_EDIT)
  247. FSM_RULE_ENTRY_ANY(s9, s0, EVT_TIMER)
  248. FSM_RULE_ENTRY_ANY(s10, s11, USER_EVT_JMP_EDIT)
  249. FSM_RULE_ENTRY_ANY(s10, s0, EVT_TIMER)
  250. FSM_RULE_ENTRY_ANY(s11, s0, EVT_TIMER)
  251. FSM_RULE_ENTRY_ANY(s11, s3, USER_EVT_JMP_EDITEND)
  252. FSM_RULE_ENTRY_ANY(s12, s3, USER_EVT_JMP_STANDBY)
  253. FSM_RULE_ENTRY_ANY(s12, s0, EVT_TIMER)
  254. END_FSM_RULE()
  255. HolderContextFSM();
  256. ~HolderContextFSM();
  257. virtual void OnStateTrans(int iSrcState, int iDstState);
  258. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName);
  259. virtual ErrorCodeEnum OnInit();
  260. virtual ErrorCodeEnum OnExit();
  261. void s0_on_entry();
  262. void s0_on_exit();
  263. unsigned int s0_on_event(FSMEvent* event);
  264. void s1_on_entry();
  265. void s1_on_exit();
  266. unsigned int s1_on_event(FSMEvent* event);
  267. void s2_on_entry();
  268. void s2_on_exit();
  269. unsigned int s2_on_event(FSMEvent* event);
  270. void s3_on_entry();
  271. void s3_on_exit();
  272. unsigned int s3_on_event(FSMEvent* event);
  273. void s4_on_entry();
  274. void s4_on_exit();
  275. unsigned int s4_on_event(FSMEvent* event);
  276. void s5_on_entry();
  277. void s5_on_exit();
  278. unsigned int s5_on_event(FSMEvent* event);
  279. void s6_on_entry();
  280. void s6_on_exit();
  281. unsigned int s6_on_event(FSMEvent* event);
  282. void s7_on_entry();
  283. void s7_on_exit();
  284. unsigned int s7_on_event(FSMEvent* event);
  285. void s8_on_entry();
  286. void s8_on_exit();
  287. unsigned int s8_on_event(FSMEvent* event);
  288. void s9_on_entry();
  289. void s9_on_exit();
  290. unsigned int s9_on_event(FSMEvent* event);
  291. void s10_on_entry();
  292. void s10_on_exit();
  293. unsigned int s10_on_event(FSMEvent* event);
  294. void s11_on_entry();
  295. void s11_on_exit();
  296. unsigned int s11_on_event(FSMEvent* event);
  297. void s12_on_entry();
  298. void s12_on_exit();
  299. unsigned int s12_on_event(FSMEvent* event);
  300. BOOL GetCallState();
  301. BOOL GetHolderState();
  302. BOOL SetHolderState(CSimpleStringA strState);
  303. BOOL GetHolderRights();//获取当前持有者是否有在线服务权限,Agent3数据库查询
  304. BOOL GetHolderMsg(CSimpleStringA strHolderInfo);
  305. //add code by @wb
  306. //上报持有者状态
  307. BOOL UploadHolderState();
  308. //BOOL TimerUploadHolderState();
  309. //add code by @wb
  310. //重传持有者状态确认包
  311. BOOL ReTransmissReq(HolderStateReqEx req);
  312. //DWORD HandleInstrution(const char *pszInstraction);
  313. //BOOL GetConnectTaskFromInstrationServer();
  314. //add code by @wb
  315. //关闭终端到分行服务连接
  316. void Disconnect();
  317. //重连操作
  318. void Reconnect();
  319. BOOL SendConnectTask();
  320. BOOL HangupTask();
  321. DWORD CheckHolderRights();
  322. DWORD QueryHolderSkill();
  323. BOOL GetEntityState(CSimpleStringA strEntityName, int &nState);
  324. DWORD FindSubStr(const char* source, const char* target);
  325. void SetErrMsg(DWORD dwErrcode, CSimpleStringA strErrmsg);
  326. CSimpleStringA m_strCallstate;
  327. HolderState m_HolderState;
  328. CSimpleStringA m_strHolderInfo;
  329. char m_cTaskData[1024]; //任务内容
  330. char m_cHolderSkill[128]; //技能内容
  331. BOOL m_bLogon;//持有者是否签入,0(未签入);1(签入)
  332. CSimpleStringA m_strErrmsg;
  333. DWORD m_nErrcode;
  334. BOOL m_bHolderBusy;//终端业务界面点击示忙,此时不响应callsate的状态变化,直至点示闲才响应callsate的状态。
  335. BOOL m_bMenu; //是否在首页状态
  336. CSimpleStringA m_CurCallState; //当前通话状态
  337. BOOL m_bIncomeHangup; //接通前客户主动挂断标志
  338. //定义vector来存储上报状态
  339. std::vector<HolderStateReqEx>reqStateVec;
  340. //定义vector用于总行上报状态的确认
  341. std::vector<HolderStateReqEx>hdStateReqVec;
  342. //定义vector用于总行确认个数统计确认
  343. std::vector<char>StateAnsNum;
  344. //设置一个状态恢复的vector
  345. std::vector<char>recvState;
  346. CRITICAL_SECTION cs;
  347. private:
  348. //读配置文件
  349. ErrorCodeEnum LoadServerConfig();
  350. ErrorCodeEnum LoadRootConfig();
  351. ErrorCodeEnum LoadCenterConfig();
  352. CSimpleStringA m_StringVerifyKey,m_StringConsoleName;
  353. CSimpleStringA m_strMachineType, m_strSite;
  354. ErrorCodeEnum AsyncStartEntity(const char *entity_name, const char *cmdline, void *pData);
  355. ErrorCodeEnum AsyncStopEntity(const char *entity_name, void *pData);
  356. instructionsServerConnection *m_pConnection;
  357. CSimpleStringA m_strTerminalNo; //终端号
  358. unsigned int m_RecordNum; //当前终端号对应的任务记录数
  359. ConnectService_ClientBase *m_pConnectService;
  360. protected:
  361. };
  362. class instructionsServerConnection : public SpSecureClient
  363. {
  364. public:
  365. instructionsServerConnection(CEntityBase *pEntity, HolderContextFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM) {}
  366. virtual ~instructionsServerConnection() {}
  367. void SendHolderStateReq()
  368. {
  369. HolderStateReqEx req={0};
  370. //标识用于重传的标识ID
  371. int countID = 1;
  372. // 压力测试
  373. // for(int i = 0; i < 100; ++ i)
  374. // {
  375. //增加HolderID不为空以及空格的判断
  376. if(m_pFSM->m_HolderState.HolderID.GetLength() > 2)
  377. {
  378. memcpy(req.HolderID, m_pFSM->m_HolderState.HolderID, m_pFSM->m_HolderState.HolderID.GetLength());
  379. Dbg("@wb req.HolderID%s", req.HolderID);
  380. memcpy(req.TerminalNo, m_pFSM->m_HolderState.TerminalNo, 10);
  381. memcpy(req.State,m_pFSM->m_HolderState.State, 1);
  382. //add code by @wb
  383. //获取唯一的序列号
  384. CUUID m_uid = CUUID::Create(m_uid);
  385. memcpy(req.SerialNumber, m_uid.ToString(), strlen( m_uid.ToString()));
  386. Dbg("@wb req.SerialNumber%s", req.SerialNumber);
  387. char ID[4] = {0};
  388. sprintf(ID, "%d", countID);
  389. memcpy(req.SerialID, ID, strlen(ID));
  390. Dbg("SerialID %s", req.SerialID);
  391. ////获取时间戳
  392. char time[16] = {0};
  393. long tc = GetTickCount();
  394. //sprintf(time, "%dl", tc);
  395. ltoa(tc, time, 10);
  396. memcpy(req.dwNow, time, strlen(time));
  397. Dbg("@wb req.dwNow%s ", req.dwNow);
  398. CSmartPointer<IPackage> pkt = CreateNewPackage("StaReqEx");
  399. pkt->AddStruct("HolderStateReqEx", false, false, (LPBYTE)&req, sizeof(HolderStateReqEx));
  400. if (SendPackage(pkt) == "")
  401. {
  402. Dbg("SendPackage failed, send [%s] sate[%s] failed", req.HolderID, req.State);
  403. m_pFSM->SetErrMsg(ERR_SEND_REQ,"上报持有者状态失败");
  404. return;
  405. }
  406. else
  407. {
  408. Dbg("send holder[%s] sate[%s] success", req.HolderID, req.State);
  409. EnterCriticalSection(&m_pFSM->cs);
  410. Dbg("push the req to reqStateVec");
  411. m_pFSM->reqStateVec.push_back(req);
  412. if(_strnicmp(req.State, "N", strlen("N")) != 0)
  413. {
  414. Dbg("push the req to hdStateReqVec");
  415. m_pFSM->hdStateReqVec.push_back(req);
  416. }
  417. LeaveCriticalSection(&m_pFSM->cs);
  418. Dbg("tmp->hsReq %s",req.SerialNumber);
  419. Dbg("send holder[%s] sate[%s] success", req.HolderID, req.State);
  420. }
  421. }
  422. // }
  423. }
  424. void reSendHdStateReq(HolderStateReqEx req)
  425. {
  426. CSmartPointer<IPackage> pkt = CreateNewPackage("StaReqEx");
  427. pkt->AddStruct("HolderStateReqEx", false, false, (LPBYTE)&req, sizeof(HolderStateReqEx));
  428. //reSend上报状态
  429. if (SendPackage(pkt) == "")
  430. {
  431. Dbg("reSendPackage failed, send [%s] sate[%s] failed", req.HolderID, req.State);
  432. m_pFSM->SetErrMsg(ERR_SEND_REQ,"重新上报持有者状态失败");
  433. return;
  434. }
  435. else
  436. {
  437. EnterCriticalSection(&m_pFSM->cs);
  438. Dbg("push the req to reqStateVec");
  439. m_pFSM->reqStateVec.push_back(req);
  440. if(_strnicmp(req.State, "N", strlen("N")) != 0)
  441. {
  442. Dbg("push the req to hdStateReqVec");
  443. m_pFSM->hdStateReqVec.push_back(req);
  444. }
  445. LeaveCriticalSection(&m_pFSM->cs);
  446. Dbg("reSend holder[%s] sate[%s] SerialNumber[%s] success", req.HolderID, req.State, req.SerialNumber);
  447. Dbg("m_pFSM->reqStateVec.size() %d", m_pFSM->reqStateVec.size());
  448. }
  449. }
  450. void SendMessageReq()
  451. {
  452. MessageReq req = {0};
  453. Dbg("SendMessageReq, HolderID:%s", m_pFSM->m_HolderState.HolderID);
  454. memcpy(req.AgentID, m_pFSM->m_HolderState.HolderID, m_pFSM->m_HolderState.HolderID.GetLength());
  455. //memcpy(req.MessageID, 0, 8);//消息ID设为0,全部取 TODO:为什么此处会导致lost
  456. CSmartPointer<IPackage> pkt = CreateNewPackage("MesReq");
  457. pkt->AddStruct("MessageReq", false, false, (LPBYTE)&req, sizeof(MessageReq));
  458. if (SendPackage(pkt) == "")
  459. {
  460. Dbg("SendPackage failed, send [%s] MesReq failed", req.AgentID);
  461. m_pFSM->SetErrMsg(ERR_SEND_REQ,"发送连线任务请求失败");
  462. return;
  463. }
  464. else
  465. {
  466. Dbg("send holder[%s] MesReq success", req.AgentID);
  467. }
  468. }
  469. DWORD SendHolderSkillReq()
  470. {
  471. HolderSkillReq req = {0};
  472. //消息ID设为0,全部取
  473. CSimpleStringA strAgentID = "SP";
  474. strAgentID += m_pFSM->m_HolderState.HolderID;
  475. memcpy(req.AgentID, strAgentID, strAgentID.GetLength());
  476. CSmartPointer<IPackage> pkt = CreateNewPackage("HdSkiReq");
  477. pkt->AddStruct("HolderSkillReq", false, false, (LPBYTE)&req, sizeof(HolderSkillReq));
  478. if (SendPackage(pkt) == "")
  479. {
  480. Dbg("SendPackage failed, send holder skill req failed");
  481. m_pFSM->SetErrMsg(ERR_SEND_REQ,"发送资质查询请求失败");
  482. return ERR_SEND_REQ;
  483. }
  484. else
  485. {
  486. Dbg("send holder skill req success");
  487. }
  488. auto pRetPkg = ReceivePackage(5);
  489. if (pRetPkg == NULL)
  490. {
  491. Dbg("ReceivePackage failed, don't revceive holder skill ans");
  492. m_pFSM->SetErrMsg(ERR_RECIEVE_ANS,"接收资质查询响应失败");
  493. return ERR_RECIEVE_ANS;
  494. }
  495. ErrorCodeEnum rc = Error_Succeed;
  496. DWORD dwSysCode, dwUserCode;
  497. string strErrMsg;
  498. CSimpleStringA strRetErrMsg;
  499. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  500. {
  501. rc = (ErrorCodeEnum)dwSysCode;
  502. LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str());
  503. strRetErrMsg = strErrMsg.c_str();
  504. m_pFSM->SetErrMsg(rc, strRetErrMsg);
  505. return rc;
  506. }
  507. int nLen = pRetPkg->GetStructLen("HolderSkillAns");
  508. if (nLen > 0)
  509. {
  510. BYTE *pBuf = new BYTE[nLen];
  511. memset(pBuf, 0, nLen);
  512. int nArrayNum = 0;
  513. if (pRetPkg->GetStructData("HolderSkillAns", pBuf, &nLen, &nArrayNum))
  514. {
  515. Dbg("收到HolderSkillAns");
  516. FSMEvent *evt = new HolderSkillAnsEvent(pBuf, nLen);
  517. HolderSkillAnsEvent *ans = (HolderSkillAnsEvent *)evt;
  518. memcpy(m_pFSM->m_cHolderSkill,ans->m_reply.HolderSkill,128);
  519. /*CSimpleStringA strSkill = m_pFSM->m_cHolderSkill;
  520. Dbg("[%s]技能列表[%s]",strAgentID,strSkill.GetData());*/
  521. delete evt;
  522. }
  523. else
  524. {
  525. m_pFSM->SetErrMsg(ERR_INVALID_ANS,"无效的资质查询响应");
  526. Dbg("get invalid HolderSkillAns packet!");
  527. return ERR_INVALID_ANS;
  528. }
  529. delete pBuf;
  530. return Error_Succeed;
  531. }
  532. else
  533. {
  534. Dbg("get GetStructLen len failed!");
  535. return ERR_INVALID_ANS;
  536. }
  537. }
  538. void HandleHolderStateAns(const CSmartPointer<IPackage> &pRecvPkg)
  539. {
  540. ErrorCodeEnum rc = Error_Succeed;
  541. DWORD dwSysCode, dwUserCode;
  542. string strErrMsg;
  543. CSimpleStringA strRetErrMsg;
  544. Dbg("start recieve ans");
  545. char SerialNum[64];
  546. //struct HandleReqState tp;
  547. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  548. {
  549. rc = (ErrorCodeEnum)dwSysCode;
  550. LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str());
  551. strRetErrMsg = strErrMsg.c_str();
  552. m_pFSM->SetErrMsg(rc, strRetErrMsg);
  553. return;
  554. }
  555. int nLen = pRecvPkg->GetStructLen("HolderStateAnsEx");
  556. Dbg("start GetStructLen ans");
  557. if (nLen > 0)
  558. {
  559. BYTE *pBuf = new BYTE[nLen];
  560. memset(pBuf, 0, nLen);
  561. int nArrayNum = 0;
  562. Dbg("start GetStructLen ans >0");
  563. if (pRecvPkg->GetStructData("HolderStateAnsEx", pBuf, &nLen, &nArrayNum))
  564. {
  565. FSMEvent *evt = new HolderStateAnsEvent(pBuf, nLen);
  566. HolderStateAnsEvent *ans = (HolderStateAnsEvent *)evt;
  567. Dbg("start GetStruct nRet %s", ans->m_reply.nRet);
  568. if (0 == ans->m_reply.nRet)
  569. {
  570. Dbg("HolderStateAnsEx return ok!");
  571. //处理分行服务端的回包 ,将reqStateVec中对应的发包进行删除
  572. memcpy(SerialNum, ans->m_reply.SerialNumber, 64);
  573. Dbg("SerialNum is %s", SerialNum);
  574. EnterCriticalSection(&m_pFSM->cs);
  575. Dbg("m_pFSM->reqStateVec.size() %d", m_pFSM->reqStateVec.size());
  576. int m_size = m_pFSM->reqStateVec.size();
  577. for (int i = m_size-1; i >= 0; i --)
  578. {
  579. if(strncmp((m_pFSM->reqStateVec)[i].SerialNumber, SerialNum, 64) == 0)
  580. {
  581. Dbg("(m_pFSM->reqStateVec)[i].hsReq->SerialNumber %s", (m_pFSM->reqStateVec)[i].SerialNumber);
  582. (m_pFSM->reqStateVec).erase((m_pFSM->reqStateVec).begin()+i);
  583. Dbg("m_pFSM->reqStateVec %d", m_pFSM->reqStateVec.size());
  584. //m_size --;
  585. }
  586. }
  587. LeaveCriticalSection(&m_pFSM->cs);
  588. }
  589. else
  590. {
  591. Dbg("HolderStateAnsEx return failed!");
  592. }
  593. delete evt;
  594. }
  595. else
  596. {
  597. Dbg("get invalid HolderStateAnsEx packet!");
  598. }
  599. delete pBuf;
  600. // return;
  601. }
  602. return;
  603. }
  604. void HandleIncomeHangupTask()
  605. {
  606. m_pFSM->HangupTask();
  607. //add广播客户端主动挂断eMsg_incomeHangup消息
  608. Connecting e;
  609. SpSendBroadcast(m_pEntity->GetFunction(),eMsg_incomeHangup , eMsgSig_incomeHangup, e);
  610. Dbg("SpSendBroadcast eMsg_incomeHangup");
  611. }
  612. //add code by @wb
  613. //接收分行推送指令处理
  614. void RecieveInstruction(const CSmartPointer<IPackage> &pRecvPkg)
  615. {
  616. ErrorCodeEnum rc = Error_Succeed;
  617. DWORD dwSysCode, dwUserCode;
  618. string strErrMsg;
  619. CSimpleStringA strRetErrMsg;
  620. InstrReqEx m_req;
  621. InstrAnsEx ans = {0};
  622. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  623. {
  624. rc = (ErrorCodeEnum)dwSysCode;
  625. LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str());
  626. strRetErrMsg = strErrMsg.c_str();
  627. m_pFSM->SetErrMsg(rc, strRetErrMsg);
  628. return;
  629. }
  630. //获取指令Req
  631. int nLen = pRecvPkg->GetStructLen("InsReqEx");
  632. if (nLen > 0)
  633. {
  634. BYTE *pBuf = new BYTE[nLen];
  635. memset(pBuf, 0, nLen);
  636. int nArrayNum = 0;
  637. if (pRecvPkg->GetStructData("InsReqEx", pBuf, &nLen, &nArrayNum))
  638. {
  639. memcpy(&m_req, pBuf, sizeof(InstrReqEx));
  640. if (_strnicmp(m_req.InstrType, "O", strlen("O")) == 0)
  641. {
  642. //连线任务(O)
  643. Dbg("收到连线任务");
  644. memcpy(m_pFSM->m_cTaskData, m_req.CommandParam, 256);
  645. m_pFSM->SetHolderState("R");//进入振铃状态
  646. m_pFSM->m_bIncomeHangup = FALSE;
  647. }
  648. else if (_strnicmp(m_req.InstrType, "I", strlen("I")) == 0)
  649. {
  650. //用户信息(I)
  651. Dbg("收到用户信息");
  652. }
  653. else if (_strnicmp(m_req.InstrType, "L", strlen("L")) == 0)
  654. {
  655. //现场求助任务(L)
  656. Dbg("收到现场求助任务指令");
  657. }
  658. else if (_strnicmp(m_req.InstrType, "T", strlen("T")) == 0)
  659. {
  660. //现场转移任务(T)
  661. Dbg("收到现场转移任务");
  662. }
  663. else if (_strnicmp(m_req.InstrType, "F", strlen("F")) == 0)
  664. {
  665. //流程任务(F)
  666. Dbg("收到流程任务");
  667. }
  668. else if (_strnicmp(m_req.InstrType, "C", strlen("C")) == 0)
  669. {
  670. //取消任务(C)
  671. Dbg("收到取消任务");
  672. m_pFSM->m_bIncomeHangup = TRUE;
  673. //执行挂断操作
  674. HandleIncomeHangupTask();
  675. }
  676. else if (_strnicmp(m_req.InstrType, "S", strlen("S")) == 0)
  677. {
  678. //框架指令(S)
  679. Dbg("收到框架指令");
  680. }
  681. else if (_strnicmp(m_req.InstrType, "N", strlen("N")) == 0)
  682. {
  683. //没有任务(N)
  684. Dbg("当前用户没有任务");
  685. }
  686. else
  687. {
  688. Dbg("收到指令类型无法识别,[%s]", m_req.InstrType);
  689. }
  690. //Sleep(5000);
  691. memcpy(ans.InstrucID, m_req.InstrucID, strlen(m_req.InstrucID));
  692. ans.EvtCode = m_req.EvtCode;
  693. CSmartPointer<IPackage> pkt = CreateNewPackage("InsAnsEx");
  694. pkt->AddStruct("InsAnsEx", false, false, (LPBYTE)&ans, sizeof(InstrAnsEx));
  695. //发送指令回复包
  696. if (SendPackage(pkt) == "")
  697. {
  698. Dbg("SendPackage failed, send InstrPush ans failed");
  699. m_pFSM->SetErrMsg(ERR_SEND_REQ,"发送收到指令数据包失败");
  700. }
  701. else
  702. {
  703. Dbg("send InstrPush ans success");
  704. }
  705. }
  706. else
  707. {
  708. Dbg("get invalid RecieveInstruction packet!");
  709. }
  710. delete pBuf;
  711. }
  712. return;
  713. }
  714. //接收到总行直接回复的状态确认包
  715. void RecieveStateAns(const CSmartPointer<IPackage> &pRecvPkg)
  716. {
  717. ErrorCodeEnum rc = Error_Succeed;
  718. DWORD dwSysCode, dwUserCode;
  719. string strErrMsg;
  720. CSimpleStringA strRetErrMsg;
  721. HdStaAns m_ans = {0};
  722. char SerialNum[64];
  723. char State_value[10] = {0};
  724. char Recover_state[10] = {0};
  725. int m_size = m_pFSM->hdStateReqVec.size();
  726. Dbg("hdStateReqVec size is %d ", m_size);
  727. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  728. {
  729. rc = (ErrorCodeEnum)dwSysCode;
  730. LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str());
  731. strRetErrMsg = strErrMsg.c_str();
  732. m_pFSM->SetErrMsg(rc, strRetErrMsg);
  733. return;
  734. }
  735. //获取总行状态回复HdStaAns
  736. int nLen = pRecvPkg->GetStructLen("HdStaAns");
  737. if (nLen > 0)
  738. {
  739. BYTE *pBuf = new BYTE[nLen];
  740. memset(pBuf, 0, nLen);
  741. int nArrayNum = 0;
  742. if (pRecvPkg->GetStructData("HdStaAns", pBuf, &nLen, &nArrayNum))
  743. {
  744. //同步总行状态
  745. memcpy(&m_ans, pBuf, sizeof(HdStaAns));
  746. //获取唯一标识
  747. memcpy(SerialNum, m_ans.SerialNumber, 64);
  748. Dbg("HdStaAns SerialNum is %s", SerialNum);
  749. memcpy(State_value, m_ans.State, 1);
  750. Dbg("HdStaAns state is %s", State_value);
  751. if(_strnicmp(State_value, "N", strlen("N")) != 0)
  752. {
  753. m_pFSM->recvState.push_back(State_value[0]);
  754. }
  755. int n_size = m_pFSM->recvState.size();
  756. Dbg("recvState size %d", n_size);
  757. EnterCriticalSection(&m_pFSM->cs);
  758. Dbg("StateAnsNum size%d", m_pFSM->StateAnsNum.size());
  759. if(m_pFSM->StateAnsNum.size() == 0)
  760. {
  761. Dbg("push the state %s for StateAnsNum!", State_value);
  762. EnterCriticalSection(&m_pFSM->cs);
  763. m_pFSM->StateAnsNum.push_back(State_value[0]);
  764. LeaveCriticalSection(&m_pFSM->cs);
  765. }
  766. else
  767. {
  768. Dbg("compare the state%c", State_value[0]);
  769. Dbg("compare the StateAnsNum state%c", (m_pFSM->StateAnsNum)[0]);
  770. if(State_value[0] == ((m_pFSM->StateAnsNum)[0]))
  771. {
  772. //避免数组出现越界
  773. if(_strnicmp(State_value, "N", strlen("N")) == 0)
  774. {
  775. if(n_size > 0)
  776. {
  777. //恢复成离线前的状态
  778. Dbg("Recover_state state is %c", (m_pFSM->recvState)[n_size-1]);
  779. Dbg("Recover State from central server and Set HolderState to %c state!", (m_pFSM->recvState)[n_size-1]);
  780. char tmp[2];
  781. tmp[0] = (m_pFSM->recvState)[n_size-1];
  782. tmp[1] = '\0';
  783. m_pFSM->SetHolderState(tmp);
  784. EnterCriticalSection(&m_pFSM->cs);
  785. m_pFSM->recvState.clear();
  786. LeaveCriticalSection(&m_pFSM->cs);
  787. }
  788. else
  789. {
  790. m_pFSM->SetHolderState("S");
  791. }
  792. }
  793. else
  794. {
  795. Dbg("Update State from central server and Set HolderState to %s state!", State_value);
  796. m_pFSM->SetHolderState(State_value);
  797. }
  798. }
  799. //有无同步状态都需要清空StateAnsNum存储的state value
  800. m_pFSM->StateAnsNum.clear();
  801. }
  802. //说明与总行连接没有问题,直接清空所有积累的包
  803. //m_pFSM->hdStateReqVec.clear();
  804. Dbg("hdStateReqVec size is %d", m_size);
  805. //说明和总行连接没有问题,删除所有拥有相同state的数据包
  806. for (int i = m_size-1; i >= 0; i --)
  807. {
  808. if(strncmp((m_pFSM->hdStateReqVec)[i].State, State_value, 1) == 0)
  809. {
  810. Dbg("(Remove m_pFSM->hdStateReqVec)[i].State is %s", (m_pFSM->hdStateReqVec)[i].State);
  811. (m_pFSM->hdStateReqVec).erase((m_pFSM->hdStateReqVec).begin()+i);
  812. }
  813. }
  814. LeaveCriticalSection(&m_pFSM->cs);
  815. }
  816. delete pBuf;
  817. }
  818. return;
  819. }
  820. //add code by @wb
  821. //断开分行服务连接
  822. void handleDisconnect()
  823. {
  824. this->Close();
  825. this->DecRefCount();
  826. }
  827. protected:
  828. virtual void OnPkgAnswer(const CSmartPointer<IPackage> &pRecvPkg)
  829. {
  830. string serviceCode = pRecvPkg->GetServiceCode();
  831. Dbg("start OnReceivePackage, serviceCode[%s]",serviceCode.c_str());
  832. if (serviceCode == "StaReqEx")
  833. {
  834. HandleHolderStateAns(pRecvPkg);
  835. }
  836. //add code by @wb
  837. //处理指令req
  838. else if(serviceCode == "InsReqEx")
  839. {
  840. RecieveInstruction(pRecvPkg);
  841. }
  842. else if(serviceCode == "HdStaAns")
  843. {
  844. RecieveStateAns(pRecvPkg);
  845. }
  846. else
  847. {
  848. Dbg("unknown service code!");
  849. //OnDisconnect();
  850. }
  851. };
  852. virtual void OnReceivePackage(IPackage *pRecvPkg)
  853. {
  854. }
  855. private:
  856. HolderContextFSM *m_pFSM;
  857. };