#include "stdafx.h" #include "windows.h" #include "HolderContextFSM.h" #include "..\EventCode.h" #define OP_START_ENTITY 1 #define OP_STOP_ENTITY 0 struct callback_entry : public IReleasable { virtual ~callback_entry() {} CSimpleStringA EntityName; union { void *pRawData; int state; }; int op; ErrorCodeEnum ErrorResult; }; namespace StateTask{ //add code by @wb //定时上报持有者状态 struct ReportStateTask : public ITaskSp { HolderContextFSM* fsm; explicit ReportStateTask(HolderContextFSM* f) : fsm(f) {} void Process() { Dbg("@wb TimerUploadHolderState init"); while(1) { Dbg("@wb m_bLogon%d",fsm->m_bLogon); //持有者从签入到签出时间之内,定期上报一次状态 if (fsm->m_bLogon) { Dbg("@wb TimerUploadHolderState m_bLogon"); if (!fsm->UploadHolderState()) { Dbg("TimerUploadHolderState failed!"); //将业务层状态置为N,避免分行断开服务时,无效呼入 /* Sleep(FIX_SETSTATE_TIMER); EnterCriticalSection(&fsm->cs); Dbg("Set HolderState to N state!"); fsm->SetHolderState("N"); LeaveCriticalSection(&fsm->cs); Sleep(FIX_SETSTATE_TIMER); */ Sleep(FIX_SETSTATE_TIMER_1); EnterCriticalSection(&fsm->cs); Dbg("Set HolderState to N State!"); fsm->SetHolderState("N"); LeaveCriticalSection(&fsm->cs); Sleep(FIX_SETSTATE_TIMER_1); } } Dbg("@wb TimerUploadHolderState Sleep"); //定时时间 Sleep(FIX_UPLOAD_TIMER); } } }; struct HandlePackageTask : public ITaskSp { HolderContextFSM* fsm; explicit HandlePackageTask(HolderContextFSM* f) : fsm(f) {} //依据reqStateVec中未确认包个数和时戳来实现重传与确认机制 void Process() { Dbg("@wb enter before Thread for retransmit"); while(1) { if (fsm->m_bLogon) { // 记录当前时间 long indexNow; //记录标识 int countID = 1; // 统计个数判断是否需要断开连接后重连 EnterCriticalSection(&fsm->cs); Dbg("@wb indentified values for retransmit"); //针对分行 int count = fsm->reqStateVec.size(); Dbg("count %d", count); //针对总行 int countN = fsm->hdStateReqVec.size(); Dbg("countN %d", countN); //针对recvState int countRecSta = fsm->recvState.size(); //超出 最大个数进行清空list,关闭与分行连接,重新连接的操作 if(count > PACKAGE_MAX_NUM) { Dbg("@wb Disconnect for retransmit"); fsm->Disconnect(); //执行清空操作 fsm->reqStateVec.clear(); //将业务层状态置为N,避免分行断开服务时,无效呼入 Dbg("Set HolderState to N state!"); EnterCriticalSection(&fsm->cs); fsm->SetHolderState("N"); LeaveCriticalSection(&fsm->cs); Dbg("@wb Reconnect for retransmit"); fsm->Reconnect(); LeaveCriticalSection(&fsm->cs); } else { //遍历进行超时重传 int m_size = fsm->reqStateVec.size(); Dbg("m_size %d", m_size); for (int i = 0; i < m_size; i ++) { Dbg("@wb GetTickCount for retransmit"); indexNow = GetTickCount(); //获取当前时间 Dbg("indexNow %d", indexNow); long timeRecord = 0; //存储状态上报包中的时间 Dbg("fsm->reqStateVec[i].dwNow %s",fsm->reqStateVec[i].dwNow); sscanf(fsm->reqStateVec[i].dwNow, "%d", &timeRecord ); Dbg("timeRecord %d", timeRecord); //出现超时进行重传,生成新的SerialID和当前时间 if((indexNow - timeRecord) > FIX_DWTICK_TIMER) { countID ++; Dbg("countID%d", countID); sprintf(fsm->reqStateVec[i].SerialID, "%d", countID); char time[16] = {0}; ltoa(indexNow, time, 10); memcpy(fsm->reqStateVec[i].dwNow, time, strlen(time)); Dbg("@wb retransmit req success!"); if(!fsm->ReTransmissReq(fsm->reqStateVec[i])) { Dbg("retransmit req not success!"); } else Dbg("retransmit req success!"); } } } if(countN >= PACKAGE_MAX_NUM) { //将业务层状态置为N,避免总行断开服务时,无效呼入 Dbg("Set HolderState to N state!"); EnterCriticalSection(&fsm->cs); fsm->SetHolderState("N"); LeaveCriticalSection(&fsm->cs); Dbg("Clear all the hdStateReqVec element!"); fsm->hdStateReqVec.clear(); } if(countRecSta >= RECV_MAX_NUM) { fsm->recvState.clear(); } LeaveCriticalSection(&fsm->cs); } Dbg("@wb Sleep retransmit!"); Sleep(FIX_CHECK_LIST_TIMER); } } }; } using namespace StateTask; class HolderContextFSM; HolderContextFSM::HolderContextFSM():m_pConnection(NULL) { m_HolderState.State = "N";//默认持有者状态,N m_pConnectService = NULL; m_bLogon = FALSE; m_nErrcode = Error_Succeed; m_strErrmsg = ""; m_bHolderBusy = FALSE; m_bMenu = TRUE; m_CurCallState = "O"; m_bIncomeHangup = FALSE; memset(m_cTaskData, 0, 1024); memset(m_cHolderSkill, 0, 128); } HolderContextFSM::~HolderContextFSM() { } void HolderContextFSM::OnStateTrans( int iSrcState, int iDstState ) { Dbg("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState)); } void HolderContextFSM::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName ) { } ErrorCodeEnum HolderContextFSM::OnInit() { ErrorCodeEnum Error; Error = LoadRootConfig(); if (Error != Error_Succeed) { LOG_TRACE("load root.ini config failed!"); return Error; } Dbg("LoadRootConfig ok, m_strMachineType[%s],m_strSite[%s]",m_strMachineType.GetData(),m_strSite.GetData()); if (Error == Error_Succeed) { AddStateHooker(this); } //add广播界面退出通知消息eMsg Connecting e; SpSendBroadcast(m_pEntity->GetFunction(), eMsg_exitRecordUI , eMsgSig_exitRecordUI , e); Dbg("SpSendBroadcast eMsgexitRecordUI"); InitializeCriticalSection(&cs); //获取终端号 CSystemStaticInfo si; m_pEntity->GetFunction()->GetSystemStaticInfo(si); m_strTerminalNo = si.strTerminalID; Dbg("Get TerminalId[%s] from root.ini",m_strTerminalNo); m_HolderState.TerminalNo = m_strTerminalNo; //初始化分行、总行状态发送记录vector reqStateVec.reserve(1000); hdStateReqVec.reserve(1000); StateAnsNum.reserve(10); recvState.reserve(1000); recvState.push_back('S'); //add code by @wb //创建定时上报状态线程 ReportStateTask* pReportTask = new ReportStateTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(pReportTask); Dbg("task1 created"); //add code by @wb //创建处理状态上报确认线程 HandlePackageTask* pHandleTask = new HandlePackageTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(pHandleTask); Dbg("task2 created"); //...... return Error; } ErrorCodeEnum HolderContextFSM::OnExit() { DeleteCriticalSection(&cs); return Error_Succeed; } /* 状态上报规则 1.None、Identified、NotHeld为客户不在现场,用户不在现场的状态无需更新用户状态 2. */ void HolderContextFSM::s0_on_entry() { Dbg("enter s0[None]!"); m_HolderState.State = "N"; //Sleep(15000); //非Pad,不需要上报状态 if (0 != strcmp(m_strMachineType.GetData(), MACHINETYPE_PAD)) { Dbg("非Pad,无需状态上报!"); return; } ////开始获取用户状态 //BOOL bRet = GetHolderState(); //if (!bRet) //{ //} //Dbg("when s0_on_entry, start get hodler state!"); //Test //if (1) //{ // m_HolderState.HolderID = "074168"; // //m_HolderState.State = "S"; // //UploadHolderState(); // //Test,进入Standby状态 // //PostEventLIFO(new FSMEvent(USER_EVT_JMP_STANDBY)); //} //Test /*m_HolderState.HolderID = "00210706"; QueryHolderSkill();*/ ScheduleTimer(1, 1000); } void HolderContextFSM::s0_on_exit() { CancelTimer(1); } unsigned int HolderContextFSM::s0_on_event( FSMEvent* event ) { Connecting e; switch (event->iEvt) { case EVT_TIMER: ScheduleTimer(1, 1000); //没有收到状态循环等待 break; case USER_EVT_JMP_IDENTIFIED: //进入S1:Identified状态 Dbg("s0_on_event, recieve USER_EVT_JMP_IDENTIFIED, go to S1!"); break; case USER_EVT_JMP_STANDBY: //进入S3:Standby状态 Dbg("s0_on_event, recieve USER_EVT_JMP_STANDBY, go to S3!"); //add广播 eMsg_OnlineStandBy为S的消息 SpSendBroadcast(m_pEntity->GetFunction(), eMsg_OnlineStandBy, eMsgSig_OnlineStandBy, e); Dbg("SpSendBroadcast eMsg_OnlineStandBy"); break; case USER_EVT_JMP_BUSY: //进入S5:Busy状态 Dbg("s0_on_event, recieve USER_EVT_JMP_BUSY, go to S5!"); //add广播Busy消息 SpSendBroadcast(m_pEntity->GetFunction(), eMsg_OnlineBusy, eMsgSig_OnlineBusy, e); Dbg("SpSendBroadcast eMsg_OnlineBusy"); break; default: Dbg("s0_on_event, recieve no defined event,[%d], continue wait!",event->iEvt); ScheduleTimer(1, 1000); break; } return 0; } //open console void HolderContextFSM::s1_on_entry() { //Identified,暂时不需要此状态 m_HolderState.State = "I"; Dbg("enter s1[Identified]"); ScheduleTimer(2, 1000); } void HolderContextFSM::s1_on_exit() { CancelTimer(2); } unsigned int HolderContextFSM::s1_on_event(FSMEvent* event) { if (event->iEvt == EVT_TIMER) { Dbg("s1_on_event, recieve timer, goto s0"); } return 0; } void HolderContextFSM::s2_on_entry() { //Unservice状态,暂时不需要此状态 Dbg("enter s2[Unservice]"); m_HolderState.State = "U"; if (!UploadHolderState()) { Dbg("UploadHolderState s2 failed!"); } ScheduleTimer(3, 1000); } void HolderContextFSM::s2_on_exit() { CancelTimer(3); } unsigned int HolderContextFSM::s2_on_event(FSMEvent* event) { if (event->iEvt == EVT_TIMER) { Dbg("s2_on_event, recieve timer, goto s0"); } return 0; } void HolderContextFSM::s3_on_entry() { Dbg("enter s3[Standby]"); //每次登录都重新下载任务, TODO:下载后怎么发起通话请求? //连线任务无需主动下载,其它任务待定 /*BOOL bRet = GetConnectTaskFromInstrationServer(); if (!bRet) { Dbg("从分行获取任务失败"); }*/ m_HolderState.State = "S"; if (!UploadHolderState()) { Dbg("UploadHolderState s3 failed!"); } } void HolderContextFSM::s3_on_exit() { CancelTimer(4); } unsigned int HolderContextFSM::s3_on_event(FSMEvent* event) { Connecting e; switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s3_on_event, recieve timer, go to S0!"); break; case USER_EVT_JMP_NOTHELD: //进入S4:NotHeld状态 Dbg("s3_on_event, recieve USER_EVT_JMP_IDENTIFIED, go to S4!"); break; case USER_EVT_JMP_BUSY: //进入S5:Busy状态 Dbg("s3_on_event, recieve USER_EVT_JMP_BUSY, go to S5!"); //add广播Busy消息 SpSendBroadcast(m_pEntity->GetFunction(), eMsg_OnlineBusy, eMsgSig_OnlineBusy, e); Dbg("SpSendBroadcast eMsg_OnlineBusy"); break; case USER_EVT_JMP_LOCAL: //进入S6:Local状态 Dbg("s3_on_event, recieve USER_EVT_JMP_LOCAL, go to S6!"); break; case USER_EVT_JMP_RINGING: //进入S8:Ringing状态 Dbg("s3_on_event, recieve USER_EVT_JMP_RINGING, go to S8!"); break; case USER_EVT_JMP_DISCONNECT: //进入S12:Disconnect状态 Dbg("s3_on_event, recieve USER_EVT_JMP_DISCONNECT, go to S12!"); break; case USER_EVT_JMP_NONE: //进入0:None状态 Dbg("s3_on_event, recieve USER_EVT_JMP_NONE, go to S0!"); //add广播 eMsg_Offline消息 SpSendBroadcast(m_pEntity->GetFunction(), eMsg_Offline, eMsgSig_Offline, e); Dbg("SpSendBroadcast eMsg_Offline"); break; default: Dbg("s3_on_event, recieve no defined event,[%d], continue wait!",event->iEvt); //ScheduleTimer(1, 1000); break; } return 0; } void HolderContextFSM::s4_on_entry() { Dbg("enter s4[NotHeld]"); //m_HolderState.State = "B";//对应什么状态值? if (!UploadHolderState()) { Dbg("UploadHolderState s4 failed!"); } } void HolderContextFSM::s4_on_exit() { CancelTimer(5); } unsigned int HolderContextFSM::s4_on_event(FSMEvent* event) { if (event->iEvt == EVT_TIMER) { Dbg("Verify cert err"); } return 0; } void HolderContextFSM::s5_on_entry() { Dbg("enter s5[Busy]"); m_HolderState.State = "B"; if (!UploadHolderState()) { Dbg("UploadHolderState s5 failed!"); } } void HolderContextFSM::s5_on_exit() { } unsigned int HolderContextFSM::s5_on_event(FSMEvent* event) { Connecting e; switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s5_on_event, recieve timer, go to S0!"); break; //add by zl 2017.12.08 case USER_EVT_JMP_NONE: Dbg("s5_on_event, recieve USER_EVT_JMP_NONE, go to S0!"); //add广播 eMsg_Offline消息 SpSendBroadcast(m_pEntity->GetFunction(), eMsg_Offline, eMsgSig_Offline, e); Dbg("SpSendBroadcast eMsg_Offline"); break; case USER_EVT_JMP_STANDBY: //进入S3:Standby状态 Dbg("s5_on_event, recieve USER_EVT_JMP_STANDBY, go to S3!"); //add广播 eMsg_OnlineStandBy为S的消息 SpSendBroadcast(m_pEntity->GetFunction(), eMsg_OnlineStandBy, eMsgSig_OnlineStandBy, e); Dbg("SpSendBroadcast eMsg_OnlineStandBy"); break; default: Dbg("s5_on_event, recieve no defined event,[%d], continue wait!",event->iEvt); //ScheduleTimer(1, 1000); break; } return 0; } void HolderContextFSM::s6_on_entry() { Dbg("enter s6[Local]"); m_HolderState.State = "L"; if (!UploadHolderState()) { Dbg("UploadHolderState s6 failed!"); } } void HolderContextFSM::s6_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s6_on_event(FSMEvent* event) { Dbg("s6_on_event"); return 0; } void HolderContextFSM::s7_on_entry() { Dbg("enter s7[Working]"); m_HolderState.State = "W"; if (!UploadHolderState()) { Dbg("UploadHolderState s7 failed!"); } } void HolderContextFSM::s7_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s7_on_event(FSMEvent* event) { Dbg("s7_on_event"); return 0; } void HolderContextFSM::s8_on_entry() { Dbg("enter s8[Ringing]"); m_HolderState.State = "R"; if (!UploadHolderState()) { Dbg("UploadHolderState s8 failed!"); } //给业务层广播振铃消息 Connecting e; SpSendBroadcast(m_pEntity->GetFunction(), eMsg_Ringing, eMsgSig_Ringing, e); Dbg("SpSendBroadcast eMsg_Ringing"); } void HolderContextFSM::s8_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s8_on_event(FSMEvent* event) { switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s8_on_event, recieve timer, go to S0!"); break; case USER_EVT_JMP_STANDBY: //进入S3:Standby状态 Dbg("s8_on_event, recieve USER_EVT_JMP_STANDBY, go to S3!"); break; case USER_EVT_JMP_BUSY: //进入S5:Busy状态 Dbg("s8_on_event, recieve USER_EVT_JMP_BUSY, go to S5!"); break; case USER_EVT_JMP_ONLINE: //进入S9:Online状态 Dbg("s8_on_event, recieve USER_EVT_JMP_ONLINE, go to S9!"); break; case USER_EVT_JMP_DEALING: //进入S10:Dealing状态 Dbg("s8_on_event, recieve USER_EVT_JMP_DEALING, go to S10!"); break; default: Dbg("s8_on_event, recieve no defined event, continue wait!"); //ScheduleTimer(1, 1000); break; } return 0; } void HolderContextFSM::s9_on_entry() { Dbg("enter s9[Online]"); //m_HolderState.State = "B";//对应什么状态值? if (!UploadHolderState()) { Dbg("UploadHolderState s9 failed!"); } } void HolderContextFSM::s9_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s9_on_event(FSMEvent* event) { switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s9_on_event, recieve timer, go to S0!"); break; case USER_EVT_JMP_DEALING: //进入S10:Dealing状态 Dbg("s9_on_event, recieve USER_EVT_JMP_DEALING, go to S10!"); break; case USER_EVT_JMP_EDIT: //进入S11:Edit状态 Dbg("s9_on_event, recieve USER_EVT_JMP_EDIT, go to S11!"); break; default: Dbg("s9_on_event, recieve no defined event, continue wait!"); //ScheduleTimer(1, 1000); break; } return 0; } void HolderContextFSM::s10_on_entry() { Dbg("enter s10[Dealing]"); m_HolderState.State = "D"; if (!UploadHolderState()) { Dbg("UploadHolderState s10 failed!"); } } void HolderContextFSM::s10_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s10_on_event(FSMEvent* event) { switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s10_on_event, recieve timer, go to S0!"); break; case USER_EVT_JMP_EDIT: //进入S11:Edit状态 Dbg("s10_on_event, recieve USER_EVT_JMP_EDIT, go to S11!"); break; default: Dbg("s10_on_event, recieve no defined event, continue wait!"); //ScheduleTimer(1, 1000); break; } return 0; } void HolderContextFSM::s11_on_entry() { Dbg("enter s11[Edit]"); m_HolderState.State = "E"; if (!UploadHolderState()) { Dbg("UploadHolderState s11 failed!"); } } void HolderContextFSM::s11_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s11_on_event(FSMEvent* event) { switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s11_on_event, recieve timer, go to S0!"); break; case USER_EVT_JMP_EDITEND: //进入S11:Edit状态 Dbg("s11_on_event, recieve USER_EVT_JMP_EDITEND, go to S11!"); break; default: Dbg("s11_on_event, recieve no defined event, continue wait!"); //ScheduleTimer(1, 1000); break; } return 0; } void HolderContextFSM::s12_on_entry() { Dbg("enter s12[Disconnect]"); m_HolderState.State = "D"; if (!UploadHolderState()) { Dbg("UploadHolderState s12 failed!"); } } void HolderContextFSM::s12_on_exit() { //CancelTimer(1); } unsigned int HolderContextFSM::s12_on_event(FSMEvent* event) { switch (event->iEvt) { case EVT_TIMER: //TODO:什么场景触发?又业务界面通知? Dbg("s12_on_event, recieve timer, go to S0!"); break; case USER_EVT_JMP_EDITEND: //进入S3:Standby状态 Dbg("s12_on_event, recieve USER_EVT_JMP_STANDBY, go to S11!"); break; default: Dbg("s12_on_event, recieve no defined event, continue wait!"); //ScheduleTimer(1, 1000); break; } return 0; } ErrorCodeEnum HolderContextFSM::LoadCenterConfig() { CSmartPointer spFunction = m_pEntity->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig); if (Error_Succeed == Error) { /*Error = spConfig->ReadConfigValueInt("MaintainWatcher", "CheckTerMinalNo", m_nCheckTerminalNo); if (Error_Succeed == Error) { Dbg("get CheckTerMinalNo=%d from CenterSetting.ini", m_nCheckTerminalNo); } else { Dbg("get CheckTerMinalNo from CenterSetting.ini failed"); } Error = spConfig->ReadConfigValueInt("MaintainWatcher", "CheckMaintainTask", m_nCheckMaintainTask); if (Error_Succeed == Error) { Dbg("get CheckMaintainTask=%d from CenterSetting.ini", m_nCheckMaintainTask); } else { Dbg("get CheckMaintainTask from CenterSetting.ini failed"); } Error = spConfig->ReadConfigValueInt("MaintainWatcher", "Verify_BlackList", m_nVerifyBlackList); if (Error_Succeed == Error) { Dbg("get Verify_BlackList=%d from CenterSetting.ini", m_nVerifyBlackList); } else { Dbg("get Verify_BlackList from CenterSetting.ini failed"); }*/ } return Error; } ErrorCodeEnum HolderContextFSM::LoadRootConfig() { CSmartPointer spFunction = m_pEntity->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum Error = spFunction->OpenConfig(Config_Root, spConfig); if (Error == Error_Succeed) { Error = spConfig->ReadConfigValue("Terminal", "MachineType", m_strMachineType); if(Error == Error_Succeed) { Error = spConfig->ReadConfigValue("Terminal", "Site", m_strSite); if (Error != Error_Succeed) { Dbg("ReadConfigValue, get Site value failed"); } } else { Dbg("ReadConfigValue, get MachineType value failed"); } } return Error; } //add code by @wb //上报持有者状态 BOOL HolderContextFSM::UploadHolderState() { EnterCriticalSection(&cs); if (!m_pConnection) { m_pConnection = new instructionsServerConnection(m_pEntity, this); if (m_pConnection) { if (!m_pConnection->ConnectFromCentralSetting()) { Dbg("connect instructions server fail,config or Servers Error!"); m_pConnection->handleDisconnect(); m_pConnection = NULL; LeaveCriticalSection(&cs); return FALSE; } } else { Dbg("UploadHolderState new instructionsServerConnection failed!"); LeaveCriticalSection(&cs); return FALSE; } } if (m_pConnection->IsConnectionOK()) { m_pConnection->SendHolderStateReq(); } else { //连接失败,关闭链接重连 if (NULL != m_pConnection) { m_pConnection->handleDisconnect(); m_pConnection = NULL; Dbg("Close m_pConnection"); } Dbg("connect to instructions server failed, can not update holder state!"); LeaveCriticalSection(&cs); return FALSE; } LeaveCriticalSection(&cs); return TRUE; } //add code by @wb //重传持有者状态确认包 BOOL HolderContextFSM::ReTransmissReq(HolderStateReqEx req) { EnterCriticalSection(&cs); if (!m_pConnection) { m_pConnection = new instructionsServerConnection(m_pEntity, this); if (m_pConnection) { if (!m_pConnection->ConnectFromCentralSetting()) { Dbg("connect instructions server fail,config or Servers Error!"); m_pConnection->handleDisconnect(); m_pConnection = NULL; LeaveCriticalSection(&cs); return FALSE; } } else { Dbg("UploadHolderState new instructionsServerConnection failed!"); LeaveCriticalSection(&cs); return FALSE; } } if (m_pConnection->IsConnectionOK()) { m_pConnection->reSendHdStateReq(req); } else { //连接失败,关闭链接重连 if (NULL != m_pConnection) { m_pConnection->handleDisconnect(); m_pConnection = NULL; Dbg("Close m_pConnection"); } Dbg("connect to instructions server failed, can not reSend holder state!"); LeaveCriticalSection(&cs); return FALSE; } LeaveCriticalSection(&cs); return TRUE; } //add code by @wb //断开与分行服务连接 void HolderContextFSM::Disconnect() { EnterCriticalSection(&cs); if (m_pConnection != NULL) { m_pConnection->handleDisconnect(); m_pConnection = NULL; Dbg("Close m_pConnection"); } LeaveCriticalSection(&cs); } //add code by @wb //重新与分行服务进行连接 void HolderContextFSM::Reconnect() { EnterCriticalSection(&cs); if (!m_pConnection) { m_pConnection = new instructionsServerConnection(m_pEntity, this); if (m_pConnection) { if (!m_pConnection->ConnectFromCentralSetting()) { Dbg("connect instructions server fail,config or Servers Error!"); m_pConnection->handleDisconnect(); m_pConnection = NULL; LeaveCriticalSection(&cs); } else { Dbg("connect instructions server success!"); } } else { Dbg("UploadHolderState new instructionsServerConnection failed!"); LeaveCriticalSection(&cs); } } if(m_pConnection->IsConnectionOK()) Dbg("Reconnect is success!"); else { //连接失败,关闭链接重连 if (NULL != m_pConnection) { m_pConnection->handleDisconnect(); m_pConnection = NULL; Dbg("Close m_pConnection"); } LeaveCriticalSection(&cs); } LeaveCriticalSection(&cs); } //发送连线请求 BOOL HolderContextFSM::SendConnectTask() { //调用陈晃提供的实体接口发起请求 ErrorCodeEnum eErr = Error_Succeed; ConnectService_StartCallExternal_Ans ans; ConnectService_StartCallExternal_Req req; req.CommandParam.Alloc(1024); memcpy(req.CommandParam.m_pData,m_cTaskData,1024); if (m_pConnectService == NULL) { m_pConnectService = new ConnectService_ClientBase(this->GetEntityBase()); eErr = m_pConnectService->Connect(); if (Error_Succeed != eErr) { Dbg("counter connector connected failed."); m_pConnectService = NULL; return FALSE; } else { Dbg("counter connector connected succeed."); } } //TODO:根据错误原因是否来决定是否重试,失败原因要及时通知总行 eErr = m_pConnectService->StartCallExternal(req, ans,10000); if (Error_Succeed != eErr) { Dbg("StartCallExternal failed."); m_pConnectService = NULL; return FALSE; } else { Dbg("StartCallExternal succeed"); } req.CommandParam.Clear(); return TRUE; } BOOL HolderContextFSM::HangupTask() { //TODO:调用陈晃提供的实体接口发起请求 ErrorCodeEnum eErr = Error_Succeed; ConnectService_StopCall_Ans ans; ConnectService_StopCall_Req req; req.SessionParam.Alloc(1024); memcpy(req.SessionParam.m_pData,m_cTaskData,1024); //TODO:根据错误原因是否来决定是否重试,失败原因要及时通知总行 if (m_pConnectService == NULL) { m_pConnectService = new ConnectService_ClientBase(this->GetEntityBase()); eErr = m_pConnectService->Connect(); if (Error_Succeed != eErr) { Dbg("counter connector connected failed."); m_pConnectService = NULL; return FALSE; } else{ Dbg("counter connector connected succeed!"); } } eErr = m_pConnectService->StopCall(req, ans,10000); if (Error_Succeed != eErr) { Dbg("StopCall failed."); m_pConnectService = NULL; return FALSE; } else { Dbg("StopCall succeed!"); } req.SessionParam.Clear(); return TRUE; } //查询持有人技能 DWORD HolderContextFSM::QueryHolderSkill() { EnterCriticalSection(&cs); if (!m_pConnection) { m_pConnection = new instructionsServerConnection(m_pEntity, this); if (!m_pConnection->ConnectFromCentralSetting()) { Dbg("connect instruction server fail,config or Servers Error!"); m_pConnection->handleDisconnect(); m_pConnection = NULL; LeaveCriticalSection(&cs); SetErrMsg(ERR_CONNECTSERVICE_FROM_CENTER,"根据集中配置连接指令服务失败"); return ERR_CONNECTSERVICE_FROM_CENTER; } } if (m_pConnection->IsConnectionOK()) { DWORD dwRet = m_pConnection->SendHolderSkillReq(); if (Error_Succeed == dwRet) { Dbg("send SendHolderSkillReq success"); } else { Dbg("send SendHolderSkillReq failed"); LeaveCriticalSection(&cs); return dwRet; } } else { //连接失败,关闭链接重连 if (NULL != m_pConnection) { m_pConnection->handleDisconnect(); m_pConnection = NULL; Dbg("Close m_pConnection"); } Dbg("connect to instructions server failed, can not get holder skill!"); LeaveCriticalSection(&cs); SetErrMsg(ERR_CONNECT,"网络异常,无法连接指令服务"); return ERR_CONNECT; } LeaveCriticalSection(&cs); return Error_Succeed; } //TODO:监控IEbrowser状态,如果为非Idle状态,持有者状态设置为“N”,但“N”状态不上报,怎么处理?(新加一个错误状态) //获取通话状态 BOOL HolderContextFSM::GetCallState() { //判断终端是否在业务界面首页,不在首页不弹出客户经理登录框 ErrorCodeEnum Error = GetEntityBase()->GetFunction()->GetSysVar("CallState",m_strCallstate); if (Error_NotExist == Error) { Dbg("CallState is not exist, errcode=%d!", Error); return FALSE; } else if (Error_Succeed != Error) { Dbg("Get CallState failed, errcode=%d!", Error); return FALSE; } else { /* "O", Offline "C", Connecting "H", HandFree "P", Pickup "B", Broken "F", Fail "R", Releasing */ ////Dbg("Get UIState success, m_strUIstate=%s!", m_strUIstate); //if ((-1 != FindSubStr(m_strUIstate, "M")) // || (-1 != FindSubStr(m_strUIstate, "A")) // || (-1 != FindSubStr(m_strUIstate, "T"))) //{ // //界面状态UIState。定义当前交互层所处的交互模式。有8种状态:目录浏览M、随机广告A、目标广告T、业务填单F、交易确认C、业务提交S、请求回报R、暂停响应Z。初始状态为M。 // //M、A、T三种状态都认为在首页 // //Dbg("At Menu status!"); // m_bMenu = TRUE; //} //else //{ // //不在首页 // //Dbg("Not at Menu status!"); // m_bMenu = FALSE; //} return TRUE; } } //获取持有者状态,TODO:增加系统变量HolderState BOOL HolderContextFSM::GetHolderState() { ErrorCodeEnum Error = GetEntityBase()->GetFunction()->GetSysVar("HolderState",(CSimpleStringA)m_HolderState.State); if (Error_NotExist == Error) { Dbg("HolderState is not exist, errcode=%d!", Error); return FALSE; } else if (Error_Succeed != Error) { Dbg("Get HolderState failed, errcode=%d!", Error); return FALSE; } else { /* "O", Offline "C", Connecting "H", HandFree "P", Pickup "B", Broken "F", Fail "R", Releasing */ ////Dbg("Get UIState success, m_strUIstate=%s!", m_strUIstate); //if ((-1 != FindSubStr(m_strUIstate, "M")) // || (-1 != FindSubStr(m_strUIstate, "A")) // || (-1 != FindSubStr(m_strUIstate, "T"))) //{ // //界面状态UIState。定义当前交互层所处的交互模式。有8种状态:目录浏览M、随机广告A、目标广告T、业务填单F、交易确认C、业务提交S、请求回报R、暂停响应Z。初始状态为M。 // //M、A、T三种状态都认为在首页 // //Dbg("At Menu status!"); // m_bMenu = TRUE; //} //else //{ // //不在首页 // //Dbg("Not at Menu status!"); // m_bMenu = FALSE; //} return TRUE; } } //由业务层设置持有者状态 BOOL HolderContextFSM::SetHolderState(CSimpleStringA strState) { Dbg("SetHolderState[%s]", strState); string State = strState; //根据的状态值发送事件跳转到相应的状态机 if ("S" == State) { //就绪(S) PostEventLIFO(new FSMEvent(USER_EVT_JMP_STANDBY)); } else if ("B" == State) { //示忙(B) PostEventLIFO(new FSMEvent(USER_EVT_JMP_BUSY)); } else if ("R" == State) { //振铃(R) PostEventLIFO(new FSMEvent(USER_EVT_JMP_RINGING)); } else if ("E" == State) { //会话整理(E) PostEventLIFO(new FSMEvent(USER_EVT_JMP_EDIT)); } else if ("N" == State) { //未绑定(N),签出时处于此状态 PostEventLIFO(new FSMEvent(USER_EVT_JMP_NONE)); } else { Dbg("SetHolderState failed, unkonwn state value"); return FALSE; } return TRUE; } //校验持有者技能 DWORD HolderContextFSM::CheckHolderRights() { //add by zl 20170811 暂时放开远程服务资质校验 return Error_Succeed; //获取权限 /*DWORD dwRet = QueryHolderSkill(); if (Error_Succeed != dwRet) { return dwRet; } //校验权限 CSimpleStringA strSkillList = m_cHolderSkill; Dbg("[%s]技能列表[%s]",m_HolderState.HolderID.GetData(),strSkillList.GetData()); if (-1 == FindSubStr(strSkillList, "ConnectService")) { SetErrMsg(ERR_NO_CONNECTRIGHT,"用户没有远程服务资质"); return ERR_NO_CONNECTRIGHT; } return Error_Succeed;*/ } //获取持有者信息 BOOL GetSAPFromUserInfo(const char *strHolderInfo, char *cSAP) { if (NULL == strHolderInfo || NULL == cSAP) { return FALSE; } string strUserInfo = strHolderInfo; int len = strUserInfo.length(); int nPos = strUserInfo.find("SAP="); if (nPos < 0) { return FALSE; } string strRecord = strUserInfo.substr(nPos, len-1); nPos = strRecord.find_first_of(";"); if (nPos < 0) { return FALSE; } string strUserIDRecord = strRecord.substr(0, nPos); if (strUserIDRecord.length() <= 4) { return FALSE; } string userID = strUserIDRecord.substr(4,nPos -4); memcpy(cSAP, userID.c_str(), 8); return TRUE; } BOOL GetAgentIDFromUserInfo(const char *strHolderInfo, char *cAgentID) { if (NULL == strHolderInfo || NULL == cAgentID) { return FALSE; } string strUserInfo = strHolderInfo; int len = strUserInfo.length(); int nPos = strUserInfo.find("UserID="); if (nPos < 0) { return FALSE; } string strRecord = strUserInfo.substr(nPos, len-1); nPos = strRecord.find_first_of(";"); if (nPos < 0) { return FALSE; } string strUserIDRecord = strRecord.substr(0, nPos); if (strUserIDRecord.length() <= 7) { return FALSE; } string userID = strUserIDRecord.substr(7,nPos -7); memcpy(cAgentID, userID.c_str(), 10); return TRUE; } BOOL HolderContextFSM::GetHolderMsg(CSimpleStringA strHolderInfo) { Dbg("GetHolderMsg success!"); m_strHolderInfo = strHolderInfo; //解析持有者信息 char cSAP[9] = {0}; if (!GetSAPFromUserInfo(m_strHolderInfo.GetData(),cSAP)) { Dbg("GetSAPFromUserInfo failed!"); return FALSE; } m_HolderState.HolderID = cSAP; Dbg("SAP=%s", m_HolderState.HolderID); //判断HolderID是否为空 add by zl 20171129 if (m_HolderState.HolderID.IsNullOrEmpty()) { Dbg("SAP is not exist!"); SetErrMsg(ERR_NO_CONNECTRIGHT,"当前用户没有SAP号"); return FALSE; } else { //PostEventLIFO(new FSMEvent(USER_EVT_JMP_STANDBY)); D:\BranchServer\RvcBranchServer1.9.5\RvcFramework.exe } return TRUE; } //查找子串 DWORD HolderContextFSM::FindSubStr(const char* source, const char* target) { unsigned int i,j; if (strlen(source) < strlen(target)) { return -1; } if (1 == strlen(source) && 1== strlen(target) && source[0] == target[0]) { return 0; } for (i = 0;i<=strlen(source)-strlen(target);i++) { if (source[i]==target[0]) { for (j = 1;j<=strlen(target);j++) { if (source[i+j]!=target[j]) break; } if ((j == strlen(target)) || (j == strlen(target)+1)) { return i; } j = 0; } } return -1; } void HolderContextFSM::SetErrMsg(DWORD dwErrcode, CSimpleStringA strErrmsg) { m_nErrcode = dwErrcode; m_strErrmsg = strErrmsg; } //获取指定实体状态 BOOL HolderContextFSM::GetEntityState(CSimpleStringA strEntityName, int &nState) { ErrorCodeEnum eErr; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CEntityRunInfo acInfo; eErr = pFunc->GetEntityRunInfo(strEntityName,acInfo); Dbg("[%s] state return %d",strEntityName, eErr); if (eErr == Error_Succeed) { nState = acInfo.eState; Dbg("[%s] state is [%d]", strEntityName, acInfo.eState); } else { Dbg("GetEntityRunInfo failed, errcode[%d]",eErr); } return TRUE; } ErrorCodeEnum HolderContextFSM::AsyncStartEntity(const char *entity_name, const char *cmdline, void *pData) { CSmartPointer pFunc = m_pEntity->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); if (pFuncPrivilege != NULL) { CSmartPointer spWait; ErrorCodeEnum Error = pFuncPrivilege->StartEntity(entity_name, cmdline, spWait); //if (Error == Error_Succeed) { // callback_entry *entry = new callback_entry(); // entry->pRawData = pData; // entry->EntityName = entity_name; // entry->ErrorResult = Error_Unexpect; // entry->op = OP_START_ENTITY; // //spWait->SetCallback(this, entry); //}z return Error; } else { return Error_NoPrivilege; } } ErrorCodeEnum HolderContextFSM::AsyncStopEntity(const char *entity_name, void *pData) { CSmartPointer pFunc = m_pEntity->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); if (pFuncPrivilege != NULL) { CSmartPointer spWait; ErrorCodeEnum Error = pFuncPrivilege->StopEntity(entity_name, spWait); //if (Error == Error_Succeed) { // callback_entry *entry = new callback_entry(); // entry->pRawData = pData; // entry->EntityName = entity_name; // entry->ErrorResult = Error_Unexpect; // entry->op = OP_STOP_ENTITY; // //spWait->SetCallback(this, entry); //} return Error; } else { return Error_NoPrivilege; } }