#pragma once #include "SpBase.h" #include "SpFSM.h" #include "SpSecureClient.h" #include "HolderContext_msg_g.h" #include "..\mod_counterconnector\CounterConnector_client_g.h" #include #include #include #include #include #include using namespace std; using namespace HolderContext; using namespace CounterConnector; #define USER_EVT_JMP_IDENTIFIED EVT_USER+1 #define USER_EVT_JMP_STANDBY EVT_USER+2 #define USER_EVT_JMP_RINGING EVT_USER+3 #define USER_EVT_JMP_ONLINE EVT_USER+4 #define USER_EVT_JMP_DEALING EVT_USER+5 #define USER_EVT_JMP_EDIT EVT_USER+6 #define USER_EVT_JMP_DISCONNECT EVT_USER+7 #define USER_EVT_JMP_LOCAL EVT_USER+8 #define USER_EVT_JMP_WORKING EVT_USER+9 #define USER_EVT_JMP_UNSERVICE EVT_USER+10 #define USER_EVT_JMP_NOTHELD EVT_USER+11 #define USER_EVT_JMP_BUSY EVT_USER+12 #define USER_EVT_JMP_EDITEND EVT_USER+13 #define USER_EVT_JMP_NONE EVT_USER+14 #define USER_EVT_HOLDERSTATE_ANS EVT_USER+15 #define USER_EVT_MESSAGE_ANS EVT_USER+16 #define USER_EVT_HOLDERSKILL_ANS EVT_USER+17 //用户类型 #define USER_TYPE_MAINTAIN 00 //维护用户 #define USER_TYPE_MATERIAL_MANAGER 01 //物料管理用户 #define USER_TYPE_CUSTOMER_MANAGER 02 //客户经理 #define USER_TYPE_AGENT3 03 //Agent3用户 #define USER_TYPE_FINANCING_MANAGER 04 //理财经理 //机型 #define MACHINETYPE_STAND2S "RVC.Stand2S" //站立式双屏 #define MACHINETYPE_STAND1S "RVC.Stand1S" //站立式单屏 #define MACHINETYPE_WALL "RVC.Wall" //挂墙式 #define MACHINETYPE_EMBED2S "RVC.Embed2S" //嵌墙式双屏 #define MACHINETYPE_EMBED1S "RVC.Embed1S" //嵌墙式单屏 #define MACHINETYPE_PAD "RVC.PAD" //携带式移动终端 //场所 #define SIT_LIB "cmb.LIB" //银行大堂内 #define SIT_SSB "cmb.SSB" //自助营业网点 #define SIT_FLB "cmb.FLB" //离行机器,银行业务为主界面,如企业,商场 #define SIT_LSS "cmb.LSS" //面向生活销售机,一般部署在小区,面向销售广告 #define SIT_SMM "cmb.SMM" //商场销售门户,放置在商场,多商户门户 #define ERR_NO_CONNECTRIGHT 901 //没有远程服务权限 #define ERR_CONNECTSERVICE_FROM_CENTER 902 //根据集中配置连接指令服务失败 #define ERR_CONNECT 903 //网络异常,无法连接指令服务 #define ERR_SEND_REQ 904 #define ERR_RECIEVE_ANS 905 #define ERR_INVALID_ANS 906 //add code by @wb #define FIX_UPLOAD_TIMER 17000 //固定上报时间 #define FIX_CHECK_LIST_TIMER 2000 //固定状态list检查时间 #define FIX_DWTICK_TIMER 6000 // 固定超时检测时间 #define FIX_SETSTATE_TIMER 1000 //固定设置状态后的等待时间 #define FIX_SETSTATE_TIMER_1 2000 //定义list中package最大数量 #define PACKAGE_MAX_NUM 3 //定义recvState最大数量 #define RECV_MAX_NUM 600 // [StructName("HolderState")] struct HolderState { CSimpleStringA HolderID; //持有者AgentID CSimpleStringA TerminalNo; //终端号 CSimpleStringA State; //持有者状态 //CSimpleStringA HolderPosition; //持有者位置 //CSimpleStringA HolderSkill; //持有者技能 }; // [StructName("HolderStateReqEx")] struct HolderStateReqEx { char HolderID[16]; char TerminalNo[10]; char State[1]; char BranceNo[4]; char IP[16]; char Port[8]; //add code by @wb char nSkillSets[1]; char SerialNumber[64]; //确认序列号(唯一标识) char SerialID[1]; //确认ID char dwNow[16]; //时间戳 }; //add code by @wb //用于状态上报 //struct HandleReqState //{ // //struct list_head entry; // //CSmartPointer package; // HolderStateReqEx *hsReq; //}; //extern struct list_head hdStateList_head; // [StructName("HolderStateAnsEx")] struct HolderStateAnsEx { int nRet; //add code by @wb char SerialNumber[64]; //确认序列号(唯一标识) char SerialID[1]; //确认ID char dwNow[16]; //时间戳 }; //[StructName("StateAnsEx")] //新增用于总行状态的确认回复 struct HdStaAns { int nRet; char HolderID[16]; char TerminalNo[10]; char State[1]; char SerialNumber[64]; //确认序列号(唯一标识) char SerialID[1]; //确认ID char dwNow[16]; //时间戳 }; //add code by @wb //[StructName("InsReqEx")] struct InstrReqEx { char InstrucID[64]; //指令唯一标识 char InstrucCSeq[64]; char InstrucGenarateTime[32]; char InstrucLastSendTime[32]; char HolderID[16]; //持有人ID int EvtCode; //指令序列号 char InstrType[1]; //指令类型,连线指令为"O" unsigned char CommandParam[256]; //指令内容 }; //add code by @wb //[StructName("InstrPushAns")] struct InstrAnsEx { char InstrucID[64]; //指令唯一标识 int EvtCode; //指令序列号 int Errmsg; //错误消息 }; struct HolderStateAnsEvent : public FSMEvent { HolderStateAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_HOLDERSTATE_ANS) { memcpy(&m_reply, pBuf, sizeof(HolderStateAnsEx)); } virtual ~HolderStateAnsEvent() {} HolderStateAnsEx m_reply; }; // [StructName("MessageReq")] struct MessageReq { char AgentID[16]; //用户号 char MessageID[8]; //消息号,上个最大号,如果都要就填0 }; // [StructName("MessageAns")] struct MessageAns { char MessageID[8]; //当前消息编号s char ExpireTime[20]; //消息失效时间,如果当前时间大于失效时间,消息丢弃 char MessageType[1]; //消息类型 char ImportantLevel[1]; //重要级别 char Competitive[1]; //是否竞争性任务 char ContinuinglyFlag[1]; //续传标志位 char ServiceCode[32]; //业务类型码 char Data[1024]; //消息内容,可以是信息,流程入口和参数,变长数据 }; struct MessageAnsEvent : public FSMEvent { MessageAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_MESSAGE_ANS) { memcpy(&m_reply, pBuf, sizeof(MessageAns)); } virtual ~MessageAnsEvent() {} MessageAns m_reply; }; // [StructName("HolderSkillReq")] struct HolderSkillReq { char AgentID[10]; //用户号 }; // [StructName("HolderSkillAns")] struct HolderSkillAns { char HolderSkill[128]; //持有者技能 }; struct HolderSkillAnsEvent : public FSMEvent { HolderSkillAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_HOLDERSKILL_ANS) { memcpy(&m_reply, pBuf, sizeof(HolderSkillAns)); } virtual ~HolderSkillAnsEvent() {} HolderSkillAns m_reply; }; class instructionsServerConnection; class HolderContextFSM : public FSMImpl, public IFSMStateHooker { public: enum {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12}; BEGIN_FSM_STATE(HolderContextFSM) FSM_STATE_ENTRY(s0,"None",s0_on_entry,s0_on_exit,s0_on_event) FSM_STATE_ENTRY(s1,"Identified",s1_on_entry,s1_on_exit,s1_on_event) FSM_STATE_ENTRY(s2,"Unservice",s2_on_entry,s2_on_exit,s2_on_event) FSM_STATE_ENTRY(s3,"Standby",s3_on_entry,s3_on_exit,s3_on_event) FSM_STATE_ENTRY(s4,"NotHeld",s4_on_entry,s4_on_exit,s4_on_event) FSM_STATE_ENTRY(s5,"Busy",s5_on_entry,s5_on_exit,s5_on_event) FSM_STATE_ENTRY(s6,"Local",s6_on_entry,s6_on_exit,s6_on_event) FSM_STATE_ENTRY(s7,"Working",s7_on_entry,s7_on_exit,s7_on_event) FSM_STATE_ENTRY(s8,"Ringing",s8_on_entry,s8_on_exit,s8_on_event) FSM_STATE_ENTRY(s9,"Online",s9_on_entry,s9_on_exit,s9_on_event) FSM_STATE_ENTRY(s10,"Dealing",s10_on_entry,s10_on_exit,s10_on_event) FSM_STATE_ENTRY(s11,"Edit",s11_on_entry,s11_on_exit,s11_on_event) FSM_STATE_ENTRY(s12,"Disconnect",s12_on_entry,s12_on_exit,s12_on_event) END_FSM_STATE() BEGIN_FSM_RULE(HolderContextFSM,s0) FSM_RULE_ENTRY_ANY(s0, s1, USER_EVT_JMP_IDENTIFIED) FSM_RULE_ENTRY_ANY(s0, s2, USER_EVT_JMP_UNSERVICE) FSM_RULE_ENTRY_ANY(s0, s3, USER_EVT_JMP_STANDBY) //add s0转s5 FSM_RULE_ENTRY_ANY(s0, s5, USER_EVT_JMP_BUSY) FSM_RULE_ENTRY_ANY(s1, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s2, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s3, s4, USER_EVT_JMP_NOTHELD)//待确认 FSM_RULE_ENTRY_ANY(s3, s12, USER_EVT_JMP_DISCONNECT) FSM_RULE_ENTRY_ANY(s3, s5, USER_EVT_JMP_BUSY)//界面点示忙 FSM_RULE_ENTRY_ANY(s3, s6, USER_EVT_JMP_LOCAL) FSM_RULE_ENTRY_ANY(s3, s8, USER_EVT_JMP_RINGING) FSM_RULE_ENTRY_ANY(s3, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s3, s0, USER_EVT_JMP_NONE)//点签出 FSM_RULE_ENTRY_ANY(s4, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s5, s0, EVT_TIMER) //add by zl 2017.12.08 FSM_RULE_ENTRY_ANY(s5, s0, USER_EVT_JMP_NONE) FSM_RULE_ENTRY_ANY(s5, s3, USER_EVT_JMP_STANDBY) FSM_RULE_ENTRY_ANY(s6, s3, USER_EVT_JMP_STANDBY) FSM_RULE_ENTRY_ANY(s6, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s8, s3, USER_EVT_JMP_STANDBY)//待确认 FSM_RULE_ENTRY_ANY(s8, s5, USER_EVT_JMP_BUSY) FSM_RULE_ENTRY_ANY(s8, s9, USER_EVT_JMP_ONLINE) FSM_RULE_ENTRY_ANY(s8, s10, USER_EVT_JMP_DEALING) FSM_RULE_ENTRY_ANY(s8, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s9, s10, USER_EVT_JMP_DEALING) FSM_RULE_ENTRY_ANY(s9, s11, USER_EVT_JMP_EDIT) FSM_RULE_ENTRY_ANY(s9, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s10, s11, USER_EVT_JMP_EDIT) FSM_RULE_ENTRY_ANY(s10, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s11, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s11, s3, USER_EVT_JMP_EDITEND) FSM_RULE_ENTRY_ANY(s12, s3, USER_EVT_JMP_STANDBY) FSM_RULE_ENTRY_ANY(s12, s0, EVT_TIMER) END_FSM_RULE() HolderContextFSM(); ~HolderContextFSM(); virtual void OnStateTrans(int iSrcState, int iDstState); virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName); virtual ErrorCodeEnum OnInit(); virtual ErrorCodeEnum OnExit(); void s0_on_entry(); void s0_on_exit(); unsigned int s0_on_event(FSMEvent* event); void s1_on_entry(); void s1_on_exit(); unsigned int s1_on_event(FSMEvent* event); void s2_on_entry(); void s2_on_exit(); unsigned int s2_on_event(FSMEvent* event); void s3_on_entry(); void s3_on_exit(); unsigned int s3_on_event(FSMEvent* event); void s4_on_entry(); void s4_on_exit(); unsigned int s4_on_event(FSMEvent* event); void s5_on_entry(); void s5_on_exit(); unsigned int s5_on_event(FSMEvent* event); void s6_on_entry(); void s6_on_exit(); unsigned int s6_on_event(FSMEvent* event); void s7_on_entry(); void s7_on_exit(); unsigned int s7_on_event(FSMEvent* event); void s8_on_entry(); void s8_on_exit(); unsigned int s8_on_event(FSMEvent* event); void s9_on_entry(); void s9_on_exit(); unsigned int s9_on_event(FSMEvent* event); void s10_on_entry(); void s10_on_exit(); unsigned int s10_on_event(FSMEvent* event); void s11_on_entry(); void s11_on_exit(); unsigned int s11_on_event(FSMEvent* event); void s12_on_entry(); void s12_on_exit(); unsigned int s12_on_event(FSMEvent* event); BOOL GetCallState(); BOOL GetHolderState(); BOOL SetHolderState(CSimpleStringA strState); BOOL GetHolderRights();//获取当前持有者是否有在线服务权限,Agent3数据库查询 BOOL GetHolderMsg(CSimpleStringA strHolderInfo); //add code by @wb //上报持有者状态 BOOL UploadHolderState(); //BOOL TimerUploadHolderState(); //add code by @wb //重传持有者状态确认包 BOOL ReTransmissReq(HolderStateReqEx req); //DWORD HandleInstrution(const char *pszInstraction); //BOOL GetConnectTaskFromInstrationServer(); //add code by @wb //关闭终端到分行服务连接 void Disconnect(); //重连操作 void Reconnect(); BOOL SendConnectTask(); BOOL HangupTask(); DWORD CheckHolderRights(); DWORD QueryHolderSkill(); BOOL GetEntityState(CSimpleStringA strEntityName, int &nState); DWORD FindSubStr(const char* source, const char* target); void SetErrMsg(DWORD dwErrcode, CSimpleStringA strErrmsg); CSimpleStringA m_strCallstate; HolderState m_HolderState; CSimpleStringA m_strHolderInfo; char m_cTaskData[1024]; //任务内容 char m_cHolderSkill[128]; //技能内容 BOOL m_bLogon;//持有者是否签入,0(未签入);1(签入) CSimpleStringA m_strErrmsg; DWORD m_nErrcode; BOOL m_bHolderBusy;//终端业务界面点击示忙,此时不响应callsate的状态变化,直至点示闲才响应callsate的状态。 BOOL m_bMenu; //是否在首页状态 CSimpleStringA m_CurCallState; //当前通话状态 BOOL m_bIncomeHangup; //接通前客户主动挂断标志 //定义vector来存储上报状态 std::vectorreqStateVec; //定义vector用于总行上报状态的确认 std::vectorhdStateReqVec; //定义vector用于总行确认个数统计确认 std::vectorStateAnsNum; //设置一个状态恢复的vector std::vectorrecvState; CRITICAL_SECTION cs; private: //读配置文件 ErrorCodeEnum LoadRootConfig(); ErrorCodeEnum LoadCenterConfig(); CSimpleStringA m_StringVerifyKey,m_StringConsoleName; CSimpleStringA m_strMachineType, m_strSite; ErrorCodeEnum AsyncStartEntity(const char *entity_name, const char *cmdline, void *pData); ErrorCodeEnum AsyncStopEntity(const char *entity_name, void *pData); instructionsServerConnection *m_pConnection; CSimpleStringA m_strTerminalNo; //终端号 unsigned int m_RecordNum; //当前终端号对应的任务记录数 ConnectService_ClientBase *m_pConnectService; protected: }; class instructionsServerConnection : public SpSecureClient { public: instructionsServerConnection(CEntityBase *pEntity, HolderContextFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM) {} virtual ~instructionsServerConnection() {} void SendHolderStateReq() { HolderStateReqEx req={0}; //标识用于重传的标识ID int countID = 1; // 压力测试 // for(int i = 0; i < 100; ++ i) // { //增加HolderID不为空以及空格的判断 if(m_pFSM->m_HolderState.HolderID.GetLength() > 2) { memcpy(req.HolderID, m_pFSM->m_HolderState.HolderID, m_pFSM->m_HolderState.HolderID.GetLength()); Dbg("@wb req.HolderID%s", req.HolderID); memcpy(req.TerminalNo, m_pFSM->m_HolderState.TerminalNo, 10); memcpy(req.State,m_pFSM->m_HolderState.State, 1); //add code by @wb //获取唯一的序列号 CUUID m_uid = CUUID::Create(m_uid); memcpy(req.SerialNumber, m_uid.ToString(), strlen( m_uid.ToString())); Dbg("@wb req.SerialNumber%s", req.SerialNumber); char ID[4] = {0}; sprintf(ID, "%d", countID); memcpy(req.SerialID, ID, strlen(ID)); Dbg("SerialID %s", req.SerialID); ////获取时间戳 char time[16] = {0}; long tc = GetTickCount(); //sprintf(time, "%dl", tc); ltoa(tc, time, 10); memcpy(req.dwNow, time, strlen(time)); Dbg("@wb req.dwNow%s ", req.dwNow); CSmartPointer pkt = CreateNewPackage("StaReqEx"); pkt->AddStruct("HolderStateReqEx", false, false, (LPBYTE)&req, sizeof(HolderStateReqEx)); if (SendPackage(pkt) == "") { Dbg("SendPackage failed, send [%s] sate[%s] failed", req.HolderID, req.State); m_pFSM->SetErrMsg(ERR_SEND_REQ,"上报持有者状态失败"); return; } else { Dbg("send holder[%s] sate[%s] success", req.HolderID, req.State); EnterCriticalSection(&m_pFSM->cs); Dbg("push the req to reqStateVec"); m_pFSM->reqStateVec.push_back(req); if(_strnicmp(req.State, "N", strlen("N")) != 0) { Dbg("push the req to hdStateReqVec"); m_pFSM->hdStateReqVec.push_back(req); } LeaveCriticalSection(&m_pFSM->cs); Dbg("tmp->hsReq %s",req.SerialNumber); Dbg("send holder[%s] sate[%s] success", req.HolderID, req.State); } } // } } void reSendHdStateReq(HolderStateReqEx req) { CSmartPointer pkt = CreateNewPackage("StaReqEx"); pkt->AddStruct("HolderStateReqEx", false, false, (LPBYTE)&req, sizeof(HolderStateReqEx)); //reSend上报状态 if (SendPackage(pkt) == "") { Dbg("reSendPackage failed, send [%s] sate[%s] failed", req.HolderID, req.State); m_pFSM->SetErrMsg(ERR_SEND_REQ,"重新上报持有者状态失败"); return; } else { EnterCriticalSection(&m_pFSM->cs); Dbg("push the req to reqStateVec"); m_pFSM->reqStateVec.push_back(req); if(_strnicmp(req.State, "N", strlen("N")) != 0) { Dbg("push the req to hdStateReqVec"); m_pFSM->hdStateReqVec.push_back(req); } LeaveCriticalSection(&m_pFSM->cs); Dbg("reSend holder[%s] sate[%s] SerialNumber[%s] success", req.HolderID, req.State, req.SerialNumber); Dbg("m_pFSM->reqStateVec.size() %d", m_pFSM->reqStateVec.size()); } } void SendMessageReq() { MessageReq req = {0}; Dbg("SendMessageReq, HolderID:%s", m_pFSM->m_HolderState.HolderID); memcpy(req.AgentID, m_pFSM->m_HolderState.HolderID, m_pFSM->m_HolderState.HolderID.GetLength()); //memcpy(req.MessageID, 0, 8);//消息ID设为0,全部取 TODO:为什么此处会导致lost CSmartPointer pkt = CreateNewPackage("MesReq"); pkt->AddStruct("MessageReq", false, false, (LPBYTE)&req, sizeof(MessageReq)); if (SendPackage(pkt) == "") { Dbg("SendPackage failed, send [%s] MesReq failed", req.AgentID); m_pFSM->SetErrMsg(ERR_SEND_REQ,"发送连线任务请求失败"); return; } else { Dbg("send holder[%s] MesReq success", req.AgentID); } } DWORD SendHolderSkillReq() { HolderSkillReq req = {0}; //消息ID设为0,全部取 CSimpleStringA strAgentID = "SP"; strAgentID += m_pFSM->m_HolderState.HolderID; memcpy(req.AgentID, strAgentID, strAgentID.GetLength()); CSmartPointer pkt = CreateNewPackage("HdSkiReq"); pkt->AddStruct("HolderSkillReq", false, false, (LPBYTE)&req, sizeof(HolderSkillReq)); if (SendPackage(pkt) == "") { Dbg("SendPackage failed, send holder skill req failed"); m_pFSM->SetErrMsg(ERR_SEND_REQ,"发送资质查询请求失败"); return ERR_SEND_REQ; } else { Dbg("send holder skill req success"); } auto pRetPkg = ReceivePackage(5); if (pRetPkg == NULL) { Dbg("ReceivePackage failed, don't revceive holder skill ans"); m_pFSM->SetErrMsg(ERR_RECIEVE_ANS,"接收资质查询响应失败"); return ERR_RECIEVE_ANS; } ErrorCodeEnum rc = Error_Succeed; DWORD dwSysCode, dwUserCode; string strErrMsg; CSimpleStringA strRetErrMsg; if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg)) { rc = (ErrorCodeEnum)dwSysCode; LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str()); strRetErrMsg = strErrMsg.c_str(); m_pFSM->SetErrMsg(rc, strRetErrMsg); return rc; } int nLen = pRetPkg->GetStructLen("HolderSkillAns"); if (nLen > 0) { BYTE *pBuf = new BYTE[nLen]; memset(pBuf, 0, nLen); int nArrayNum = 0; if (pRetPkg->GetStructData("HolderSkillAns", pBuf, &nLen, &nArrayNum)) { Dbg("收到HolderSkillAns"); FSMEvent *evt = new HolderSkillAnsEvent(pBuf, nLen); HolderSkillAnsEvent *ans = (HolderSkillAnsEvent *)evt; memcpy(m_pFSM->m_cHolderSkill,ans->m_reply.HolderSkill,128); /*CSimpleStringA strSkill = m_pFSM->m_cHolderSkill; Dbg("[%s]技能列表[%s]",strAgentID,strSkill.GetData());*/ delete evt; } else { m_pFSM->SetErrMsg(ERR_INVALID_ANS,"无效的资质查询响应"); Dbg("get invalid HolderSkillAns packet!"); return ERR_INVALID_ANS; } delete pBuf; return Error_Succeed; } else { Dbg("get GetStructLen len failed!"); return ERR_INVALID_ANS; } } void HandleHolderStateAns(const CSmartPointer &pRecvPkg) { ErrorCodeEnum rc = Error_Succeed; DWORD dwSysCode, dwUserCode; string strErrMsg; CSimpleStringA strRetErrMsg; Dbg("start recieve ans"); char SerialNum[64]; //struct HandleReqState tp; if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg)) { rc = (ErrorCodeEnum)dwSysCode; LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str()); strRetErrMsg = strErrMsg.c_str(); m_pFSM->SetErrMsg(rc, strRetErrMsg); return; } int nLen = pRecvPkg->GetStructLen("HolderStateAnsEx"); Dbg("start GetStructLen ans"); if (nLen > 0) { BYTE *pBuf = new BYTE[nLen]; memset(pBuf, 0, nLen); int nArrayNum = 0; Dbg("start GetStructLen ans >0"); if (pRecvPkg->GetStructData("HolderStateAnsEx", pBuf, &nLen, &nArrayNum)) { FSMEvent *evt = new HolderStateAnsEvent(pBuf, nLen); HolderStateAnsEvent *ans = (HolderStateAnsEvent *)evt; Dbg("start GetStruct nRet %s", ans->m_reply.nRet); if (0 == ans->m_reply.nRet) { Dbg("HolderStateAnsEx return ok!"); //处理分行服务端的回包 ,将reqStateVec中对应的发包进行删除 memcpy(SerialNum, ans->m_reply.SerialNumber, 64); Dbg("SerialNum is %s", SerialNum); EnterCriticalSection(&m_pFSM->cs); Dbg("m_pFSM->reqStateVec.size() %d", m_pFSM->reqStateVec.size()); int m_size = m_pFSM->reqStateVec.size(); for (int i = m_size-1; i >= 0; i --) { if(strncmp((m_pFSM->reqStateVec)[i].SerialNumber, SerialNum, 64) == 0) { Dbg("(m_pFSM->reqStateVec)[i].hsReq->SerialNumber %s", (m_pFSM->reqStateVec)[i].SerialNumber); (m_pFSM->reqStateVec).erase((m_pFSM->reqStateVec).begin()+i); Dbg("m_pFSM->reqStateVec %d", m_pFSM->reqStateVec.size()); //m_size --; } } LeaveCriticalSection(&m_pFSM->cs); } else { Dbg("HolderStateAnsEx return failed!"); } delete evt; } else { Dbg("get invalid HolderStateAnsEx packet!"); } delete pBuf; // return; } return; } void HandleIncomeHangupTask() { m_pFSM->HangupTask(); //add广播客户端主动挂断eMsg_incomeHangup消息 Connecting e; SpSendBroadcast(m_pEntity->GetFunction(),eMsg_incomeHangup , eMsgSig_incomeHangup, e); Dbg("SpSendBroadcast eMsg_incomeHangup"); } //add code by @wb //接收分行推送指令处理 void RecieveInstruction(const CSmartPointer &pRecvPkg) { ErrorCodeEnum rc = Error_Succeed; DWORD dwSysCode, dwUserCode; string strErrMsg; CSimpleStringA strRetErrMsg; InstrReqEx m_req; InstrAnsEx ans = {0}; if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg)) { rc = (ErrorCodeEnum)dwSysCode; LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str()); strRetErrMsg = strErrMsg.c_str(); m_pFSM->SetErrMsg(rc, strRetErrMsg); return; } //获取指令Req int nLen = pRecvPkg->GetStructLen("InsReqEx"); if (nLen > 0) { BYTE *pBuf = new BYTE[nLen]; memset(pBuf, 0, nLen); int nArrayNum = 0; if (pRecvPkg->GetStructData("InsReqEx", pBuf, &nLen, &nArrayNum)) { memcpy(&m_req, pBuf, sizeof(InstrReqEx)); if (_strnicmp(m_req.InstrType, "O", strlen("O")) == 0) { //连线任务(O) Dbg("收到连线任务"); memcpy(m_pFSM->m_cTaskData, m_req.CommandParam, 256); m_pFSM->SetHolderState("R");//进入振铃状态 m_pFSM->m_bIncomeHangup = FALSE; } else if (_strnicmp(m_req.InstrType, "I", strlen("I")) == 0) { //用户信息(I) Dbg("收到用户信息"); } else if (_strnicmp(m_req.InstrType, "L", strlen("L")) == 0) { //现场求助任务(L) Dbg("收到现场求助任务指令"); } else if (_strnicmp(m_req.InstrType, "T", strlen("T")) == 0) { //现场转移任务(T) Dbg("收到现场转移任务"); } else if (_strnicmp(m_req.InstrType, "F", strlen("F")) == 0) { //流程任务(F) Dbg("收到流程任务"); } else if (_strnicmp(m_req.InstrType, "C", strlen("C")) == 0) { //取消任务(C) Dbg("收到取消任务"); m_pFSM->m_bIncomeHangup = TRUE; //执行挂断操作 HandleIncomeHangupTask(); } else if (_strnicmp(m_req.InstrType, "S", strlen("S")) == 0) { //框架指令(S) Dbg("收到框架指令"); } else if (_strnicmp(m_req.InstrType, "N", strlen("N")) == 0) { //没有任务(N) Dbg("当前用户没有任务"); } else { Dbg("收到指令类型无法识别,[%s]", m_req.InstrType); } //Sleep(5000); memcpy(ans.InstrucID, m_req.InstrucID, strlen(m_req.InstrucID)); ans.EvtCode = m_req.EvtCode; CSmartPointer pkt = CreateNewPackage("InsAnsEx"); pkt->AddStruct("InsAnsEx", false, false, (LPBYTE)&ans, sizeof(InstrAnsEx)); //发送指令回复包 if (SendPackage(pkt) == "") { Dbg("SendPackage failed, send InstrPush ans failed"); m_pFSM->SetErrMsg(ERR_SEND_REQ,"发送收到指令数据包失败"); } else { Dbg("send InstrPush ans success"); } } else { Dbg("get invalid RecieveInstruction packet!"); } delete pBuf; } return; } //接收到总行直接回复的状态确认包 void RecieveStateAns(const CSmartPointer &pRecvPkg) { ErrorCodeEnum rc = Error_Succeed; DWORD dwSysCode, dwUserCode; string strErrMsg; CSimpleStringA strRetErrMsg; HdStaAns m_ans = {0}; char SerialNum[64]; char State_value[10] = {0}; char Recover_state[10] = {0}; int m_size = m_pFSM->hdStateReqVec.size(); Dbg("hdStateReqVec size is %d ", m_size); if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg)) { rc = (ErrorCodeEnum)dwSysCode; LogError(Severity_Middle, rc, dwUserCode, strErrMsg.c_str()); strRetErrMsg = strErrMsg.c_str(); m_pFSM->SetErrMsg(rc, strRetErrMsg); return; } //获取总行状态回复HdStaAns int nLen = pRecvPkg->GetStructLen("HdStaAns"); if (nLen > 0) { BYTE *pBuf = new BYTE[nLen]; memset(pBuf, 0, nLen); int nArrayNum = 0; if (pRecvPkg->GetStructData("HdStaAns", pBuf, &nLen, &nArrayNum)) { //同步总行状态 memcpy(&m_ans, pBuf, sizeof(HdStaAns)); //获取唯一标识 memcpy(SerialNum, m_ans.SerialNumber, 64); Dbg("HdStaAns SerialNum is %s", SerialNum); memcpy(State_value, m_ans.State, 1); Dbg("HdStaAns state is %s", State_value); if(_strnicmp(State_value, "N", strlen("N")) != 0) { m_pFSM->recvState.push_back(State_value[0]); } int n_size = m_pFSM->recvState.size(); Dbg("recvState size %d", n_size); EnterCriticalSection(&m_pFSM->cs); Dbg("StateAnsNum size%d", m_pFSM->StateAnsNum.size()); if(m_pFSM->StateAnsNum.size() == 0) { Dbg("push the state %s for StateAnsNum!", State_value); EnterCriticalSection(&m_pFSM->cs); m_pFSM->StateAnsNum.push_back(State_value[0]); LeaveCriticalSection(&m_pFSM->cs); } else { Dbg("compare the state%c", State_value[0]); Dbg("compare the StateAnsNum state%c", (m_pFSM->StateAnsNum)[0]); if(State_value[0] == ((m_pFSM->StateAnsNum)[0])) { //避免数组出现越界 if(_strnicmp(State_value, "N", strlen("N")) == 0) { if(n_size > 0) { //恢复成离线前的状态 Dbg("Recover_state state is %c", (m_pFSM->recvState)[n_size-1]); Dbg("Recover State from central server and Set HolderState to %c state!", (m_pFSM->recvState)[n_size-1]); char tmp[2]; tmp[0] = (m_pFSM->recvState)[n_size-1]; tmp[1] = '\0'; m_pFSM->SetHolderState(tmp); EnterCriticalSection(&m_pFSM->cs); m_pFSM->recvState.clear(); LeaveCriticalSection(&m_pFSM->cs); } else { m_pFSM->SetHolderState("S"); } } else { Dbg("Update State from central server and Set HolderState to %s state!", State_value); m_pFSM->SetHolderState(State_value); } } //有无同步状态都需要清空StateAnsNum存储的state value m_pFSM->StateAnsNum.clear(); } //说明与总行连接没有问题,直接清空所有积累的包 //m_pFSM->hdStateReqVec.clear(); Dbg("hdStateReqVec size is %d", m_size); //说明和总行连接没有问题,删除所有拥有相同state的数据包 for (int i = m_size-1; i >= 0; i --) { if(strncmp((m_pFSM->hdStateReqVec)[i].State, State_value, 1) == 0) { Dbg("(Remove m_pFSM->hdStateReqVec)[i].State is %s", (m_pFSM->hdStateReqVec)[i].State); (m_pFSM->hdStateReqVec).erase((m_pFSM->hdStateReqVec).begin()+i); } } LeaveCriticalSection(&m_pFSM->cs); } delete pBuf; } return; } //add code by @wb //断开分行服务连接 void handleDisconnect() { this->Close(); this->DecRefCount(); } protected: virtual void OnPkgAnswer(const CSmartPointer &pRecvPkg) { string serviceCode = pRecvPkg->GetServiceCode(); Dbg("start OnReceivePackage, serviceCode[%s]",serviceCode.c_str()); if (serviceCode == "StaReqEx") { HandleHolderStateAns(pRecvPkg); } //add code by @wb //处理指令req else if(serviceCode == "InsReqEx") { RecieveInstruction(pRecvPkg); } else if(serviceCode == "HdStaAns") { RecieveStateAns(pRecvPkg); } else { Dbg("unknown service code!"); //OnDisconnect(); } }; virtual void OnReceivePackage(IPackage *pRecvPkg) { } private: HolderContextFSM *m_pFSM; };