ソースを参照

Z991239-385 #comment 封装对终端状态更新的系统变量广播

gifur 5 年 前
コミット
e4f87497d0

+ 19 - 0
Common/SpBase.h

@@ -453,6 +453,11 @@ struct ISysVarListener
 		const char *pszValue,const char *pszOldValue,const char *pszEntityName)=0;
 };
 
+struct ITerminalStateChangedListener
+{
+	virtual void OnStateChanged(FrameworkStateEnum oldState, FrameworkStateEnum curState, const char* triggerEntity) = 0;
+};
+
 struct IBroadcastListener
 {
 	virtual void OnBroadcastEvent(CUUID SubID, const char *pszEntityName,DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer)=0;
@@ -655,6 +660,20 @@ struct IEntityFunction
 	/*if pszKey=NULL mean unregist all keys event*/
 	virtual ErrorCodeEnum UnregistSysVarEvent(const char *pszKey)=0;
 
+	/*!
+	 * @brief 
+	 * @param pListener the sub class boject pointer inherit ITerminalStateChangedListener and implement 
+	 *                OnStateChanged interface.
+	 * @return : Error_Succeed if regist successfully, other means failure.
+	 */
+	virtual ErrorCodeEnum RegistTerminalStateChangeEvent(ITerminalStateChangedListener* pListener) = 0;
+
+	/*!
+	 * @brief 
+	 * @return : Error_Succeed if unregist successfully
+	 */
+	virtual ErrorCodeEnum UnregistTerminalStateChangeEvent() = 0;
+
 	/**
 	 * every entity can broadcast messages, user entity can subscribe an entity's broadcast messages
 	 */

+ 132 - 0
Common/SpComm.hpp

@@ -0,0 +1,132 @@
+#ifndef _SP_COMM_H__
+#define _SP_COMM_H__
+
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#ifdef _WIN32
+#include <crtdbg.h>
+#endif //_WIN32
+
+namespace SP
+{
+
+	struct MachineFormat 
+	{
+		enum Site
+		{
+			CMB_UNKNOWN,
+			CMB_LIB,       /** 行内大堂*/
+			CMB_SSB,      /** 自助网点*/
+			CMB_LSS,      /** 生活销售机*/
+			CMB_FLB,      /** 离行机器*/
+			CMB_OSB,     /** 外拓PAD*/
+			CMB_SMM     /** 商户终端*/
+		};
+
+#define SITE_ENUM_TYPE(MACRO)	\
+		MACRO(LIB)\
+		MACRO(SSB)\
+		MACRO(LSS)\
+		MACRO(FLB)\
+		MACRO(OSB)\
+		MACRO(SMM)
+
+
+#define ENUM_MAP_CONVERT(elem) \
+	if (stricmp(lpcszSiteName, "CMB."#elem) == 0) return CMB_##elem;
+		/*!
+		 * convert cmb site name to enum type.
+		 */
+		static Site Str2Site(LPCSTR lpcszSiteName) 
+		{
+			if (lpcszSiteName == NULL || strlen(lpcszSiteName) == 0)
+				return CMB_UNKNOWN;
+			SITE_ENUM_TYPE(ENUM_MAP_CONVERT)
+			return CMB_UNKNOWN;
+		}
+
+#undef ENUM_MAP_CONVERT
+#define ENUM_MAP_CONVERT(elem) case CMB_##elem: return "CMB."#elem;
+
+		static LPCSTR Site2Str(Site site) {
+			switch (site) {
+				SITE_ENUM_TYPE(ENUM_MAP_CONVERT)
+			default:
+				break;
+			}
+			return "Unkown";
+		}
+
+		enum What 
+		{
+			RVC_UNKNOWN,
+			RVC_Stand2S,          /** 落地式大机*/
+			RVC_PAD,                /** PAD*/
+			RVC_Desk2S,           /** 低柜双屏*/
+			RVC_IL,                    /** 简版*/
+			RVC_Desk1S           /** 低柜一体机*/
+		};
+
+#define MACHINE_ENUM_TYPE(MACRO)	\
+		MACRO(Stand2S)\
+		MACRO(PAD)\
+		MACRO(Desk2S)\
+		MACRO(IL)\
+		MACRO(Desk1S)
+
+#undef ENUM_MAP_CONVERT
+#define ENUM_MAP_CONVERT(elem) \
+	if (stricmp(lpcszTypeName, "RVC."#elem) == 0) return RVC_##elem;
+		/*!
+		 * convert cmb site name to enum type.
+		 */
+		static What Str2Type(LPCSTR lpcszTypeName)
+		{
+			if (lpcszTypeName == NULL || strlen(lpcszTypeName) == 0)
+				return RVC_UNKNOWN;
+			MACHINE_ENUM_TYPE(ENUM_MAP_CONVERT)
+			return RVC_UNKNOWN;
+		}
+
+#undef ENUM_MAP_CONVERT
+#define ENUM_MAP_CONVERT(elem) case RVC_##elem: return "RVC."#elem;
+
+		static LPCSTR Type2Str(What what) {
+			switch (what) {
+				MACHINE_ENUM_TYPE(ENUM_MAP_CONVERT)
+			default:
+				break;
+			}
+			return "Unkown";
+		}
+	};
+
+
+
+	/** Leak Detector*/
+	namespace Perf
+	{
+
+		struct SPBASE_API LeakDetector
+		{
+			LeakDetector()
+			{
+#ifdef _WIN32
+				int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+				flag |= _CRTDBG_LEAK_CHECK_DF;
+				flag |= _CRTDBG_ALLOC_MEM_DF;
+				_CrtSetDbgFlag(flag);
+#endif //_WIN32
+			}
+			~LeakDetector()
+			{
+
+			}
+		};
+
+
+	}
+
+}
+
+#endif // _SP_COMM_H__

+ 7 - 6
Common/SpTest.h

@@ -64,17 +64,17 @@ do  {	\
 
 #else
 
-#define IFFAILRET(func) ((void *)0)
+#define IFFAILRET(func) ((void)0)
 
-#define IFFAILBREAK(func) ((void *)0)
+#define IFFAILBREAK(func) ((void)0)
 
-#define REQUIRE(expr) ((void *)0)
+#define REQUIRE(expr) ((void)0)
 
-#define CHECK(expr) ((void *)0)
+#define CHECK(expr) ((void)0)
 
-#define THROW_FATAL(fmt, ...) ((void *)0)
+#define THROW_FATAL(fmt, ...) ((void)0)
 
-#define THROW_ERROR(fmt, ...) ((void *)0)
+#define THROW_ERROR(fmt, ...) ((void)0)
 
 #endif
 
@@ -84,6 +84,7 @@ do  {	\
 #define CHECK_FALSE(expr)	\
 	CHECK(!(expr))
 
+
 /** Test Case */
 
 struct ITestCaseSuite 

+ 3 - 2
Common/precompile.h

@@ -5,13 +5,14 @@
 
 #include <WinSock2.h>
 #ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
+	#define WIN32_LEAN_AND_MEAN
 #endif //WIN32_LEAN_AND_MEAN
 #include <Mmsystem.h>
 #include <process.h>
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
 #include <crtdbg.h>
 #include <locale.h>
-#include <time.h>
 #endif // _WIN32
 
 #include <stdlib.h>

+ 22 - 1
module/mod_testSubscribe/mod_testSubscribe.cpp

@@ -14,9 +14,12 @@ class CLogSubscribeEntity : public CEntityBase
 	, public ISysVarListener
 	, public IBroadcastListener
 	, public ILogListener
+	, public ITerminalStateChangedListener
 {
 public:
-	CLogSubscribeEntity():m_logCalCount(NULL), m_bSysValUpdated(false){
+	CLogSubscribeEntity():m_logCalCount(NULL), m_bSysValUpdated(false)
+		, m_bTerminalStateChangedCheck(false)
+	{
 		m_logCalCount = new LogTypeSeverity[0x1000];
 		if (m_logCalCount) {
 			memset(m_logCalCount, 0, sizeof(LogTypeSeverity) * (0x1000));
@@ -71,6 +74,10 @@ public:
 		if (!m_bSysValUpdated) {
 			THROW_ERROR("Test SysValue Updated Failed!, entity: %s, key: %s", SYSVAL_CHANGED_ENTITY_NAME, SYSVAL_CHANGED_KEY_NAME);
 		}
+		if (!m_bTerminalStateChangedCheck) {
+			THROW_ERROR("Test terminal state changed Failed!");
+		}
+
 		GetFunction()->KillTimer(1);
 	}
 
@@ -168,10 +175,18 @@ public:
 		}
 	}
 
+	void OnStateChanged(FrameworkStateEnum oldState, FrameworkStateEnum curState, const char* triggerEntity)
+	{
+		Dbg("OnStateChanged:  from %s to %s trigged by %s", 
+			SpStrFrameworkState(oldState), SpStrFrameworkState(curState), triggerEntity);
+		m_bTerminalStateChangedCheck = true;
+	}
+
 private:
 	CUUID m_logSubUUID;
 	LogTypeSeverity* m_logCalCount;
 	BOOL m_bSysValUpdated;
+	BOOL m_bTerminalStateChangedCheck;
 
 	ErrorCodeEnum __onTest()
 	{
@@ -193,6 +208,12 @@ private:
 		Dbg("to listeren specified sys key: %s", SYSVAL_CHANGED_KEY_NAME);
 		IFFAILRET(GetFunction()->RegistSysVarEvent(SYSVAL_CHANGED_KEY_NAME, this));
 
+		Dbg("to listeren terminal state");
+		IFFAILRET(GetFunction()->RegistTerminalStateChangeEvent(this));
+		Dbg("to unregist listeren terminal state");
+		IFFAILRET(GetFunction()->UnregistTerminalStateChangeEvent());
+		Dbg("regist terminal state again.");
+		IFFAILRET(GetFunction()->RegistTerminalStateChangeEvent(this));
 #if 1
 		//after TestLogSender started, it schedules a timer fired 10s and send some log. This entity would catch it
 		//so here set a timer to confirm its validity, the interval must great than 10s.

+ 12 - 2
module/mod_validityVertifier/mod_validityVertifier.cpp

@@ -20,6 +20,7 @@ class CTestDeamon
 	, public IEntityStateListener
 	, public ILogListener
 	, public ICallbackListener
+	, public ITerminalStateChangedListener
 {
 public:
 	CTestDeamon() : _dwStartedTestEntities(0) { _arrTestEntities.Clear(); }
@@ -106,7 +107,7 @@ public:
 	virtual void OnStarted()
 	{
 		LOG_FUNCTION();
-
+		IFFAILBREAK(GetFunction()->RegistTerminalStateChangeEvent(this));
 		if (_testInfo.isTestMode) {
 			if (IS_SUCCEED(StartTestEntity())) {
 				//TestAllRegistedEntity();
@@ -199,6 +200,15 @@ public:
 		}
 	}
 
+	void OnStateChanged(FrameworkStateEnum oldState, FrameworkStateEnum curState, const char* triggerEntity)
+	{
+		Dbg("OnStateChanged:  from %s to %s trigged by %s",
+			SpStrFrameworkState(oldState), SpStrFrameworkState(curState), triggerEntity);
+		if (curState == FrameworkState_Running && _testInfo.isTestMode) {
+			TestAllRegistedEntity();
+		}
+	}
+
 	struct TestCallbackResult : public IReleasable
 	{
 		TestCallbackResult() :strEntityName(true), op(0) {}
@@ -254,7 +264,7 @@ private:
 
 	ErrorCodeEnum TestEntity(const char* lcpszEntityName)
 	{
-		Dbg("Test specified entity: %s", lcpszEntityName);
+		LogEvent(Severity_High, 0, CSimpleStringA::Format("Test specified entity: %s", lcpszEntityName));
 		auto pPriviFunc = GetFunction()->GetPrivilegeFunction();
 		CSmartPointer<IAsynWaitSp> waitSp;
 		auto ec = pPriviFunc->TestEntity(lcpszEntityName, Test_Examine, waitSp);

+ 26 - 3
spbase/SpEntity.cpp

@@ -51,7 +51,13 @@ static void var_callback(sp_var_listener_t *listener,
 	sp_env_t *env = sp_get_env();
 	sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, client_id);
 	if (ent) {
-		pListener->OnSysVarEvent(key, newstr, oldstr, ent->cfg->name);
+		if(strcmp(VAR_RSERVERD_KEY_TERM_STATE, key) != 0)
+			pListener->OnSysVarEvent(key, newstr, oldstr, ent->cfg->name);
+		else {
+			FrameworkStateEnum oldState = static_cast<FrameworkStateEnum>(atoi(oldstr));
+			FrameworkStateEnum newState = static_cast<FrameworkStateEnum>(atoi(newstr));
+			(static_cast<ITerminalStateChangedListener*>(user_data))->OnStateChanged(oldState, newState, ent->cfg->name);
+		}
 	}
 	else {
 		sp_dbg_warn("cannot found the entity by id: %d", client_id);
@@ -828,11 +834,15 @@ ErrorCodeEnum SpEntity::RegistSysVarEvent(const char *pszKey,ISysVarListener *pL
 {
 	int rc = 0;
 
-	if (!pszKey || !pListener)
+	if (!pszKey || strlen(pszKey) == 0 || !pListener)
 		return Error_Param;
 
 	sp_env_t *env = sp_get_env();
 	sp_var_listener_t **pp_var;
+
+	//if (strcmp(pszKey, VAR_RSERVERD_KEY_TERM_STATE) == 0)
+	//	return Error_NoPrivilege;
+
 	if (strcmp(pszKey, "*") != 0) {
 		sp_cfg_shell_sysevent_t *sysevent = sp_cfg_get_sysevent(env->cfg, pszKey);
 		if (!sysevent)
@@ -860,11 +870,14 @@ ErrorCodeEnum SpEntity::RegistSysVarEvent(const char *pszKey,ISysVarListener *pL
 
 ErrorCodeEnum SpEntity::UnregistSysVarEvent(const char *pszKey)
 {
-	if (!pszKey)
+	if (!pszKey || strlen(pszKey) == 0)
 		return Error_Param;
 
 	int rc = 0;
 
+	//if (strcmp(pszKey, VAR_RSERVERD_KEY_TERM_STATE) == 0)
+	//	return Error_NoPrivilege;
+
 	if (strcmp(pszKey, "*") != 0) {
 		sp_env_t *env = sp_get_env();
 		sp_cfg_shell_sysevent_t *sysevent = sp_cfg_get_sysevent(env->cfg, pszKey);
@@ -896,6 +909,16 @@ ErrorCodeEnum SpEntity::UnregistSysVarEvent(const char *pszKey)
 	return SpTranslateError(rc); 
 }
 
+ErrorCodeEnum SpEntity::RegistTerminalStateChangeEvent(ITerminalStateChangedListener* pListener)
+{
+	return RegistSysVarEvent(VAR_RSERVERD_KEY_TERM_STATE, (ISysVarListener*)(void*)((uintptr_t)pListener));
+}
+
+ErrorCodeEnum SpEntity::UnregistTerminalStateChangeEvent()
+{
+	return UnregistSysVarEvent(VAR_RSERVERD_KEY_TERM_STATE);
+}
+
 ErrorCodeEnum SpEntity::SendBroadcast(DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer)
 {
 	int rc;

+ 3 - 0
spbase/SpEntity.h

@@ -85,6 +85,9 @@ public:
 	virtual ErrorCodeEnum RegistSysVarEvent(const char *pszKey,ISysVarListener *pListener);
 	virtual ErrorCodeEnum UnregistSysVarEvent(const char *pszKey);
 
+	virtual ErrorCodeEnum RegistTerminalStateChangeEvent(ITerminalStateChangedListener* pListener);
+	virtual ErrorCodeEnum UnregistTerminalStateChangeEvent();
+
 	// evt bcast
 	virtual ErrorCodeEnum SendBroadcast(DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer);
 	virtual ErrorCodeEnum GetBroadcastReceivers(CAutoArray<BroadcastSubscribeInfo> &Subscribers);

+ 10 - 3
spbase/SpEntityPrivilege.cpp

@@ -1995,10 +1995,17 @@ ErrorCodeEnum SpEntityPrivilege::SetSysDebugLevel(const char *pszEntityName,Debu
 
 ErrorCodeEnum SpEntityPrivilege::RefreshFrameworkState(FrameworkStateEnum eState)
 {
+	int rc = Error_Succeed;
+	char n[12] = { '\0' };
 	sp_env_t* env = sp_get_env();
-	env->cfg->shell_ini->shell_state = (int)eState;
-	//TODO: broadcast
-	return Error_Succeed;
+	sp_cfg_t* cfg = env->cfg;
+	const int old_state = cfg->shell_ini->shell_state;
+	if (old_state != (int)eState) {
+		cfg->shell_ini->shell_state = eState;
+		_itoa(eState, n, 10);
+		rc = sp_var_client_set((sp_var_client_t*)m_var_client, VAR_RSERVERD_KEY_TERM_STATE, n, 0);
+	}
+	return SpTranslateError(rc);
 }
 
 ErrorCodeEnum SpEntityPrivilege::ShowOuputConsole()

+ 23 - 4
spbase/sp_cfg.cpp

@@ -6,6 +6,7 @@
 #include "sp_dir.h"
 #include "sp_dbg_export.h"
 #include "sp_env.h"
+#include "sp_var.h"
 
 #include "iniutil.h"
 #include "strutil.h"
@@ -645,11 +646,32 @@ static int shell_ini__load_mod_entity(sp_dir_t* dir, sp_cfg_shell_ini_t* shell,
 static int shell_ini__load_sysevent(sp_cfg_shell_ini_t* shell, const char* shell_ini_path, const char* shell_var_path)
 {
 	int rc = 0;
-	int i;
+	int i, index;
 	array_header_t* arr;
 
 	shell->arr_sysevent = shm_array_make(0, sizeof(sp_cfg_shell_sysevent_t*));
+	index = 0;
+	{
+		sp_cfg_shell_sysevent_t* sysevent = T_MALLOC_T(sp_cfg_shell_sysevent_t, 1);
+		memset(sysevent, 0, sizeof(sp_cfg_shell_sysevent_t));
+		sysevent->name = T_STRDUP(VAR_RSERVERD_KEY_TERM_STATE, 1);
+		sysevent->init_value[0] = '0', sysevent->init_value[1] = '\0';
+
+		sysevent->arr_owner_entity = shm_array_make(0, sizeof(sp_cfg_shell_entity_t*));
+		sp_cfg_shell_entity_t* owner_entity = find_entity(shell, "SpShell");
+		if (owner_entity) {
+			sp_dbg_debug("add framework level sys val: %s", VAR_RSERVERD_KEY_TERM_STATE);
+			SHM_ARRAY_PUSH(sysevent->arr_owner_entity, sp_cfg_shell_entity_t*) = owner_entity;
+			sysevent->idx = shell->arr_sysevent->nelts;
+			SHM_ARRAY_PUSH(shell->arr_sysevent, sp_cfg_shell_sysevent_t*) = sysevent;
+		} else {
+			sp_dbg_warn("cannot find specified entity for sys val: %s", VAR_RSERVERD_KEY_TERM_STATE);
+			destroy_sysevent(sysevent);
+		}
+	}
+	
 	arr = inifile_read_section_key_all(shell_ini_path, "SysEvent");
+
 	for (i = 0; i < arr->nelts; ++i) {
 		char tmp[1024], tmp2[1024];
 		char initVar[SP_CFG_MAX_SYSEVT_BUF];
@@ -1038,9 +1060,6 @@ static int load_shell_ini(sp_dir_t *dir, sp_cfg_shell_ini_t *shell, const sp_cfg
 			break;
 		}
 	}
-
-	shell->shell_state = (rc == 0) ? 1 /*booting*/: 3 /*breakdown*/;
-
 	return rc;
 }
 

+ 3 - 2
spbase/sp_var.c

@@ -240,7 +240,7 @@ static void listener_on_pkt_threadpool(threadpool_t *threadpool, void *arg)
 			int from_client_id;
 			char *key = NULL;
 			iobuffer_format_read(pkt, "4s", &from_client_id, &key);
-			if (listener->key[0] == '*' || _stricmp(key, listener->key) == 0) {
+			if ((listener->key[0] == '*' &&_stricmp(key, VAR_RSERVERD_KEY_TERM_STATE) != 0) || _stricmp(key, listener->key) == 0) {
 				char *old_value = NULL;
 				char *new_value = NULL;
 				iobuffer_format_read(pkt, "ss", &old_value, &new_value);
@@ -423,7 +423,8 @@ static int daemon_on_pkt(sp_svc_t *svc,int epid, int svc_id, int pkt_type, int p
 		daemon_lock(daemon);
 		for (i = 0; i < daemon->arr_listener->nelts; ++i) {
 			var_listener_entry* tmp = ARRAY_IDX(daemon->arr_listener, i, var_listener_entry*);
-			if (_stricmp(tmp->key, "*") == 0 || _stricmp(key, tmp->key) == 0) {
+			if ((_stricmp(tmp->key, "*") == 0 && _stricmp(key, VAR_RSERVERD_KEY_TERM_STATE) !=0)
+				|| _stricmp(key, tmp->key) == 0) {
 				iobuffer_t *copy_pkt;
 				if (i == daemon->arr_listener->nelts-1) {
 					copy_pkt = pkt;

+ 5 - 3
spbase/sp_var.h

@@ -9,6 +9,8 @@ extern "C" {
 
 #include "sp_uid.h"
 
+#define VAR_RSERVERD_KEY_TERM_STATE "{314A6884-6373-48AD-A800-AE8E866E3572}"
+
 /* variable support, sub/unsub notification support */
 
 typedef struct sp_var_client_t sp_var_client_t;
@@ -25,9 +27,9 @@ typedef void (*sp_var_on_change)(sp_var_listener_t *listener,
 								 void *user_data);
 
 // client
-int sp_var_client_create(sp_svc_t *svc, sp_var_client_t **p_client);
-void sp_var_client_destroy(sp_var_client_t *client);
-int sp_var_client_set(sp_var_client_t *client, const char *key, const char *str, int persist);
+SPBASE_API int sp_var_client_create(sp_svc_t *svc, sp_var_client_t **p_client);
+SPBASE_API void sp_var_client_destroy(sp_var_client_t *client);
+SPBASE_API int sp_var_client_set(sp_var_client_t *client, const char *key, const char *str, int persist);
 int sp_var_client_get(sp_var_client_t *client, const char *key, char *str, int *n);
 int sp_var_client_lock(sp_var_client_t *client);
 int sp_var_client_unlock(sp_var_client_t *client);

+ 28 - 0
spbase/test/SpBaseMiscTest.cpp

@@ -30,3 +30,31 @@ TEST(SpBaseErrorCode, ErrorCode2MsgTest)
 	ASSERT_STREQ("Unkown ErrorCode(0x6FFFFFFF)", SpStrError((ErrorCodeEnum)0x6FFFFFFF));
 }
 
+#include "SpComm.hpp"
+
+TEST(SpCommTest, MachineSiteTypeTest)
+{
+	EXPECT_TRUE(SP::MachineFormat::Str2Site("cmb.lib") == SP::MachineFormat::CMB_LIB);
+	EXPECT_TRUE(SP::MachineFormat::Str2Site("CMB.SMM") == SP::MachineFormat::CMB_SMM);
+	EXPECT_TRUE(SP::MachineFormat::Str2Site("CMB.XXXX") == SP::MachineFormat::CMB_UNKNOWN);
+	EXPECT_TRUE(SP::MachineFormat::Str2Site("") == SP::MachineFormat::CMB_UNKNOWN);
+	EXPECT_TRUE(SP::MachineFormat::Str2Site(NULL) == SP::MachineFormat::CMB_UNKNOWN);
+
+	ASSERT_STREQ("CMB.SMM", SP::MachineFormat::Site2Str(SP::MachineFormat::CMB_SMM));
+	ASSERT_STREQ("CMB.LSS", SP::MachineFormat::Site2Str(SP::MachineFormat::CMB_LSS));
+	ASSERT_STREQ("Unkown", SP::MachineFormat::Site2Str(SP::MachineFormat::CMB_UNKNOWN));
+}
+
+TEST(SpCommTest, MachineTypeTest)
+{
+	EXPECT_TRUE(SP::MachineFormat::Str2Type("rvc.PAD") == SP::MachineFormat::RVC_PAD);
+	EXPECT_TRUE(SP::MachineFormat::Str2Type("RVC.Stand2S") == SP::MachineFormat::RVC_Stand2S);
+	EXPECT_TRUE(SP::MachineFormat::Str2Type("rvc.XXXX") == SP::MachineFormat::RVC_UNKNOWN);
+	EXPECT_TRUE(SP::MachineFormat::Str2Type("") == SP::MachineFormat::RVC_UNKNOWN);
+	EXPECT_TRUE(SP::MachineFormat::Str2Type(NULL) == SP::MachineFormat::RVC_UNKNOWN);
+
+	ASSERT_STREQ("RVC.PAD", SP::MachineFormat::Type2Str(SP::MachineFormat::RVC_PAD));
+	ASSERT_STREQ("RVC.Desk2S", SP::MachineFormat::Type2Str(SP::MachineFormat::RVC_Desk2S));
+	ASSERT_STREQ("Unkown", SP::MachineFormat::Type2Str(SP::MachineFormat::RVC_UNKNOWN));
+}
+

+ 30 - 2
spshell/app.cpp

@@ -91,14 +91,14 @@ static unsigned int __stdcall __startlist_proc(void *param)
 		sp_dbg_error("======================================================");
 		sp_dbg_error("!!!!!! a few of entities started up failed! please get more detail from dbg\\spshell !!!!!!");
 		sp_dbg_error("======================================================");
-		env->cfg->shell_ini->shell_state = 3/*break down*/;
+		app_update_terminal_state(FrameworkState_Breakdown);
 		Sleep(10000);
 		app_t *app = get_app_instance();
 		sp_iom_post_quit(app->iom);
 	}
 	else {
 		sp_dbg_info("all boot up entities has been started succ.");
-		env->cfg->shell_ini->shell_state = 2/*running*/;
+		app_update_terminal_state(FrameworkState_Running);
 	}
 	return 0;
 }
@@ -317,6 +317,13 @@ int app_init(const sp_cfg_start_args_t* args)
 	// 检查轻量更新包是否有.new文件
 	RenameLightPacks(env->cfg->root_ini->ref_addata_path);
 
+	/** for update terminal state event*/
+	rc = sp_var_client_create(g_app.svc, &g_app.var_client);
+	if (rc != 0) {
+		sp_dbg_error("var client create failed!");
+		return rc;
+	}
+
 	rc = sp_var_daemon_create(g_app.svc, &g_app.var_daemon);	// add workitem daemon_on_pkt and daemon_on_sys
 	if (rc != 0) {
 		sp_dbg_error("var daemon create failed!");
@@ -361,6 +368,8 @@ int app_init(const sp_cfg_start_args_t* args)
 	sp_dbg_info("create and start silverlight policy server ok!");
 #endif //_WIN32
 
+	app_update_terminal_state(FrameworkState_Booting);
+
 	rc = kickoff_startlist();
 	if (rc != 0) {
 		sp_dbg_error("kickoff startlist thread proc failed!");
@@ -383,6 +392,8 @@ int app_init(const sp_cfg_start_args_t* args)
 	}
 #endif
 
+
+
 #ifdef _WIN32
 	sp_runtask_startprocess();
 #endif //_WIN32
@@ -445,6 +456,10 @@ int app_term()
 	sp_var_daemon_destroy(g_app.var_daemon);
 	g_app.var_daemon = NULL;
 
+	sp_dbg_info("destroy var client");
+	sp_var_client_destroy(g_app.var_client);
+	g_app.var_client = NULL;
+
 	sp_dbg_info("destroy log daemon.");
 	log_destroy(g_app.log);
 
@@ -513,6 +528,19 @@ int app_run()
 	return rc;
 }
 
+int app_update_terminal_state(int state)
+{
+	int rc;
+	char n[12] = {'\0'};
+	sp_env_t* env = sp_get_env();
+	sp_cfg_t* cfg = env->cfg;
+	int old_state = cfg->shell_ini->shell_state;
+	cfg->shell_ini->shell_state = state;
+	_itoa(state, n, 10);
+	rc = sp_var_client_set(g_app.var_client, VAR_RSERVERD_KEY_TERM_STATE, n, 0);
+	return rc;
+}
+
 app_t *get_app_instance()
 {
 	return &g_app;

+ 3 - 0
spshell/app.h

@@ -23,6 +23,7 @@ struct app_t {
 	bus_daemon_t *bus_daemon;
 	sp_svc_t *svc;
 	sp_iom_t *iom;
+	sp_var_client_t* var_client;
 	sp_var_daemon_t *var_daemon;
 	sp_bcm_daemon_t *bcm_daemon;
 	log_t *log;
@@ -39,4 +40,6 @@ int app_init(const sp_cfg_start_args_t* args);
 int app_term();
 int app_run();
 
+int app_update_terminal_state(int state);
+
 #endif //__APP_H__

+ 12 - 16
spshell/spshell.cpp

@@ -26,9 +26,6 @@
 #include <winpr/sysinfo.h>
 using namespace std;
 
-//let CMake do it.
-//#pragma comment(lib, "dbghelp.lib")
-
 #define DRIVER_NAME "HelloDDK"
 #define DRIVER_PATH "InterceptDll.sys"
 #define SET_EVENT		\
@@ -168,7 +165,7 @@ static HANDLE create_process(const char *app)
 			(PTOKEN_PRIVILEGES)NULL, NULL);
 		//CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE);
 		if (CreateProcessAsUserA(hUserTokenDup, NULL, 
-			(LPSTR)app,		// "D:\\Source\\RVC\\RVCProject\\Release\\version\\1.0.0.1\\bin\\MetroWatcher64.exe 732",
+			(LPSTR)app,
 			NULL, NULL, FALSE, 0, pEnv, NULL, &si, &pi)) 
 		{
 			CloseHandle(pi.hThread);
@@ -307,7 +304,7 @@ static bool DisableWindowsCharmBar(bool bX64)
 #endif //_WIN32
 
 /*!
- * @at Linux, judge whether current process runs as root privilege.
+ * at Linux, judge whether current process runs as root privilege.
  * @return : True only if run as admin or root
  */
 static bool  IsProcessRunAsAdmin()
@@ -355,14 +352,14 @@ const char *GetMachineType()
 const char *GetCenterSettingNameBySite(const char *pszSite)
 {
 	if ((stricmp(pszSite, "CMB.LIB") == 0)	// 行内大堂
-		|| (stricmp(pszSite, "CMB.SSB") == 0))// 自助网点
+		|| (stricmp(pszSite, "CMB.SSB") == 0))// 
 	{
 		return  "CenterSetting.LAN.ini";
 	}
-	else if ((stricmp(pszSite, "CMB.LSS") == 0)	// 生活销售机
-		|| (stricmp(pszSite, "CMB.FLB") == 0)		// 离行机器
-		|| (stricmp(pszSite, "CMB.OSB") == 0)		// 外拓PAD
-		|| (stricmp(pszSite, "CMB.SMM") == 0))		// 商户终端
+	else if ((stricmp(pszSite, "CMB.LSS") == 0)	// 
+		|| (stricmp(pszSite, "CMB.FLB") == 0)		// 
+		|| (stricmp(pszSite, "CMB.OSB") == 0)		// 
+		|| (stricmp(pszSite, "CMB.SMM") == 0))		// 
 	{
 		return   "CenterSetting.DMZ.ini";
 	}
@@ -398,10 +395,6 @@ const char *GetWebSiteFromConfig()
 		}
 	}
 
-	//auto pCfgPath = env->dir->cfg_path;
-	//char szCfgFile[256] = {};
-	//sprintf(szCfgFile, "%s\\%s", pCfgPath, "CenterSetting.ini");
-
 	// get machine type
 	auto pMachineType = env->cfg->root_ini->machine_type;
 	char szKeyName[256] = {};
@@ -752,9 +745,12 @@ void DisplayUsage()
 		"  --kill                                          -- 直接杀死程序相关进程\n"
 		"  --ipc <pipe,tcp>                      -- pipe: 实体间以管道的方式通信;tcp: 实体间以socket的方式通信\n"
 	);
+
 	sp_dbg_info(szHelp);
 #ifdef _WIN32
 	MessageBoxA(NULL, szHelp, "Spshell Usage Tip", MB_OK);
+#else
+	printf(szHelp);
 #endif //_WIN32
 }
 
@@ -852,9 +848,9 @@ sp_cfg_start_args_t* DealWithArgs(int argc, char** argv)
 	}
 
 	if (getopt_optind < argc) {
-		sp_dbg_info("non-option ARGV-elements: ");
+		sp_dbg_warn("non-option ARGV-elements: ");
 		while (getopt_optind < argc)
-			sp_dbg_info("\t%s", argv[getopt_optind++]);
+			sp_dbg_warn("\t%s", argv[getopt_optind++]);
 	}
 
 	if (args && args->start_entities != 0) {