// mod_systemcustomization.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "SpBase.h" #include "..\EventCode.h" #include "HolderContextFSM.h" #include "io.h" #include "HolderContext_server_g.h" #include "HolderContext_def_g.h" #include "../mod_MaintainWatcher/MaintainWatcher_msg_g.h" using namespace MaintainWatcher; using namespace HolderContext; //机型 #define MACHINE_TYPE_STAND2S "RVC.Stand2S" //站立式双屏 #define MACHINE_TYPE_STAND1S "RVC.Stand1S" //站立式单屏 #define MACHINE_TYPE_EMBED2S "RVC.Embed2S" //嵌墙式双屏 #define MACHINE_TYPE_EMBED1S "RVC.Embed1S" //嵌墙式单屏 #define MACHINE_TYPE_PAD "RVC.Pad" //携带式移动终端 #define MACHINE_TYPE_WALL "RVC.Wall" //挂壁式 //场所 #define SITE_LIB "cmb.LIB"//银行大堂内 #define SITE_SSB "cmb.SSB"//自助营业网点 #define SITE_FLB "cmb.FLB"//离行机器,银行业务为主界面,如企业,商场 #define SITE_LSS "cmb.LSS"//面向生活销售机,一般部署在小区,面向销售广告 #define SITE_SMM "cmb.SMM"//商场销售门户,放置在商场,多商户门户 class CHolderContextEntiy; class HolderContextSession : public HolderContext_ServerSessionBase { public: HolderContextSession(CHolderContextEntiy *pEntity): m_pEntity(pEntity) {} virtual ~HolderContextSession() {} virtual void Handle_SetHolderState(SpReqAnsContext::Pointer ctx); virtual void Handle_PickUp(SpReqAnsContext::Pointer ctx); virtual void Handle_Hangup(SpOnewayCallContext::Pointer ctx); virtual void Handle_CheckHolderRights(SpReqAnsContext::Pointer ctx); private: CHolderContextEntiy *m_pEntity; }; class CHolderContextEntiy : public CEntityBase, public ILogListener, public IBroadcastListener, public ISysVarListener { public: CHolderContextEntiy() {} virtual ~CHolderContextEntiy() {} virtual const char *GetEntityName() const { return "HolderContext"; } bool StrEqual(const char *s1, const char *s2,int len) { for (int i = 0; i < len; ++i) { if (toupper(s1[i]) != toupper(s2[i])) return false; } return true; } ErrorCodeEnum LoadRootConfig() { CSmartPointer spFunction = this->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum Error = spFunction->OpenConfig(Config_Root, spConfig); if (Error_Succeed == Error) { Error = spConfig->ReadConfigValue("Terminal", "MachineType", m_strMachineType); if(Error_Succeed == Error) { Error = spConfig->ReadConfigValue("Terminal", "Site", m_strSite); if(Error_Succeed != Error) { Dbg("ReadConfigValue Site failed"); } } else { Dbg("ReadConfigValue MachineType failed"); } } return Error; } void OnPreStart(CAutoArray strArgs,CSmartPointer pTransactionContext) { //MessageBox(0,NULL,NULL,0); Dbg("OnPreStart."); ErrorCodeEnum Error = Error_Succeed; //TODO:订阅持有者登录事件(电子钥匙验证通过事件),获取持有者信息 ErrorCodeEnum errorCode = Error_Succeed; CSystemStaticInfo StaticInfo; CSmartPointer spEntityFunction = GetFunction(); errorCode = spEntityFunction->GetSystemStaticInfo(StaticInfo); if (Error_Succeed != errorCode) { Dbg("GetSystemStaticInfo failed. %s",StaticInfo.strMachineType); return; } Dbg("GetSystemStaticInfo ok. %s",StaticInfo.strMachineType); if(0 == _stricmp(StaticInfo.strMachineType, "RVC.PAD")) { Dbg("pad."); CUUID m_SubIDHolderLogon; char cHolderInfo[2048] = {0}; errorCode = spEntityFunction->SubscribeBroadcast("MaintainWatcher", cHolderInfo, this, m_SubIDHolderLogon); if(errorCode != Error_Succeed) { LOG_TRACE("Subscribe MaintainWatcher evt failed 0x%x"); Dbg("Subscribe MaintainWatcher evt failed."); return; } Dbg("SubScribe MaintainWatcher status broadcast suc."); } if (__OnStart(Error_Succeed)!=Error_Succeed) { return; } // delete code //不订阅心跳实体的指令事件 /*Dbg("SubscribeLog."); 订阅心跳实体的指令事件 Error = GetFunction()->SubscribeLog(m_UUIDHeatbeat, this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_INC_VEDIO_CONNECTING, "HeartBeat", false) if (Error_Succeed != Error) { Dbg("SubScribe LOG_EVT_HEARTBEAT_CONSTRATCIONS failed."); }*/ Dbg("before Init."); Error = m_fsm.Init(this); Dbg("Init return %d",Error); pTransactionContext->SendAnswer(Error) ; } void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext) { __OnClose(Error_Succeed); pTransactionContext->SendAnswer(Error_Succeed); } //delete code void OnLog(const CAutoArray &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage) { /* if (dwUserCode == LOG_EVT_INC_VEDIO_CONNECTING) { //Dbg("recv log event from Heartbeat, Instruction[%s]", pszMessage); //add code by @wb Dbg("recv log event from Connect, Instruction[%s]", pszMessage); if (NULL != pszMessage) { m_fsm.HandleInstrution(pszMessage); } } */ if (strlen(pszMessage)>2) { CSimpleStringA str = pszMessage; if (str[str.GetLength()-2] == '\r' && str[str.GetLength()-1]=='\n') str[str.GetLength()-2] = 0; if (eLogType == Log_Error) str = CSimpleStringA::Format("[%s] %s || SysCode: 0x%X, UserCode: 0x%X\r\n", pszEntityName, (const char*)str, dwSysError, dwUserCode); else str = CSimpleStringA::Format("[%s] %s\r\n", pszEntityName, (const char*)str); } } void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName) { //"O", // Offline // "C", // Connecting // "H", // HandFree // "P", // Pickup // "B", // Broken // "F", // Fail // "R", // Releasing if (m_fsm.m_bHolderBusy) { Dbg("正在示忙状态"); return; } //过滤非手机呼pad模式的广播消息 if (FALSE == m_fsm.m_bIncomeHangup){ CSimpleStringA strValue; ErrorCodeEnum Error = this->GetFunction()->GetSysVar("CallType", strValue); if (Error == Error_Succeed) { if (strValue[0] == 'N') { return; } } } //通话状态 if (0 == _stricmp(pszKey, "CallState")) { Dbg("CallState from : %c to %c", pszOldValue[0], pszValue[0]); m_fsm.m_CurCallState = pszValue[0]; //除了offline状态对应“S”或“R”,其它通话状态都对应“B” if (pszValue[0] == 'O' || pszValue[0] == 'R') { /*if (m_fsm.m_bMenu) { Dbg("通话结束且首页状态,设置S状态"); m_fsm.SetHolderState("S"); }*/ //给业务层广播连接断开消息 Connecting e; SpSendBroadcast(this->GetFunction(), eMsg_DisConnect, eMsgSig_DisConnect, e); Dbg("SpSendBroadcast eMsg_DisConnect"); } else { if ((pszValue[0] == 'H')||(pszValue[0] == 'P')) { //给业务层广播连接成功消息 Connecting e; SpSendBroadcast(this->GetFunction(), eMsg_Connected, eMsgSig_Connected, e); Dbg("SpSendBroadcast eMsg_Connected"); } else if (pszValue[0] == 'C') { //给业务层广播正在连接消息 Connecting e; SpSendBroadcast(this->GetFunction(), eMsg_Connecting, eMsgSig_Connecting, e); Dbg("SpSendBroadcast eMsg_Connecting"); } Dbg("响应CallSate变化,设置为B状态!"); m_fsm.SetHolderState("B"); } //m_fsm.SetHolderState(pszValue); } else if (0 == _stricmp(pszKey, "UIState")) { Dbg("UIState from : %c to %c", pszOldValue[0], pszValue[0]); if (pszValue[0] == 'M' || pszValue[0] == 'A' || pszValue[0] == 'T' || pszValue[0] == 'X') { //界面状态UIState。定义当前交互层所处的交互模式。有8种状态:目录浏览M、随机广告A、目标广告T、业务填单F、交易确认C、业务提交S、请求回报R、暂停响应Z。初始状态为M。 //M、A、T三种状态都认为在首页 Dbg("首页状态!"); m_fsm.m_bMenu = TRUE; /*if (m_fsm.m_CurCallState == "O") { Dbg("首页状态且通话结束,设置S状态"); m_fsm.SetHolderState("S"); }*/ } else { m_fsm.m_bMenu = FALSE; } } else { Dbg("warning: unknown Sys var changed!"); } } virtual void OnBroadcastEvent(CUUID SubID, const char *pszEntityName,DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer) { UkeyVerifyEx fc; Dbg("%s,%d,%d",pszEntityName,dwMessageId,dwMessageSignature); if (_strnicmp(pszEntityName, "MaintainWatcher", strlen("MaintainWatcher")) == 0) { switch (dwMessageSignature) { case eMsgSig_UkeyInsert: Dbg("recieve MaintainWatcher eMsgSig_UkeyInsert"); break; case eMsgSig_UkeyPullOut: m_fsm.m_bLogon = FALSE; Dbg("recieve MaintainWatcher eMsgSig_UkeyPullOut"); break; case eMsgSig_UkeyVerifyEx: m_fsm.m_bLogon = TRUE; SpBuffer2Object(Buffer, fc); m_fsm.GetHolderMsg(fc.UserInfo); Dbg("recieve MaintainWatcher eMsg_UkeyVerify"); break; default: Dbg("recieve unknown MaintainWatcher entity Broadcast msg type"); break; } } } ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError) { CSmartPointer Func = GetFunction(); CSimpleStringA strValue; if (Func->RegistSysVarEvent("CallState", this)!=Error_Succeed) { Dbg("RegistSysVarEvent CallState Fail!"); } else { Func->GetSysVar("CallState", strValue); Dbg("RegistSysVarEvent CallState success,value=%s",strValue); m_fsm.m_HolderState.State = strValue; } return Error_Succeed; } ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError) { LOG_FUNCTION(); CSmartPointer Func = GetFunction(); Func->UnregistSysVarEvent("CallState"); Func->UnsubscribeBroadcast("MaintainWatcher"); //delete code //Func->UnsubscribeLog(m_UUIDHeatbeat); return Error_Succeed; } virtual bool IsService()const{return true;} virtual CServerSessionBase *OnNewSession(const char* /*pszRemoteEntityName*/, const char * /*pszParam*/){return new HolderContextSession(this);} public: HolderContextFSM m_fsm; private: //delete code //CUUID m_UUIDHeatbeat; CSimpleStringA m_strMachineType, m_strSite; bool m_bWow64, m_bPad, m_bFlb; }; void HolderContextSession::Handle_SetHolderState(SpReqAnsContext::Pointer ctx) { Dbg("On Handle_SetHolderState!"); ctx->Answer(Error_Succeed); // 告知中台已经收到状态设置 Dbg("业务界面设置状态[%s]", ctx->Req.state); if ("B" == ctx->Req.state) { Dbg("点击示忙!"); m_pEntity->m_fsm.m_bHolderBusy = TRUE; } else if ("S" == ctx->Req.state) { Dbg("点击示闲,或通话结束且退出业务界面!"); m_pEntity->m_fsm.m_bHolderBusy = FALSE; } m_pEntity->m_fsm.m_HolderState.State = ctx->Req.state; if (m_pEntity->m_fsm.SetHolderState(ctx->Req.state)) { Dbg("Handle_SetHolderState ok!"); } else { Dbg("Handle_SetHolderState failed!"); } } void HolderContextSession::Handle_PickUp(SpReqAnsContext::Pointer ctx) { Dbg("On Handle_PickUp!"); ctx->Answer(Error_Succeed); // 告知中台已经收到接听动作 if (m_pEntity->m_fsm.SendConnectTask()) { Dbg("Handle_PickUp ok!"); } else { Dbg("Handle_PickUp failed!"); } } void HolderContextSession::Handle_Hangup(SpOnewayCallContext::Pointer ctx) { Dbg("On Handle_Hangup!"); if (m_pEntity->m_fsm.HangupTask()) { Dbg("Handle_Hangup ok!"); } else { Dbg("Handle_Hangup failed!"); } } void HolderContextSession::Handle_CheckHolderRights(SpReqAnsContext::Pointer ctx) { Dbg("On Handle_CheckHolderRights!"); //检测权限是否足够,检测结果返回业务 DWORD dwRet = m_pEntity->m_fsm.CheckHolderRights(); if (Error_Succeed == dwRet) { Dbg("Handle_CheckHolderRights ok!"); ctx->Ans.Errcode = Error_Succeed; ctx->Ans.ErrMsg = ""; ctx->Answer(Error_Succeed); } else { Dbg("Handle_CheckHolderRights failed!"); ctx->Ans.Errcode = m_pEntity->m_fsm.m_nErrcode; ctx->Ans.ErrMsg = m_pEntity->m_fsm.m_strErrmsg; ctx->Answer(Error_Succeed); } return; } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CHolderContextEntiy) SP_END_ENTITY_MAP()