#include "stdafx.h" #include "SpBase.h" #include "SpTimer.h" #include "SpMisc.h" #include "SpBinaryPersistStream.h" #include "SpEntity.h" #include "SpModule.h" #include "SpAsyncWait.h" #include "SpClientSessionFunction.h" #include "SpServerSessionFunction.h" #include "sp_iom.h" #include "sp_svc.h" #include "sp_dbg_export.h" #include "sp_log.h" #include "sp_var.h" #include "sp_def.h" #include "sp_cfg.h" #include "sp_env.h" #include "sp_btr.h" #include "memutil.h" #include "strutil.h" #include "fileutil.h" #include "shm_array.h" #include "def.h" #ifdef _WIN32 #include "CodeSignVerify.h" #include "sp_checkEntity.h" #endif //_WIN32 static void var_callback(sp_var_listener_t *listener, const char *key, const char *oldstr, const char *newstr, int client_id, void *user_data) { ISysVarListener *pListener = (ISysVarListener *)user_data; SpEntity *pEntity = (SpEntity*)sp_var_listener_get_tag(listener); #ifdef _WIN32 SetthreadGroup(GetCurrentThreadId(), pEntity->get_cfg_ent()->name); getEntityResource()->m_Entity = pEntity; #else GetSpModule()->SetThreadEntity(pEntity); #endif //_WIN32 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); } } static void bcm_callback(sp_bcm_listener_t *listener, int from_client_id, int message_id, int message_sig, const void *buf, int len, void *user_data) { IBroadcastListener *pListener = (IBroadcastListener *)user_data; SpEntity *pEntity = (SpEntity*)sp_bcm_listener_get_tag(listener); sp_uid_t uid; #ifdef _WIN32 SetthreadGroup(GetCurrentThreadId(), pEntity->get_cfg_ent()->name); getEntityResource()->m_Entity = pEntity; #else GetSpModule()->SetThreadEntity(pEntity); #endif //_WIN32 sp_bcm_listener_get_uid(listener, &uid); sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, from_client_id); if (ent) { CAutoBuffer Buf; Buf.Init(len); if (len > 0) { memcpy(&Buf[0], buf, len); } pListener->OnBroadcastEvent(CUUID(uid), ent->cfg->name, (DWORD)message_id, (DWORD)message_sig, Buf); } } static void on_log(void *inst, int nsub, u__int64_t *sub, int client_id, int log_epid, int client_instance_id, u__int64_t log_id, u__int64_t prev_rsn, u__int64_t curr_rsn, int original_rsn_type, int rsn_depth, unsigned int log_time, int log_type, int log_severity, int log_sys_error, int log_usr_error, int param_cnt, int *params, const char *msg, void *user_data) { try { ILogListener *pListener = (ILogListener *)user_data; sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, client_id); if (ent) { int i; CAutoArray arr; arr.Init(param_cnt); for (i = 0; i < param_cnt; ++i) { arr[i] = (DWORD)params[i]; } CAutoArray subIDs; subIDs.Init(nsub); CUUID *pSub = (CUUID*)sub; for (i = 0; i < nsub; i++) subIDs[i] = pSub[i]; pListener->OnLog(subIDs, CUUID(log_id), (LogTypeEnum)log_type, (SeverityLevelEnum)log_severity, log_sys_error, log_usr_error, ent->instance_id, ent->cfg->devel_id, arr, ent->cfg->name, ent->mod->cfg->name, msg); } } catch (const std::exception&) { } } static void task_callback(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2) { ITaskSp *pTask = (ITaskSp*)arg; SpEntity *pEntity = (SpEntity*)param1; //Dbg("task_callback pTask = %08x", pTask); #ifdef _WIN32 SetthreadGroup(GetCurrentThreadId(), pEntity->GetEntityBase()->GetEntityName()); try { getEntityResource()->m_Entity = pEntity; pTask->Process(); pTask->DecRef(); } catch (...) { } #else GetSpModule()->SetThreadEntity(pEntity); #endif //_WIN32 } static void tpool_log(threadpool_t *threadpool, const char* str) { sp_dbg_debug(str); } static ErrorCodeEnum GetEntityStaticInfo(CEntityStaticInfo &Info, sp_entity_t *ent) { sp_env_t *env = sp_get_env(); if (ent) { bool bStartedByShell = false; for (int i = 0; i < env->cfg->shell_ini->arr_startlist->nelts; ++i) { sp_cfg_shell_entity_t * tmp_ent = ARRAY_IDX(env->cfg->shell_ini->arr_startlist, i, sp_cfg_shell_entity_t*); if (tmp_ent->idx == ent->cfg->idx) { bStartedByShell = true; break; } } Info.wEntityDevelopID = ent->cfg->devel_id; Info.strSpFileName = ent->mod->cfg->name; Info.bStartedByShell = bStartedByShell; Info.bIndispensable = true; Info.bHasPrivilege = !!ent->cfg->privilege; } else { return Error_NotExist; } return Error_Succeed; } SpEntity::SpEntity(SpModule *pModule, sp_entity_t *ent, sp_cfg_shell_entity_t *cfg_ent, CEntityBase *pEntityBase) : m_pModule(pModule), m_pEntityBase(pEntityBase), m_pTimerList(NULL), m_svc(NULL), m_var_client(NULL), m_log_client(NULL), m_ent(ent), m_cfg_ent(cfg_ent), m_tbs(NULL), m_bcm_client(NULL), m_arr_any_var(NULL), m_arr_bcm_listener(NULL), m_log_mgr(NULL) { m_ent->service_flag = m_pEntityBase->IsService() ? 1 : 0; memset(&m_arr_var[0], 0, sizeof(m_arr_var)); } SpEntity::~SpEntity() { Dbg("run ~SpEntity()"); #ifdef _WIN32 getEntityResource()->m_Entity = NULL; #endif //_WIN32 } ErrorCodeEnum SpEntity::Init() { sp_mod_entity_stub_cb cb; int rc; threadpool_t *threadpool; rc = sp_svc_create(m_pModule->get_iom(), 0, m_ent->cfg->idx,m_ent->cfg->devel_id, &m_svc); //threadpool if (rc != 0) { sp_dbg_warn("create svc failed!"); return SpTranslateError(rc); } sp_dbg_info("create svc ok!"); threadpool = sp_svc_get_threadpool(m_svc); threadpool_set_thread_decorator(threadpool, &SpEntity::__on_thread_init, &SpEntity::__on_thread_term, this); //Entity thread threadpool_create(&m_tpool); threadpool_set_log(m_tpool, &tpool_log); threadpool_set_thread_decorator(m_tpool, &SpEntity::__on_thread_init, &SpEntity::__on_thread_term, this); threadpool_start(m_tpool, 0, 64, 5*60*1000, 0); #ifdef _WIN32 setModuleAliasName(GetEntityBase()->GetEntityName()); #endif //_WIN32 rc = sp_svc_start(m_svc); if (rc != 0) { sp_dbg_warn("start svc failed!"); return SpTranslateError(rc); } sp_dbg_info("start svc ok!"); m_pTimerList = SpTimerListCreate(this); if (!m_pTimerList) { sp_dbg_warn("create timer list failed!"); return Error_Unexpect; } cb.on_entity_prestart = &SpEntity::__on_entity_prestart; cb.on_entity_stop = &SpEntity::__on_entity_stop; cb.on_entity_prepause = &SpEntity::__on_entity_prepause; cb.on_entity_test = &SpEntity::__on_entity_test; cb.on_entity_precontinue = &SpEntity::__on_entity_precontinue; cb.on_entity_redirect_subscribe = &SpEntity::__on_entity_redirect_subscribe; cb.user_data = this; rc = sp_mod_entity_stub_create(&cb, m_svc, &m_stub); //add a workItem mod_entity_on_pkt if (rc != 0) { sp_dbg_warn("create entity stub failed!"); return SpTranslateError(rc); } sp_dbg_info("start entity stub ok!"); sp_rpc_client_mgr_callback mgr_cb = {SpEntity::__on_rpc_request, NULL, this}; rc = sp_rpc_client_mgr_create(m_svc, &mgr_cb, &m_rpc_mgr); //Init variable m_rpc_mgr, callback handle if (rc != 0) { sp_dbg_warn("create rpc client mgr failed!"); return SpTranslateError(rc); } rc = sp_rpc_client_mgr_start(m_rpc_mgr); //add workItem mgr_on_pkt and mgr_on_sys if (rc != 0) { sp_dbg_warn("start rpc client mgr failed!"); return SpTranslateError(rc); } sp_dbg_info("start rpc client ok!"); sp_ses_mgr_callback_t ses_mgr_cb = {0}; ses_mgr_cb.on_accept = &__on_accept; ses_mgr_cb.on_destroy = NULL; ses_mgr_cb.user_data = this; rc = sp_ses_mgr_create(m_svc, &ses_mgr_cb, &m_ses_mgr); //Init variable m_ses_mgr if (rc != 0) { sp_dbg_warn("create ses mgr failed!"); return SpTranslateError(rc); } rc = sp_ses_mgr_start(m_ses_mgr); //add workItem mgr_on_pkt and mgr_on_sys if (rc != 0) { sp_dbg_warn("start ses mgr failed!"); return SpTranslateError(rc); } sp_dbg_info("start ses mgr ok!"); rc = sp_log_client_create(m_svc, m_pModule->get_iom(), &m_log_client); if (rc != 0) { sp_dbg_warn("create log client failed!"); return SpTranslateError(rc); } sp_dbg_info("start entity log client ok!"); rc = sp_var_client_create(m_svc, &m_var_client); if (rc != 0) { sp_dbg_warn("create var client failed!"); return SpTranslateError(rc); } sp_dbg_info("create var client ok!"); rc = sp_bcm_client_create(m_svc, &m_bcm_client); if (rc != 0) { sp_dbg_warn("create bcm client failed!"); return SpTranslateError(rc); } sp_dbg_warn("create bcm client ok!"); rc = sp_log_listener_mgr_create(m_svc, on_log, &m_log_mgr); if (rc == 0) { rc = sp_log_listener_mgr_start(m_log_mgr); if (rc != 0) { sp_dbg_warn("create log mgr failed!"); return SpTranslateError(rc); } } sp_dbg_warn("create log mgr ok!"); m_arr_bcm_listener = array_make(0, sizeof(sp_bcm_listener_t*)); return SpTranslateError(rc); } void SpEntity::Term() { SpTimerListStopAll(m_pTimerList); } void SpEntity::on_entity_prestart(int trigger_entity_id, int argc, char *argv[]) { CAutoArray Args; Args.Init(argc); CSmartPointer pTransactionContext; pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_START)); for (int i = 0; i < argc; ++i) Args[i] = argv[i]; m_pEntityBase->OnPreStart(Args, pTransactionContext); } void SpEntity::on_entity_stop(int trigger_entity_id, int cause_code) { CSmartPointer pTransactionContext; pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_CLOSE)); m_pEntityBase->OnPreClose((EntityCloseCauseEnum)cause_code, pTransactionContext); } void SpEntity::on_entity_prepause(int trigger_entity_id) { CSmartPointer pTransactionContext; pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_PAUSE)); m_pEntityBase->OnPrePause(pTransactionContext); } void SpEntity::on_entity_precontinue(int trigger_entity_id) { CSmartPointer pTransactionContext; pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_CONTINUE)); m_pEntityBase->OnPreContinue(pTransactionContext); } void SpEntity::on_entity_test(int trigger_entity_id, int test_type) { CSmartPointer pTransactionContext; pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_SELFTEST)); m_pEntityBase->OnSelfTest((EntityTestEnum)test_type, pTransactionContext); } void SpEntity::on_entity_redirect_subscribe(sp_uid_t *uid, int from_entity_id, const char *param) { CUUID id(*uid); sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, from_entity_id); if (ent) { m_pEntityBase->OnBroadcastSubscribe(id, ent->cfg->name, param); } } void SpEntity::__on_entity_prestart(sp_mod_entity_stub_t *, int trigger_entity_id, int argc, char *argv[], void *user_data) { sp_dbg_debug("==> %s", __FUNCTION__); SpEntity *pThis = static_cast(user_data); pThis->on_entity_prestart(trigger_entity_id, argc, argv); sp_dbg_debug("<== %s", __FUNCTION__); } void SpEntity::__on_entity_stop(sp_mod_entity_stub_t *, int trigger_entity_id, int cause_code, void *user_data) { Dbg("stop Entity"); SpEntity *pThis = static_cast(user_data); pThis->on_entity_stop(trigger_entity_id, cause_code); } void SpEntity::__on_entity_prepause(sp_mod_entity_stub_t *, int trigger_entity_id, void *user_data) { SpEntity *pThis = static_cast(user_data); pThis->on_entity_prepause(trigger_entity_id); } void SpEntity::__on_entity_precontinue(sp_mod_entity_stub_t *, int trigger_entity_id, void *user_data) { SpEntity *pThis = static_cast(user_data); pThis->on_entity_precontinue(trigger_entity_id); } void SpEntity::__on_entity_test(sp_mod_entity_stub_t *, int trigger_entity_id, int test_type, void *user_data) { SpEntity *pThis = static_cast(user_data); pThis->on_entity_test(trigger_entity_id, test_type); } void SpEntity::__on_entity_redirect_subscribe(sp_mod_entity_stub_t *, sp_uid_t *uid, int from_entity_id, const char *param, void *user_data) { SpEntity *pThis = static_cast(user_data); pThis->on_entity_redirect_subscribe(uid, from_entity_id, param); } int SpEntity::__on_accept(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, iobuffer_t **conn_pkt, int *redirect_entity_id, void *user_data) { SpEntity *pThis = static_cast(user_data); return pThis->on_accept(epid, svc_id, conn_id, conn_pkt, redirect_entity_id); } int SpEntity::on_accept(int epid, int svc_id, int conn_id, iobuffer_t **conn_pkt, int *redirect_entity_id) { sp_env_t *env = sp_get_env(); ErrorCodeEnum Error = Error_Succeed; if (!m_pEntityBase->IsService()) { sp_dbg_warn("current entity is no registed as service type, please confirm it at code scope."); return Error_Bug; } sp_entity_t *remote_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, svc_id); if (!remote_ent) { sp_dbg_error("cannot recognize the customer entity: %d!", svc_id); return Error_Bug; } char *pszParam = NULL; CServerSessionBase *pServerSessionBase = NULL; iobuffer_format_read(*conn_pkt, "s", &pszParam); try { m_redirect_entity_cache = NULL; // user can set entity_cache value in OnNewSession by invoking RedirectSession method pServerSessionBase = m_pEntityBase->OnNewSession(remote_ent->cfg->name, pszParam); } catch (...) { Error = Error_Exception; } toolkit_free(pszParam); if (pServerSessionBase) { SpServerSessionFunction *pServerSessionFunction = new SpServerSessionFunction(this, pServerSessionBase, epid, svc_id, conn_id); pServerSessionBase->m_pSessionFunction = pServerSessionFunction; Error = pServerSessionFunction->Begin(); if (Error != Error_Succeed) { delete pServerSessionBase; // this will also delete pServerSessionFunction } } else { if (m_redirect_entity_cache) { *redirect_entity_id = m_redirect_entity_cache->cfg->idx; Error = Error_Redirect; } else { Error = Error_NotImpl; } } return Error; } void SpEntity::on_thread_init() { #ifdef _WIN32 SetthreadGroup(GetCurrentThreadId(), this->get_cfg_ent()->name); getEntityResource()->m_Entity = this; #else m_pModule->SetThreadEntity(this); #endif //_WIN32 } void SpEntity::on_thread_term() { #ifdef _WIN32 SetthreadGroup(GetCurrentThreadId(), this->get_cfg_ent()->name); getEntityResource()->m_Entity = NULL; #else m_pModule->SetThreadEntity(NULL); #endif //_WIN32 } void SpEntity::__on_thread_init(threadpool_t *, void *arg) { SpEntity *pThis = static_cast(arg); pThis->on_thread_init(); sp_dbg_debug("thread init, thread id:%d", GetCurrentThreadId()); } void SpEntity::__on_thread_term(threadpool_t *, void *arg) { SpEntity *pThis = static_cast(arg); pThis->on_thread_term(); sp_dbg_debug("thread term, thread id:%d", GetCurrentThreadId()); } ErrorCodeEnum SpEntity::SetTimer(DWORD nTimerID, ITimerListener *pListener, DWORD dwInterval) { ErrorCodeEnum Error = Error_Succeed; if (!pListener) return Error_Param; SpTimerListLock(m_pTimerList); if (SpTimerListFind(m_pTimerList, nTimerID)) { sp_dbg_warn("timer id %d already in use!", nTimerID); Error = Error_AlreadyExist; } else { SpTimer *pTimer = SpTimerCreate(m_pTimerList, nTimerID, dwInterval, pListener); if (pTimer) { SpTimerListAdd(m_pTimerList, pTimer); Error = SpTimerStart(pTimer); if (Error) { SpTimerListRemove(m_pTimerList, pTimer); SpTimerDestroy(pTimer); sp_dbg_warn("start timer %d failed: %d!", nTimerID, Error); } else { sp_dbg_info("timer %d added! interval = %d", nTimerID, dwInterval); } } else { Error = Error_Unexpect; } } SpTimerListUnlock(m_pTimerList); return Error; } ErrorCodeEnum SpEntity::SetTimerData(DWORD dwTimerID, IReleasable *pData) { ErrorCodeEnum Error = Error_Succeed; SpTimerListLock(m_pTimerList); SpTimer *pTimer = SpTimerListFind(m_pTimerList, dwTimerID); if (pTimer) { SpTimerSetUserData(pTimer, pData); } else { sp_dbg_warn("timer %d not found!", dwTimerID); Error = Error_NotExist; } SpTimerListUnlock(m_pTimerList); return Error; } ErrorCodeEnum SpEntity::GetTimerData(DWORD dwTimerID, CSmartPointer &pData) { ErrorCodeEnum Error = Error_Succeed; SpTimerListLock(m_pTimerList); SpTimer *pTimer = SpTimerListFind(m_pTimerList, dwTimerID); if (pTimer) { SpTimerGetUserData(pTimer, pData); } else { sp_dbg_warn("timer %d not found!", dwTimerID); Error = Error_NotExist; } SpTimerListUnlock(m_pTimerList); return Error; } ErrorCodeEnum SpEntity::KillTimer(DWORD nTimerID) { ErrorCodeEnum Error = Error_Succeed; SpTimerListLock(m_pTimerList); SpTimer *pTimer = SpTimerListFind(m_pTimerList, nTimerID); if (pTimer) { sp_dbg_info("timer %d killed!", nTimerID); SpTimerListRemove(m_pTimerList, pTimer); SpTimerStop(pTimer); SpTimerDestroy(pTimer); } else { sp_dbg_warn("timer %d has not set!", nTimerID); Error = Error_NotExist; } SpTimerListUnlock(m_pTimerList); return Error; } ErrorCodeEnum SpEntity::ResetTimer(DWORD nTimerID, DWORD dwInterval) { ErrorCodeEnum Error = Error_Succeed; SpTimerListLock(m_pTimerList); SpTimer *pTimer = SpTimerListFind(m_pTimerList, nTimerID); if (pTimer) { SpTimerSetInterval(pTimer, dwInterval); } else { sp_dbg_warn("timer %d has not set!", nTimerID); Error = Error_NotExist; } SpTimerListUnlock(m_pTimerList); return Error; } ErrorCodeEnum SpEntity::GetTimerInterval(DWORD nTimerID, DWORD &dwInterval) { ErrorCodeEnum Error = Error_Succeed; SpTimerListLock(m_pTimerList); SpTimer *pTimer = SpTimerListFind(m_pTimerList, nTimerID); if (pTimer) { dwInterval = SpTimerGetInterval(pTimer); } else { sp_dbg_warn("timer %d has not set!", nTimerID); Error = Error_NotExist; } SpTimerListUnlock(m_pTimerList); return Error; } ErrorCodeEnum SpEntity::ReadPersistObject(const char *pszClass, const char *pszKey, IEntityPersistObject *pInstance) { sp_env_t *env = sp_get_env(); sp_pst_tree_t *tree; int rc; if (!pszClass || !pszKey || !pInstance) return Error_Param; rc = sp_pst_tree_load(env->dir->obj_path, m_ent->cfg->name, pszClass, pszKey, &tree); if (rc == 0) { sp_pst_elem_t *root = sp_pst_tree_get_root(tree); CSmartPointer pStream; pStream.Attach(new SpBinaryPersistStream(SpBinaryPersistStream::Read, root)); rc = (int)pInstance->OnRead(pStream); sp_pst_tree_destroy(tree); } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::WritePersistObject(const char *pszClass, const char *pszKey, const IEntityPersistObject *pInstance) { sp_env_t *env = sp_get_env(); sp_pst_elem_t *root; int rc; if (!pszClass || !pszKey || !pInstance) return Error_Param; root = sp_pst_elem_create(NULL, pszKey); CSmartPointer pStream; pStream.Attach(new SpBinaryPersistStream(SpBinaryPersistStream::Write, root)); rc = (int)pInstance->OnWrite(pStream); if (rc == 0) { sp_pst_tree_t *tree; sp_pst_tree_create(&tree); sp_pst_tree_set_root(tree, root); rc = sp_pst_tree_save(env->dir->obj_path, m_ent->cfg->name, pszClass, pszKey, tree); sp_pst_tree_destroy(tree); } else { sp_pst_elem_destroy(root); } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::ReadNumOfPersistObject(const char *pszClassName,DWORD &nNum) { if (!pszClassName) return Error_Param; sp_env_t *env = sp_get_env(); int cnt; int rc = sp_pst_get_object_count(env->dir->obj_path, m_ent->cfg->name, pszClassName, &cnt); if (rc == 0) //nNum = (DWORD)rc; // {bug} nNum = (DWORD)cnt; return SpTranslateError(rc); } ErrorCodeEnum SpEntity::GetPersistClassObjectKeys(const char *pszClassName, CAutoArray &strKeys) { if (!pszClassName) return Error_Param; sp_env_t *env = sp_get_env(); array_header_t *arr = sp_pst_get_object_keys(env->dir->obj_path, m_ent->cfg->name, pszClassName); if (arr) { strKeys.Init(arr->nelts); for (int i = 0; i < arr->nelts; ++i) strKeys[i] = ARRAY_IDX(arr, i, char*); array_free2(arr); } else { strKeys.Init(0); } return Error_Succeed; } ErrorCodeEnum SpEntity::DeleteKeyOfPersistObject(const char *pszClassName,const char *pszKey) { if (!pszClassName || !pszKey) return Error_Param; sp_env_t *env = sp_get_env(); int rc = sp_pst_delete_object(env->dir->obj_path, m_ent->cfg->name, pszClassName, pszKey); return SpTranslateError(rc); } ErrorCodeEnum SpEntity::EnumKeyOfPersistObject(const char *pszClass,CSimpleStringA &strKey,DWORD &handle) { if (!pszClass) return Error_Param; int rc = 0; sp_env_t *env = sp_get_env(); struct HelperIterator { array_header_t *arr; int Current; } * pIterator = NULL; if (handle == 0) { pIterator = new HelperIterator(); pIterator->arr = sp_pst_get_object_keys(env->dir->obj_path, m_ent->cfg->name, pszClass); if (!pIterator->arr) { delete pIterator; return Error_NotExist; } pIterator->Current = 0; //TODO: x64 environment, depend on how to use the out-param handle = (uintptr_t)(static_cast(pIterator)); //Handle = (DWORD)pIterator; } else { pIterator = (HelperIterator *)handle; } if (pIterator->Current < pIterator->arr->nelts) { strKey = ARRAY_IDX(pIterator->arr, pIterator->Current, char*); pIterator->Current++; } else { if (pIterator->arr) array_free2(pIterator->arr); delete pIterator; handle = 0; // zero handle rc = Error_NotExist;// the end } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::CleanAllOfPersistObject(const char *pszClass) { if (!pszClass) return Error_Param; sp_env_t *env = sp_get_env(); int rc = sp_pst_delete_class_objects(env->dir->obj_path, m_ent->cfg->name, pszClass); return SpTranslateError(rc); } ErrorCodeEnum SpEntity::SubscribeLog(CUUID &SubscribeID, ILogListener *pListener,LogTypeEnum eLogType,SeverityLevelEnum eLevel, ErrorCodeEnum eSysError,DWORD dwUserCode,const char *pszEntityName,bool bIgnoreMessage) { _ASSERT(pListener); sp_entity_t *ent = NULL; if (pszEntityName) { ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszEntityName); if (!ent) { sp_dbg_error("SubscribeLog failed! Entity %s not exist!", pszEntityName); return Error_NotExist; } } unsigned int listen_id = 0; int rc = sp_log_listener_mgr_subscribe(m_log_mgr, &listen_id, pListener, !!bIgnoreMessage, eLogType, ent ? ent->cfg->idx : -1, eLevel, eSysError, dwUserCode); if (rc == 0) { SubscribeID = listen_id; } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::UnsubscribeLog(CUUID SubscribeID) { unsigned int listen_id = (unsigned int)SubscribeID; int rc = sp_log_listener_mgr_unsubscribe(m_log_mgr, listen_id); return SpTranslateError(rc); } ErrorCodeEnum SpEntity::FlushLogFile() { return LogFlush(); } ErrorCodeEnum SpEntity::SetSysVar(const char *pszKey,const char *pszValue, bool bPersist) { int rc; _ASSERT(pszKey); // pszValue can be null, use for delete rc = sp_var_client_set((sp_var_client_t*)m_var_client, pszKey, pszValue, bPersist ? 1 : 0); return SpTranslateError(rc); } ErrorCodeEnum SpEntity::GetSysVar(const char *pszKey,CSimpleStringA &strValue) { sp_var_client_t* client = (sp_var_client_t*)m_var_client; int slen; int rc; _ASSERT(pszKey); rc = sp_var_client_lock(client); if (rc == 0) { rc = sp_var_client_get(client, pszKey, NULL, &slen); if (rc == 0) { CSimpleStringA strTmp('\0', slen); rc = sp_var_client_get((sp_var_client_t*)m_var_client, pszKey, &strTmp[0], &slen); if (rc == 0) strValue = strTmp; } sp_var_client_unlock(client); } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::RegistSysVarEvent(const char *pszKey,ISysVarListener *pListener) { int rc = 0; if (!pszKey || !pListener) return Error_Param; sp_env_t *env = sp_get_env(); sp_var_listener_t **pp_var; if (strcmp(pszKey, "*") != 0) { sp_cfg_shell_sysevent_t *sysevent = sp_cfg_get_sysevent(env->cfg, pszKey); if (!sysevent) return Error_NotExist; if (m_arr_var[sysevent->idx]) return Error_Duplication; pp_var = &m_arr_var[sysevent->idx]; } else { if (m_arr_any_var) return Error_Duplication; pp_var = &m_arr_any_var; } sp_var_listener_t *listener; sp_var_listener_create(m_svc, pszKey, &var_callback, pListener, &listener); sp_var_listener_set_tag(listener, this); rc = sp_var_listener_subscribe(listener); if (rc == 0) { *pp_var = listener; } else { sp_var_listener_destroy(listener); } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::UnregistSysVarEvent(const char *pszKey) { if (!pszKey) return Error_Param; int rc = 0; if (strcmp(pszKey, "*") != 0) { sp_env_t *env = sp_get_env(); sp_cfg_shell_sysevent_t *sysevent = sp_cfg_get_sysevent(env->cfg, pszKey); if (!sysevent) return Error_NotExist; sp_var_listener_t *listener = m_arr_var[sysevent->idx]; if (listener) { int rc; rc = sp_var_listener_unsubscribe(listener); if (rc == 0) { sp_var_listener_destroy(listener); m_arr_var[sysevent->idx] = NULL; } } else { rc = Error_NotInit; } } else { if (m_arr_any_var != NULL) { rc = sp_var_listener_unsubscribe(m_arr_any_var); if (rc == 0) { sp_var_listener_destroy(m_arr_any_var); m_arr_any_var = NULL; } } } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::SendBroadcast(DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer) { int rc; iobuffer_t *pkt = iobuffer_create(-1, Buffer.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &Buffer[0], Buffer.GetCount()); rc = sp_bcm_client_bcast(m_bcm_client, dwMessageId, dwMessageSignature, &pkt); if (pkt) iobuffer_dec_ref(pkt); return SpTranslateError(rc); } ErrorCodeEnum SpEntity::GetBroadcastReceivers(CAutoArray &Subscribers) { ErrorCodeEnum Error; iobuffer_t *req_pkt = iobuffer_create(-1, -1); iobuffer_t *ans_pkt = NULL; Error = AskShell(SHELL_CMD_REQ_GET_BCAST_RECEIVER, &req_pkt, &ans_pkt); if (Error == Error_Succeed) { sp_env_t *env = sp_get_env(); int size; iobuffer_read(ans_pkt, IOBUF_T_I4, &size, NULL); Subscribers.Init(size); for (int i = 0; i < size; ++i) { int ent_id; sp_uid_t uid; char *param = NULL; iobuffer_format_read(ans_pkt, "84s", &uid, &ent_id, ¶m); Subscribers[i].SubID = CUUID(uid); sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, ent_id); Subscribers[i].strListener = ent->cfg->name; Subscribers[i].strParam = param; toolkit_free(param); } } if (req_pkt) iobuffer_dec_ref(req_pkt); if (ans_pkt) iobuffer_dec_ref(ans_pkt); return Error; } ErrorCodeEnum SpEntity::SubscribeBroadcast(const char *pszRemoteEntity, const char *pszParam, IBroadcastListener *pListener, CUUID &SubscribeID) { if (pszParam == NULL) pszParam = ""; if (pListener == NULL) return Error_Param; sp_entity_t *remote_ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszRemoteEntity); if (remote_ent) { int rc; sp_uid_t uid; sp_bcm_listener_t *listener; sp_bcm_listener_cb cb = {0}; cb.on_destroy = NULL; cb.on_message = &bcm_callback; cb.on_message_raw = NULL; cb.user_data = pListener; rc = sp_bcm_listener_create(m_svc, remote_ent->cfg->idx, pszParam, &cb, &listener); if (rc == 0) { rc = sp_bcm_listener_subscribe(listener, &uid); } if (rc != 0) { return SpTranslateError(rc); } SubscribeID = CUUID(uid); sp_bcm_listener_set_tag(listener, this); ARRAY_PUSH(m_arr_bcm_listener, sp_bcm_listener_t*) = listener; } else { return Error_NotExist; } return Error_Succeed; } ErrorCodeEnum SpEntity::UnsubscribeBroadcast(CUUID SubscribeID) { sp_bcm_listener_t *listener = NULL; int i; for (i = 0; i < m_arr_bcm_listener->nelts; ++i) { listener = ARRAY_IDX(m_arr_bcm_listener, i, sp_bcm_listener_t*); sp_uid_t uid; sp_bcm_listener_get_uid(listener, &uid); if (uid == SubscribeID.m_nUUID64) { ARRAY_DEL(m_arr_bcm_listener, i, sp_bcm_listener_t*); break; } } if (listener) { sp_bcm_listener_unsubscribe(listener); sp_bcm_listener_destroy(listener); return Error_Succeed; } else { return Error_NotExist; } } ErrorCodeEnum SpEntity::UnsubscribeBroadcast(const char *pszRemoteEntity) { if (pszRemoteEntity == NULL) return Error_Param; sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszRemoteEntity); if (!ent) return Error_NotExist; sp_bcm_listener_t *listener = NULL; int i; for (i = m_arr_bcm_listener->nelts-1; i >= 0; --i) { listener = ARRAY_IDX(m_arr_bcm_listener, i, sp_bcm_listener_t*); if (ent->cfg->idx == sp_bcm_listener_get_target_entity_id(listener)) { ARRAY_DEL(m_arr_bcm_listener, i, sp_bcm_listener_t*); sp_bcm_listener_unsubscribe(listener); sp_bcm_listener_destroy(listener); } } return Error_Succeed; } ErrorCodeEnum SpEntity::LogMessage( const LogTypeEnum LogType, const SeverityLevelEnum Level, DWORD dwSysErrorCode, DWORD dwUserErrorCode, const char *pMessage ) { // xkm@20160726: 校验 dwUserErrorCode 是否合法 int nDevID = m_ent->cfg->devel_id; if (dwUserErrorCode!=0 && ((dwUserErrorCode >> 20) & nDevID) != nDevID) { sp_dbg_warn("[InvalidUserCode] devID: 0x%x, userCode: 0x%x", nDevID, dwUserErrorCode); } auto rc = sp_log_client_log(m_log_client, LogType, Level, (int)dwSysErrorCode, (int)dwUserErrorCode, 0, 0, pMessage); if (rc != 0) { sp_dbg_warn("log message failed! raw msg: %s", pMessage); } else sp_dbg_info("userCode: 0x%x send", dwUserErrorCode); return SpTranslateError(rc); } ErrorCodeEnum SpEntity::LogMessage(const LogTypeEnum LogType, const SeverityLevelEnum Level, DWORD iSysErrorCode, DWORD iUserErrorCode, CAutoArray Param, const char *pMessage) { // xkm@20160726: У��dwUserErrorCode�Ƿ�Ϸ� int nDevID = m_ent->cfg->devel_id; if (iUserErrorCode != 0 && ((iUserErrorCode >> 20) & nDevID) != nDevID) { sp_dbg_warn("[InvalidUserCode] devID: 0x%x, userCode: 0x%x", nDevID, iUserErrorCode); } int rc; sp_log_client_t *client = (sp_log_client_t*)m_log_client; rc = sp_log_client_log(client, LogType, Level, (int)iSysErrorCode, (int)iUserErrorCode, (int)Param.GetCount(), (int*)&Param[0], pMessage); if (rc != 0) { sp_dbg_warn("log message failed! raw msg: %s", pMessage); } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::LogFlush() { int rc; sp_log_client_t *client = (sp_log_client_t*)m_log_client; rc = sp_log_client_flush(client); if (rc != 0) { sp_dbg_warn("flush log message failed!"); } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::OpenConfig(ConfigTypeEnum eConfigType,CSmartPointer &spConfigInfo) { IConfigInfo *pConfigInfo = new SpIniConfig(this, eConfigType); spConfigInfo.Attach(pConfigInfo); return Error_Succeed; } ErrorCodeEnum SpEntity::SetUserDefineState(DWORD dwState) { sp_env_t *env = sp_get_env(); sp_mod_mgr_t *mod_mgr = env->mod_mgr; //sp_mod_mgr_lock(mod_mgr); DWORD dwOldState = m_ent->user_state; m_ent->user_state = dwState; //sp_mod_mgr_unlock(mod_mgr); // send state chage event to shell if (dwOldState != dwState) sp_mod_entity_stub_report_user_state_change(m_stub, dwOldState, dwState); return Error_Succeed; } ErrorCodeEnum SpEntity::GetSystemStaticInfo(CSystemStaticInfo &Info) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; sp_cfg_root_ini_t *root_ini = cfg->root_ini; sp_cfg_install_ini_t *install_ini = cfg->install_ini; //char tmp[MAX_PATH]; //char *pdir; //int major, minor; int i; sp_cfg_version_info_t *version_info; memset(&Info, 0, sizeof(Info)); Info.strTerminalID = CSimpleStringA(root_ini->terminal_no); Info.strMachineType = CSimpleStringA(root_ini->machine_type); //Info.strMachineModel = CSimpleStringA(root_ini->machine_model); Info.MachineVersion = CVersion(root_ini->machine_version.major, root_ini->machine_version.minor, root_ini->machine_version.revision, root_ini->machine_version.build); Info.LatterInstallVersion = CVersion(install_ini->latter_install_version.major, install_ini->latter_install_version.minor, install_ini->latter_install_version.revision, install_ini->latter_install_version.build); if (install_ini->arr_light_pack->nelts > 0) { Info.LightPackInfos.Init(install_ini->arr_light_pack->nelts); } for (i = 0; i < install_ini->arr_light_pack->nelts; ++i) { sp_cfg_pack_info_t *pack = ARRAY_IDX(install_ini->arr_light_pack, i, sp_cfg_pack_info_t*); Info.LightPackInfos[i].strPackName = pack->name; Info.LightPackInfos[i].State = (InstallStateEnum)pack->state; Info.LightPackInfos[i].tmInstalledDate = CSmallDateTime(pack->install_time); } Info.nTotalRunCount = install_ini->total_run_count; Info.nTodayRunCount = install_ini->today_run_count; Info.tmCreateDate = install_ini->install_time; Info.tmCurrentTime = install_ini->current_startup_time; Info.strSite = root_ini->site; Info.eScreen = (ScreenEnum)root_ini->screen; Info.strEnrolAddr = root_ini->enroll_address; Info.EnrolGPS = CSphereVector(root_ini->enroll_gps_x, root_ini->enroll_gps_y); version_info = sp_cfg_find_previous_version_info(cfg, &install_ini->install_version); if (version_info) { Info.PreviousInstallVersion = CVersion(version_info->version.major, version_info->version.minor, version_info->version.revision, version_info->version.build); } else { Info.PreviousInstallVersion = CVersion(0, 0, 0, 0); } version_info = sp_cfg_find_version_info(cfg, &install_ini->install_version); if (version_info) { Info.InstallVersion = CVersion(install_ini->install_version.major, install_ini->install_version.minor, install_ini->install_version.revision, install_ini->install_version.build); Info.tmSwithOverDate = version_info->switch_time; Info.InstallPack = version_info->install_pack; Info.InstallState = (InstallStateEnum)version_info->install_state; } return Error_Succeed; } ErrorCodeEnum SpEntity::GetInstallInfo(CVersion Version,CInstallInfo &Info) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; /*sp_cfg_root_ini_t *root_ini = cfg->root_ini; sp_cfg_install_ini_t *install_ini = cfg->install_ini;*/ sp_cfg_version_info_t *version_info; sp_version_t ver = {Version.GetMajor(), Version.GetMinor(), Version.GetRevision(), Version.GetBuild()}; version_info = sp_cfg_find_version_info(cfg, &ver); if (version_info) { Info.InstallPack = version_info->install_pack; Info.InstallState = (InstallStateEnum)version_info->install_state; Info.InstallVersion = Version; Info.PreviousInstallVersion = CVersion(version_info->previous_version.major, version_info->previous_version.minor, version_info->previous_version.revision, version_info->previous_version.build); Info.tmSwithOverDate = version_info->switch_time; } else { return Error_NotExist; } return Error_Succeed; } bool SpEntity::IsPackInstalled(const char *pPackName) { if (pPackName && strlen(pPackName) > 0) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; sp_cfg_root_ini_t *root_ini = cfg->root_ini; sp_cfg_install_ini_t *install_ini = cfg->install_ini; // 先查询当前版本的轻量安装历史 if (strstr(install_ini->light_packs, pPackName) != NULL) { for(int i=0; iarr_light_pack->nelts; i++) { sp_cfg_pack_info_t *pack = ARRAY_IDX(install_ini->arr_light_pack, i, sp_cfg_pack_info_t*); if (pack && pack->name && _stricmp(pack->name, pPackName) == 0) return true; } } // 查询历史版本安装包 for(int i=0; iarr_version->nelts; i++) { sp_cfg_version_info_t *ver_info = ARRAY_IDX(cfg->install_ini->arr_version, i, sp_cfg_version_info_t*); if (strstr(ver_info->install_pack, pPackName) != NULL) return true; } } return false; } const char *SpEntity::GetCenterSettingNameBySite() { CSystemStaticInfo info; GetSystemStaticInfo(info); if ((stricmp(info.strSite, "CMB.LIB") == 0) || (stricmp(info.strSite, "CMB.SSB") == 0)) { return "CenterSetting.LAN.ini"; } else if ((stricmp(info.strSite, "CMB.LSS") == 0) || (stricmp(info.strSite, "CMB.FLB") == 0) || (stricmp(info.strSite, "CMB.OSB") == 0) || (stricmp(info.strSite, "CMB.SMM") == 0)) { return "CenterSetting.DMZ.ini"; } else { return "CenterSetting.DMZ.ini"; } } ErrorCodeEnum SpEntity::GetPath(const char *pszKey,CSimpleStringA &strPath) { sp_env_t *env = sp_get_env(); ErrorCodeEnum Error = Error_Succeed; if (!pszKey) return Error_Null; if (_stricmp(pszKey, "Root") == 0) { strPath = env->dir->root_path; } else if (_stricmp(pszKey, "RootVer") == 0) { strPath = env->dir->root_ver_path; } else if (_stricmp(pszKey, "Data") == 0) { strPath = CSimpleStringA(env->dir->obj_path); } else if (_stricmp(pszKey, "Bin") == 0) { strPath = CSimpleStringA(env->dir->bin_path); } else if (_stricmp(pszKey, "Cfg") == 0 || _stricmp(pszKey, "Etc") == 0) { strPath = CSimpleStringA(env->dir->cfg_path); } else if (_stricmp(pszKey, "Rec") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_localvideo_path); } else if (_stricmp(pszKey, "Temp") == 0 || _stricmp(pszKey, "Tmp") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_tmp_path); } else if (_stricmp(pszKey, "SysLog") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_syslog_path); } else if (_stricmp(pszKey, "InterLog") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_intlog_path); } else if (_stricmp(pszKey, "Base") == 0 || _stricmp(pszKey, "BaseDir") == 0) { strPath = CSimpleStringA(env->dir->base_path); } else if (_stricmp(pszKey, "SysRoot") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_sysroot_path); } else if (_stricmp(pszKey, "Photo") == 0 || _stricmp(pszKey, "UploadPhoto") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_uploadphoto_path); } else if (_stricmp(pszKey, "Download") == 0 || _stricmp(pszKey, "Downloads") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_downloads_path); } else if (_stricmp(pszKey, "Upgraded") == 0){ strPath = CSimpleStringA(env->cfg->root_ini->ref_upgraded_path); } else if (_stricmp(pszKey, "Ad") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_addata_path); } else if (_stricmp(pszKey, "UploadPhoto") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_uploadphoto_path); } else if (_stricmp(pszKey, "UploadVideo") == 0) { strPath = CSimpleStringA(env->cfg->root_ini->ref_uploadvideo_path); } else if (_stricmp(pszKey, "Dbg") == 0) { strPath = CSimpleStringA(env->dir->dbg_path); } else if (_stricmp(pszKey, "Slv") == 0) { strPath = CSimpleStringA(env->dir->slv_path); } else if (_stricmp(pszKey, "Dep") == 0) { strPath = CSimpleStringA(env->dir->dep_path); } else if (_stricmp(pszKey, "Ad0") == 0) { strPath = CSimpleStringA(env->dir->ad0_path); //} else if (_stricmp(pszKey, "CenterSetting") == 0) { // strPath = CSimpleStringA(env->cfg->root_ini->ref_centersetting_path); } else if (_stricmp(pszKey, "Dmp") == 0 || _stricmp(pszKey, "Dump") == 0) { strPath = CSimpleStringA(env->dir->dmp_path); } else if (_stricmp(pszKey, "RunInfo") == 0){ strPath = CSimpleStringA(env->dir->root_runinfo_path); } else if (_stricmp(pszKey, "HardwareCfg") ==0){ strPath = CSimpleStringA(env->dir->root_hardwarecfg_path); } else if (_stricmp(pszKey, "CenterSetting") == 0) { // return centersetting name by current site strPath = CSimpleStringA(env->dir->cfg_path); strPath += SPLIT_SLASH_STR; strPath += GetCenterSettingNameBySite(); } else { char *path = sp_cfg_get_path(env->cfg, pszKey); if (path) { strPath = path; } else { Error = Error_Param; } } return Error; } ErrorCodeEnum SpEntity::GetSystemRunInfo(CSystemRunInfo &Info) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; Info.eDebugLevel = (DebugLevelEnum)cfg->shell_ini->shell_debug_level; Info.tmStart = cfg->run_info->startup_time; sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_mod_t *pos; array_header_t *arr = array_make(16, sizeof(char*)); list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry) { if (pos->state) { sp_entity_t *ent; list_for_each_entry(ent, &pos->entity_list, sp_entity_t, entry) { int state = ent->state; if (state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause) { ARRAY_PUSH(arr, char*) = ent->cfg->name; } } } } Info.strRunningEntityNames.Init(arr->nelts); for (int i = 0; i < arr->nelts; ++i) { Info.strRunningEntityNames[i] = CSimpleStringA(ARRAY_IDX(arr, i, char*)); } array_free(arr); return Error_Succeed; } ErrorCodeEnum SpEntity::GetEntityBusyRate(WORD &nBusyEntity,WORD &nAllEntity) { sp_env_t *env = sp_get_env(); sp_mod_mgr_t *mod_mgr = env->mod_mgr; int nAll(0), nBusy(0); sp_mod_t *mod; list_for_each_entry(mod, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry) { if (mod->state) { sp_entity_t *ent; list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) { int state = ent->state; if (state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause) nAll++; if (state == EntityState_Busy) nBusy++; } } nBusyEntity = nBusy; nAllEntity = nAll; } return Error_Succeed; } ErrorCodeEnum SpEntity::GetRebootInfo(CSmallDateTime BeforeThisTime, CBootInfo &Info) { CSimpleStringA strPath; auto rc = GetPath("RunInfo", strPath); if (rc != Error_Succeed) return rc; strPath += SPLIT_SLASH_STR "BootLog"; sp_env_t *env = sp_get_env(); auto pRec = sp_btr_get_rec_before(strPath, env->btr_ctx, BeforeThisTime); if (pRec == NULL) return Error_NotExist; Info.tmStart = pRec->tm_start; Info.tmReboot = pRec->tm_shutdown; Info.InstallVersion = CVersion(pRec->version.major, pRec->version.minor, pRec->version.revision, pRec->version.build); Info.eTriggerReason = (RebootTriggerEnum)pRec->shutdown_reason; Info.eWay = (RebootWayEnum)pRec->shutdown_way; Info.wSameReasonTime = pRec->shutdown_reason_cnt; Info.wSameWayTime = pRec->shutdown_way_cnt; delete pRec; return Error_Succeed; } ErrorCodeEnum SpEntity::GetAllRegistSpFile(CAutoArray &Names) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; array_header_t *arr_module = cfg->shell_ini->arr_module; Names.Init(arr_module->nelts); for (int i = 0; i < arr_module->nelts; ++i) { sp_cfg_shell_module_t* mod = ARRAY_IDX(arr_module, i, sp_cfg_shell_module_t*); Names[i] = mod->name; // BugFix [Gifur@2020422] //Names[i] = ARRAY_IDX(arr_module, i, char*); } return Error_Succeed; } ErrorCodeEnum SpEntity::GetSpFileInfo(const char *pszSpName,CSpInfo &Info) { if (!pszSpName) return Error_Null; sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; sp_cfg_shell_module_t *cfg_mod = sp_cfg_get_module_by_name(cfg, pszSpName); if (!cfg_mod) return Error_NotExist; Info.strAuthor = cfg_mod->author; Info.strCompany = cfg_mod->company; Info.SoftwareVersion = CVersion((WORD)cfg_mod->version.major, (WORD)cfg_mod->version.minor, (WORD)cfg_mod->version.revision, (WORD)cfg_mod->version.build); sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_mod_t *mod = sp_mod_mgr_find_module_by_name(mod_mgr, pszSpName); if (!mod) return Error_NotExist; sp_entity_t *ent; int cnt = 0; list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) { cnt++; } Info.strEntitys.Init(cnt); int i = 0; list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) { Info.strEntitys[i++] = ent->cfg->name; } return Error_Succeed; } ErrorCodeEnum SpEntity::GetAllRegistedEntity(CAutoArray &strEntityNames, CAutoArray &wEntityDevelopIDs) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; array_header_t *arr_entity = cfg->shell_ini->arr_entity; strEntityNames.Init(arr_entity->nelts-1); wEntityDevelopIDs.Init(arr_entity->nelts-1); for (int i = 1; i < arr_entity->nelts; ++i) { // from index 1, because zero for special entity, ie. spshell entity sp_cfg_shell_entity_t *ent = ARRAY_IDX(arr_entity, i, sp_cfg_shell_entity_t*); strEntityNames[i-1] = ent->name; wEntityDevelopIDs[i-1] = ent->devel_id; } return Error_Succeed; } ErrorCodeEnum SpEntity::GetAllStartedEntity(CAutoArray &strEntityNames, CAutoArray &dwEntityInstanceIDs) { sp_env_t *env = sp_get_env(); sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_mod_t *pos; int i; array_header_t *arr = array_make(16, sizeof(sp_entity_t*)); list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry) { if (pos->state) { sp_entity_t *ent; list_for_each_entry(ent, &pos->entity_list, sp_entity_t, entry) { int state = ent->state; if (state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause) { ARRAY_PUSH(arr, sp_entity_t*) = ent; } } } } strEntityNames.Init(arr->nelts); dwEntityInstanceIDs.Init(arr->nelts); for (i = 0; i < arr->nelts; ++i) { sp_entity_t *ent = ARRAY_IDX(arr, i, sp_entity_t*); strEntityNames[i] = ent->cfg->name; dwEntityInstanceIDs[i] = ent->instance_id; } // {bug} forget array_free(arr) array_free(arr); return Error_Succeed; } ErrorCodeEnum SpEntity::GetSelfEntityRunInfo(CEntityRunInfo &Info) { return GetEntityRunInfo(m_ent->cfg->name, Info); } ErrorCodeEnum SpEntity::GetEntityStaticInfo(const char *pszEntityName,CEntityStaticInfo &Info) { if (!pszEntityName) return Error_Null; sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszEntityName); return ::GetEntityStaticInfo(Info, ent); } ErrorCodeEnum SpEntity::GetEntityStaticInfo(WORD wEntitySerialNO,CEntityStaticInfo &Info) { sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_devel_id(env->mod_mgr, wEntitySerialNO); return ::GetEntityStaticInfo(Info, ent); } ErrorCodeEnum SpEntity::GetEntityRunInfo(const char *pszEntityName, CEntityRunInfo &Info) { sp_env_t *env = sp_get_env(); if (!pszEntityName) return Error_Null; sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(mod_mgr, pszEntityName); if (!ent) return Error_NotExist; Info.dwEntityInstanceID = (DWORD)ent->instance_id; Info.tmFirstStart = ent->first_start_time; Info.tmLastStart = ent->last_start_time; Info.bService = !!ent->service_flag; Info.eState = (EntityStateEnum)ent->state; Info.tmBeginCurrentState = ent->state_start_time; Info.dwProcessID = (DWORD)ent->mod->process.pid; Info.eDebugLevel = (DebugLevelEnum)ent->cfg->debug_level; Info.dwUserState = (DWORD)ent->user_state; return Error_Succeed; } ErrorCodeEnum SpEntity::GetEntityName(WORD wEntityDevelopID, CSimpleStringA &strName) { sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_devel_id(env->mod_mgr, wEntityDevelopID); if (ent) { strName = ent->cfg->name; } else { return Error_NotExist; } return Error_Succeed; } ErrorCodeEnum SpEntity::GetEntityName(DWORD dwEntityInstanceID, CSimpleStringA &strName) { assert(dwEntityInstanceID != 0); sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_inst_id(env->mod_mgr, dwEntityInstanceID); if (ent) { strName = ent->cfg->name; } else { return Error_NotExist; } return Error_Succeed; } ErrorCodeEnum SpEntity::GetModuleName(DWORD nModuleID, CSimpleStringA &strName) { if (nModuleID != SP_INVALID_MOD_ID) { sp_env_t *env = sp_get_env(); sp_mod_t *mod = sp_mod_mgr_find_module_by_idx(env->mod_mgr, nModuleID); if (mod) { strName = mod->cfg->name; return Error_Succeed; } else { return Error_NotExist; } } return Error_Param; } ErrorCodeEnum SpEntity::GetEntitySessionInfo(const char *pszEntityName, CAutoArray &Infos) { iobuffer_t *req_pkt = iobuffer_create(-1, -1); iobuffer_t *ans_pkt = NULL; auto rc = AskEntityByRPC(pszEntityName, ENTITY_CMD_REQ_QUERY_ENTITY_SESSIONS, &req_pkt, &ans_pkt); if (rc == Error_Succeed) { int nCount(0); iobuffer_read(ans_pkt, IOBUF_T_I4, &nCount, NULL); auto pCfg = sp_get_env()->cfg; Infos.Init(nCount); for (int i = 0; i < nCount; ++i) { int nFromSvcID, nToSvcID, nBeginTime, nState, nStateBeginTime; iobuffer_format_read(ans_pkt, "44444", &nFromSvcID, &nToSvcID, &nBeginTime, &nState, &nStateBeginTime); Infos[i].strCallerEntity = sp_cfg_get_entity_by_idx(pCfg, nFromSvcID)->name; Infos[i].strServiceEntity = sp_cfg_get_entity_by_idx(pCfg, nToSvcID)->name; Infos[i].tmStart = CSmallDateTime(nBeginTime); Infos[i].eState = (SessionStateEnum)nState; Infos[i].tmBeginState = CSmallDateTime(nStateBeginTime); } } if (req_pkt) iobuffer_dec_ref(req_pkt); if (ans_pkt) iobuffer_dec_ref(ans_pkt); return rc; } bool SpEntity::HasPrivilege() { return !!m_cfg_ent->privilege; } CSmartPointer SpEntity::GetPrivilegeFunction() { return NULL; } ErrorCodeEnum SpEntity::PostQuit() { ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); int v = m_ent->cfg->idx; iobuffer_write(pkt, IOBUF_T_I4, &v, 0); Error = PostInfoShell(SHELL_CMD_INFO_ENTITY_QUIT, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntity::PostReload() { ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); int v = m_ent->cfg->idx; iobuffer_write(pkt, IOBUF_T_I4, &v, 0); Error = PostInfoShell(SHELL_CMD_INFO_ENTITY_RELOAD, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntity::PostEntityTaskFIFO(ITaskSp *pTask) { threadpool_t *threadpool = sp_svc_get_threadpool(m_svc); int rc; rc = threadpool_post_workitem_fifo2(threadpool, NULL, &task_callback, pTask, (param_size_t)((intptr_t)this), 0); return rc == 0 ? Error_Succeed : Error_Unexpect; } ErrorCodeEnum SpEntity::PostEntityTaskLIFO(ITaskSp *pTask) { threadpool_t *threadpool = sp_svc_get_threadpool(m_svc); int rc; rc = threadpool_post_workitem_lifo2(threadpool, NULL, &task_callback, pTask, (param_size_t)((intptr_t)this), 0); return rc == 0 ? Error_Succeed : Error_Unexpect; } ErrorCodeEnum SpEntity::PostThreadPoolTask(ITaskSp *pTask) { int rc = threadpool_post_workitem_fifo2(m_tpool, NULL, &task_callback, pTask, (param_size_t)((intptr_t)this), 0); return rc == 0 ? Error_Succeed : Error_Unexpect; } ErrorCodeEnum SpEntity::StartTcpBridgeServer(unsigned short port) { if (port >4506 || port < 4502) return Error_Duplication; #ifdef _DEBUG const char *ip = "0.0.0.0"; #else const char *ip = "127.0.0.1"; #endif if (m_tbs) return Error_Duplication; int rc = sp_tbs_create(m_ses_mgr, ip, port, &m_tbs); if (rc == 0) { rc = sp_tbs_start(m_tbs); if (rc != 0) { sp_tbs_destroy(m_tbs); m_tbs = NULL; } } return SpTranslateError(rc); } ErrorCodeEnum SpEntity::StopTcpBridgeServer() { if (m_tbs) { sp_tbs_stop(m_tbs); sp_tbs_destroy(m_tbs); m_tbs = NULL; return Error_Succeed; } else { return Error_NotInit; } } ErrorCodeEnum SpEntity::RequestCloseDelay(WORD nSecond) { return Error_NotImpl; } void SpEntity::SendLog(const LogTypeEnum eLogType,const SeverityLevelEnum eLevel,DWORD dwUserEventCode,CAutoArray Param,const char *pszMessage) { LogMessage(eLogType, eLevel, 0, dwUserEventCode, Param, pszMessage); } ErrorCodeEnum SpEntity::VerifySignature(const char *pszSignedFile, CSimpleStringA &strErrInfo) { #ifdef _WIN32 CCodeSignVerify verify; CSignInfo signInfo; if (!verify.VerifySignature(pszSignedFile, signInfo)) { strErrInfo = verify.GetErrorMsg(); return Error_FailVerify; } // xkm@20140905: check cer file's hash is consistent with spbase's hash sp_env_t* env = sp_get_env(); assert(env != NULL); auto pShellCfg = env->cfg->shell_ini; if (pShellCfg->spbase_sign_cert_hash != NULL && stricmp(pShellCfg->spbase_sign_cert_hash, signInfo.strSignCertHash) != 0) { strErrInfo = "signing certificate is not authorized certificate."; return Error_FailVerify; } strErrInfo = signInfo.strSignCertHash; #else strErrInfo = "TODO: not implement VerifySignature current times."; #endif //_WIN32 return Error_Succeed; } ErrorCodeEnum SpEntity::ShowFatalError(const char *pszMsg) { LogError(Severity_High, Error_Unrecover, 0, pszMsg); ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); iobuffer_write(pkt, IOBUF_T_STR, pszMsg, -1); //int nBlueScreen = 1; //iobuffer_write(pkt, IOBUF_T_I4, &nBlueScreen, 0); Error = PostInfoShell(SHELL_CMD_INFO_FATAL_ERROR_DISPLAY, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntity::ShowStartupInfo(const char *pszMsg) { LogEvent(Severity_High, 0, pszMsg); ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); iobuffer_write(pkt, IOBUF_T_STR, pszMsg, -1); Error = PostInfoShell(SHELL_CMD_INFO_STARTUP_INFO_DISPLAY, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntity::InitLogCurrentThread() { #ifdef _WIN32 SetthreadGroup(GetCurrentThreadId(), get_cfg_ent()->name); getEntityResource()->m_Entity = this; #else GetSpModule()->SetThreadEntity(this); #endif //_WIN32 return Error_Succeed; } ErrorCodeEnum SpEntity::ConnectRemoteEntity(CClientSessionBase *pClientSession, const char *pszRemoteEntity, const char *pszParam, CSmartPointer &pAsynWaitSp) { ErrorCodeEnum Error; if (!pClientSession || !pszRemoteEntity) return Error_Param; if (pClientSession->m_pSessionFunction) return Error_Param; SpClientSessionFunction *pFunction = new SpClientSessionFunction(this, pClientSession, pszRemoteEntity); Error = pFunction->Begin(pszParam); if (Error == Error_Succeed) { pClientSession->m_pSessionFunction = pFunction; pAsynWaitSp.Attach(pFunction, pFunction->GetRefCountPtr()); } else { pFunction->DecrementRef(); } Dbg("connect to %s %s", pszRemoteEntity, Error_Succeed == Error ? "success" : "fail"); return Error; } ErrorCodeEnum SpEntity::RedirectSession(CClientSessionBase *pClientSession) { return Error_NotImpl; } ErrorCodeEnum SpEntity::RedirectSession(const char *pszSuggestEntity) { if (pszSuggestEntity) { sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszSuggestEntity); if (ent) { m_redirect_entity_cache = ent; return Error_Succeed; } else { sp_dbg_warn("RedirectSession failed, cannot find entity %s", pszSuggestEntity); return Error_Param; } } return Error_Param; } ErrorCodeEnum SpEntity::RedirectSubscribBroadcast(CUUID SubID, const char *pszSugguestEntity) { if (pszSugguestEntity) { sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszSugguestEntity); if (ent) { sp_uid_t uid = SubID.m_nUUID64; sp_mod_entity_stub_finish_redirect_subscribe(m_stub, &uid, ent->cfg->idx); } else { return Error_NotExist; } } else { return Error_Param; } return Error_Succeed; } ErrorCodeEnum SpEntity::AskShell(int call_type, iobuffer_t **req_pkt, iobuffer_t **ans_pkt) { ErrorCodeEnum Error; iobuffer_t *r_pkt = NULL; if (!req_pkt || !*req_pkt || !ans_pkt) return Error_Param; if (*ans_pkt) return Error_Param; // must be null so can return pkt SpAsyncWaitRPC *pAsyncWait = new SpAsyncWaitRPC(this, req_pkt, call_type); Error = pAsyncWait->Begin(); if (Error == Error_Succeed) { Error = pAsyncWait->WaitAnswer(INFINITE); if (Error == Error_Succeed) { CAutoBuffer AnsBuf; bool bEnd; Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd); if (Error == Error_Succeed) { iobuffer_t *pkt = iobuffer_create(-1, AnsBuf.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount()); *ans_pkt = pkt; } } } pAsyncWait->DecrementRef(); // xkm@20150115 return Error; } ErrorCodeEnum SpEntity::AskEntityByRPC(const char *pszEntityName, int call_type, iobuffer_t **req_pkt, iobuffer_t **ans_pkt) { ErrorCodeEnum Error; iobuffer_t *r_pkt = NULL; if (!req_pkt || !*req_pkt || !ans_pkt) return Error_Param; if (*ans_pkt) return Error_Param; // must be null so can return pkt SpAsyncWaitRPC *pAsyncWait = new SpAsyncWaitRPC(this, req_pkt, call_type); Error = pAsyncWait->Begin(pszEntityName); if (Error == Error_Succeed) { Error = pAsyncWait->WaitAnswer(INFINITE); if (Error == Error_Succeed) { CAutoBuffer AnsBuf; bool bEnd; Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd); if (Error == Error_Succeed) { iobuffer_t *pkt = iobuffer_create(-1, AnsBuf.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount()); *ans_pkt = pkt; } } } pAsyncWait->DecrementRef(); // xkm@20150115 return Error; } void SpEntity::__on_rpc_request(sp_rpc_client_mgr_t *mgr, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt, void *user_data) { SpEntity *pThis = static_cast(user_data); #if _DEBUG //Dbg("on_rpc_req(), calltype: %d", call_type); #endif if (call_type == ENTITY_CMD_REQ_QUERY_ENTITY_SESSIONS) { pThis->OnQueryEntitySessions(epid, svc_id, rpc_id); } } void SpEntity::OnQueryEntitySessions(int epid, int svc_id, int rpc_id) { int rc; int nCount(0); int nResult(0); sp_ses_info_t* ret = sp_ses_mgr_get_ses_info(m_ses_mgr, &nCount); iobuffer_t *ans_pkt = iobuffer_create(-1, -1); iobuffer_write(ans_pkt, IOBUF_T_I4, &nResult, 0); iobuffer_write(ans_pkt, IOBUF_T_I4, &nCount, 0); for(int i=0; iOnStarted(); } } void SpEntity::FinishClose(ErrorCodeEnum Error) { sp_mod_entity_stub_finish_stop(m_stub, Error); if (Error == Error_Succeed) { Term(); } } void SpEntity::FinishPause(ErrorCodeEnum Error) { sp_mod_entity_stub_finish_pause(m_stub, Error); if (Error == Error_Succeed) { m_pEntityBase->OnPaused(); } } void SpEntity::FinishContinue(ErrorCodeEnum Error) { sp_mod_entity_stub_finish_continue(m_stub, Error); if (Error == Error_Succeed) { m_pEntityBase->OnContinued(); } } void SpEntity::FinishSelfTest(ErrorCodeEnum Error) { sp_mod_entity_stub_finish_test(m_stub, Error); }