1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci#include <ctype.h> 16d9f0492fSopenharmony_ci 17d9f0492fSopenharmony_ci#include "init_param.h" 18d9f0492fSopenharmony_ci#include "init_service_manager.h" 19d9f0492fSopenharmony_ci#include "init_utils.h" 20d9f0492fSopenharmony_ci#include "param_manager.h" 21d9f0492fSopenharmony_ci#include "param_message.h" 22d9f0492fSopenharmony_ci#include "param_utils.h" 23d9f0492fSopenharmony_ci#include "trigger_checker.h" 24d9f0492fSopenharmony_ci#include "trigger_manager.h" 25d9f0492fSopenharmony_ci#include "securec.h" 26d9f0492fSopenharmony_ci#include "hookmgr.h" 27d9f0492fSopenharmony_ci#include "bootstage.h" 28d9f0492fSopenharmony_ci 29d9f0492fSopenharmony_ci#define MAX_TRIGGER_COUNT_RUN_ONCE 20 30d9f0492fSopenharmony_ci#define MAX_TRIGGER_NAME_LENGTH 256 31d9f0492fSopenharmony_cistatic TriggerWorkSpace g_triggerWorkSpace = {}; 32d9f0492fSopenharmony_ci 33d9f0492fSopenharmony_cistatic int DoTriggerExecute_(const TriggerNode *trigger, const char *content, uint32_t size) 34d9f0492fSopenharmony_ci{ 35d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return -1, "Invalid trigger"); 36d9f0492fSopenharmony_ci PARAM_LOGV("Do execute trigger %s type: %d", GetTriggerName(trigger), trigger->type); 37d9f0492fSopenharmony_ci PARAM_CHECK(trigger->type <= TRIGGER_UNKNOW, return -1, "Invalid trigger type %d", trigger->type); 38d9f0492fSopenharmony_ci CommandNode *cmd = GetNextCmdNode((JobNode *)trigger, NULL); 39d9f0492fSopenharmony_ci while (cmd != NULL) { 40d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST 41d9f0492fSopenharmony_ci DoCmdByIndex(cmd->cmdKeyIndex, cmd->content, &cmd->cfgContext); 42d9f0492fSopenharmony_ci#endif 43d9f0492fSopenharmony_ci cmd = GetNextCmdNode((JobNode *)trigger, cmd); 44d9f0492fSopenharmony_ci } 45d9f0492fSopenharmony_ci return 0; 46d9f0492fSopenharmony_ci} 47d9f0492fSopenharmony_ci 48d9f0492fSopenharmony_cistatic int DoTriggerCheckResult(TriggerNode *trigger, const char *content, uint32_t size) 49d9f0492fSopenharmony_ci{ 50d9f0492fSopenharmony_ci UNUSED(content); 51d9f0492fSopenharmony_ci UNUSED(size); 52d9f0492fSopenharmony_ci if (TRIGGER_IN_QUEUE(trigger)) { 53d9f0492fSopenharmony_ci PARAM_LOGI("DoTiggerExecute trigger %s has been waiting execute", GetTriggerName(trigger)); 54d9f0492fSopenharmony_ci return 0; 55d9f0492fSopenharmony_ci } 56d9f0492fSopenharmony_ci TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_QUEUE); 57d9f0492fSopenharmony_ci PARAM_LOGV("Add trigger %s to execute queue", GetTriggerName(trigger)); 58d9f0492fSopenharmony_ci ExecuteQueuePush(&g_triggerWorkSpace, trigger); 59d9f0492fSopenharmony_ci return 0; 60d9f0492fSopenharmony_ci} 61d9f0492fSopenharmony_ci 62d9f0492fSopenharmony_cistatic int ExecuteTriggerImmediately(TriggerNode *trigger, const char *content, uint32_t size) 63d9f0492fSopenharmony_ci{ 64d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return -1, "Invalid trigger"); 65d9f0492fSopenharmony_ci PARAM_LOGV("ExecuteTriggerImmediately trigger %s", GetTriggerName(trigger)); 66d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(&g_triggerWorkSpace, trigger->type); 67d9f0492fSopenharmony_ci if (triggerHead != NULL) { 68d9f0492fSopenharmony_ci triggerHead->executeTrigger(trigger, content, size); 69d9f0492fSopenharmony_ci TRIGGER_CLEAR_FLAG(trigger, TRIGGER_FLAGS_QUEUE); 70d9f0492fSopenharmony_ci 71d9f0492fSopenharmony_ci if (TRIGGER_TEST_FLAG(trigger, TRIGGER_FLAGS_ONCE)) { 72d9f0492fSopenharmony_ci FreeTrigger(&g_triggerWorkSpace, trigger); 73d9f0492fSopenharmony_ci } 74d9f0492fSopenharmony_ci } 75d9f0492fSopenharmony_ci return 0; 76d9f0492fSopenharmony_ci} 77d9f0492fSopenharmony_ci 78d9f0492fSopenharmony_cistatic void StartTriggerExecute_(TriggerNode *trigger, const char *content, uint32_t size) 79d9f0492fSopenharmony_ci{ 80d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(&g_triggerWorkSpace, trigger->type); 81d9f0492fSopenharmony_ci if (triggerHead != NULL) { 82d9f0492fSopenharmony_ci PARAM_LOGV("StartTriggerExecute_ trigger %s flags:0x%04x", 83d9f0492fSopenharmony_ci GetTriggerName(trigger), trigger->flags); 84d9f0492fSopenharmony_ci triggerHead->executeTrigger(trigger, content, size); 85d9f0492fSopenharmony_ci TRIGGER_CLEAR_FLAG(trigger, TRIGGER_FLAGS_QUEUE); 86d9f0492fSopenharmony_ci if (TRIGGER_TEST_FLAG(trigger, TRIGGER_FLAGS_SUBTRIGGER)) { // boot && xxx=xxx trigger 87d9f0492fSopenharmony_ci const char *condition = triggerHead->getCondition(trigger); 88d9f0492fSopenharmony_ci CheckTrigger(&g_triggerWorkSpace, TRIGGER_UNKNOW, condition, strlen(condition), ExecuteTriggerImmediately); 89d9f0492fSopenharmony_ci } 90d9f0492fSopenharmony_ci if (TRIGGER_TEST_FLAG(trigger, TRIGGER_FLAGS_ONCE)) { 91d9f0492fSopenharmony_ci FreeTrigger(&g_triggerWorkSpace, trigger); 92d9f0492fSopenharmony_ci } 93d9f0492fSopenharmony_ci } 94d9f0492fSopenharmony_ci} 95d9f0492fSopenharmony_ci 96d9f0492fSopenharmony_cistatic void ExecuteQueueWork(uint32_t maxCount, void (*bootStateChange)(int start, const char *)) 97d9f0492fSopenharmony_ci{ 98d9f0492fSopenharmony_ci uint32_t executeCount = 0; 99d9f0492fSopenharmony_ci TriggerNode *trigger = ExecuteQueuePop(&g_triggerWorkSpace); 100d9f0492fSopenharmony_ci char triggerName[MAX_TRIGGER_NAME_LENGTH] = {0}; 101d9f0492fSopenharmony_ci while (trigger != NULL) { 102d9f0492fSopenharmony_ci int ret = strcpy_s(triggerName, sizeof(triggerName), GetTriggerName(trigger)); 103d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return, "strcpy triggerName failed!"); 104d9f0492fSopenharmony_ci if (bootStateChange != NULL) { 105d9f0492fSopenharmony_ci bootStateChange(0, triggerName); 106d9f0492fSopenharmony_ci } 107d9f0492fSopenharmony_ci 108d9f0492fSopenharmony_ci StartTriggerExecute_(trigger, NULL, 0); 109d9f0492fSopenharmony_ci if (bootStateChange != NULL) { 110d9f0492fSopenharmony_ci bootStateChange(1, triggerName); 111d9f0492fSopenharmony_ci } 112d9f0492fSopenharmony_ci executeCount++; 113d9f0492fSopenharmony_ci if (executeCount > maxCount) { 114d9f0492fSopenharmony_ci break; 115d9f0492fSopenharmony_ci } 116d9f0492fSopenharmony_ci trigger = ExecuteQueuePop(&g_triggerWorkSpace); 117d9f0492fSopenharmony_ci } 118d9f0492fSopenharmony_ci} 119d9f0492fSopenharmony_ci 120d9f0492fSopenharmony_ciPARAM_STATIC void ProcessBeforeEvent(const ParamTaskPtr stream, 121d9f0492fSopenharmony_ci uint64_t eventId, const uint8_t *content, uint32_t size) 122d9f0492fSopenharmony_ci{ 123d9f0492fSopenharmony_ci PARAM_LOGV("ProcessBeforeEvent %s ", (char *)content); 124d9f0492fSopenharmony_ci switch (eventId) { 125d9f0492fSopenharmony_ci case EVENT_TRIGGER_PARAM: { 126d9f0492fSopenharmony_ci CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM, 127d9f0492fSopenharmony_ci (const char *)content, size, DoTriggerCheckResult); 128d9f0492fSopenharmony_ci ExecuteQueueWork(MAX_TRIGGER_COUNT_RUN_ONCE, NULL); 129d9f0492fSopenharmony_ci break; 130d9f0492fSopenharmony_ci } 131d9f0492fSopenharmony_ci case EVENT_TRIGGER_BOOT: { 132d9f0492fSopenharmony_ci if (g_triggerWorkSpace.bootStateChange != NULL) { 133d9f0492fSopenharmony_ci g_triggerWorkSpace.bootStateChange(0, (const char *)content); 134d9f0492fSopenharmony_ci } 135d9f0492fSopenharmony_ci CheckTrigger(&g_triggerWorkSpace, TRIGGER_BOOT, 136d9f0492fSopenharmony_ci (const char *)content, size, DoTriggerCheckResult); 137d9f0492fSopenharmony_ci ExecuteQueueWork(1, NULL); 138d9f0492fSopenharmony_ci if (g_triggerWorkSpace.bootStateChange != NULL) { 139d9f0492fSopenharmony_ci g_triggerWorkSpace.bootStateChange(1, (const char *)content); 140d9f0492fSopenharmony_ci } 141d9f0492fSopenharmony_ci ExecuteQueueWork(MAX_TRIGGER_COUNT_RUN_ONCE, g_triggerWorkSpace.bootStateChange); 142d9f0492fSopenharmony_ci break; 143d9f0492fSopenharmony_ci } 144d9f0492fSopenharmony_ci case EVENT_TRIGGER_PARAM_WAIT: { 145d9f0492fSopenharmony_ci CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM_WAIT, 146d9f0492fSopenharmony_ci (const char *)content, size, ExecuteTriggerImmediately); 147d9f0492fSopenharmony_ci break; 148d9f0492fSopenharmony_ci } 149d9f0492fSopenharmony_ci case EVENT_TRIGGER_PARAM_WATCH: { 150d9f0492fSopenharmony_ci CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM_WATCH, 151d9f0492fSopenharmony_ci (const char *)content, size, ExecuteTriggerImmediately); 152d9f0492fSopenharmony_ci break; 153d9f0492fSopenharmony_ci } 154d9f0492fSopenharmony_ci default: 155d9f0492fSopenharmony_ci break; 156d9f0492fSopenharmony_ci } 157d9f0492fSopenharmony_ci} 158d9f0492fSopenharmony_ci 159d9f0492fSopenharmony_cistatic void SendTriggerEvent(int type, const char *content, uint32_t contentLen) 160d9f0492fSopenharmony_ci{ 161d9f0492fSopenharmony_ci PARAM_CHECK(content != NULL, return, "Invalid param"); 162d9f0492fSopenharmony_ci PARAM_LOGV("SendTriggerEvent type %d content %s", type, content); 163d9f0492fSopenharmony_ci ParamEventSend(g_triggerWorkSpace.eventHandle, (uint64_t)type, content, contentLen); 164d9f0492fSopenharmony_ci} 165d9f0492fSopenharmony_ci 166d9f0492fSopenharmony_civoid PostParamTrigger(int type, const char *name, const char *value) 167d9f0492fSopenharmony_ci{ 168d9f0492fSopenharmony_ci PARAM_CHECK(name != NULL && value != NULL, return, "Invalid param"); 169d9f0492fSopenharmony_ci uint32_t bufferSize = strlen(name) + strlen(value) + 1 + 1 + 1; 170d9f0492fSopenharmony_ci PARAM_CHECK(bufferSize < (PARAM_CONST_VALUE_LEN_MAX + PARAM_NAME_LEN_MAX + 1 + 1 + 1), 171d9f0492fSopenharmony_ci return, "bufferSize is longest %d", bufferSize); 172d9f0492fSopenharmony_ci char *buffer = (char *)calloc(1, bufferSize); 173d9f0492fSopenharmony_ci PARAM_CHECK(buffer != NULL, return, "Failed to alloc memory for param %s", name); 174d9f0492fSopenharmony_ci int ret = sprintf_s(buffer, bufferSize - 1, "%s=%s", name, value); 175d9f0492fSopenharmony_ci PARAM_CHECK(ret > EOK, free(buffer); 176d9f0492fSopenharmony_ci return, "Failed to copy param"); 177d9f0492fSopenharmony_ci SendTriggerEvent(type, buffer, strlen(buffer)); 178d9f0492fSopenharmony_ci free(buffer); 179d9f0492fSopenharmony_ci} 180d9f0492fSopenharmony_ci 181d9f0492fSopenharmony_civoid PostTrigger(EventType type, const char *content, uint32_t contentLen) 182d9f0492fSopenharmony_ci{ 183d9f0492fSopenharmony_ci PARAM_CHECK(content != NULL && contentLen > 0, return, "Invalid param"); 184d9f0492fSopenharmony_ci SendTriggerEvent(type, content, contentLen); 185d9f0492fSopenharmony_ci} 186d9f0492fSopenharmony_ci 187d9f0492fSopenharmony_cistatic int GetTriggerType(const char *type) 188d9f0492fSopenharmony_ci{ 189d9f0492fSopenharmony_ci if (strncmp("param:", type, strlen("param:")) == 0) { 190d9f0492fSopenharmony_ci return TRIGGER_PARAM; 191d9f0492fSopenharmony_ci } 192d9f0492fSopenharmony_ci if (strncmp("boot-service:", type, strlen("boot-service:")) == 0) { 193d9f0492fSopenharmony_ci return TRIGGER_BOOT; 194d9f0492fSopenharmony_ci } 195d9f0492fSopenharmony_ci const char *triggerTypeStr[] = { 196d9f0492fSopenharmony_ci "pre-init", "boot", "early-init", "init", "early-init", "late-init", "post-init", 197d9f0492fSopenharmony_ci "fs", "early-fs", "post-fs", "late-fs", "early-boot", "post-fs-data", "reboot", "suspend" 198d9f0492fSopenharmony_ci }; 199d9f0492fSopenharmony_ci for (size_t i = 0; i < ARRAY_LENGTH(triggerTypeStr); i++) { 200d9f0492fSopenharmony_ci if (strcmp(triggerTypeStr[i], type) == 0) { 201d9f0492fSopenharmony_ci return TRIGGER_BOOT; 202d9f0492fSopenharmony_ci } 203d9f0492fSopenharmony_ci } 204d9f0492fSopenharmony_ci return TRIGGER_UNKNOW; 205d9f0492fSopenharmony_ci} 206d9f0492fSopenharmony_ci 207d9f0492fSopenharmony_cistatic int GetCommandInfo(const char *cmdLine, int *cmdKeyIndex, char **content) 208d9f0492fSopenharmony_ci{ 209d9f0492fSopenharmony_ci const char *matchCmd = GetMatchCmd(cmdLine, cmdKeyIndex); 210d9f0492fSopenharmony_ci PARAM_CHECK(matchCmd != NULL, return -1, "Command not support %s", cmdLine); 211d9f0492fSopenharmony_ci char *str = strstr(cmdLine, matchCmd); 212d9f0492fSopenharmony_ci if (str != NULL) { 213d9f0492fSopenharmony_ci str += strlen(matchCmd); 214d9f0492fSopenharmony_ci } 215d9f0492fSopenharmony_ci while (str != NULL && isspace(*str)) { 216d9f0492fSopenharmony_ci str++; 217d9f0492fSopenharmony_ci } 218d9f0492fSopenharmony_ci *content = str; 219d9f0492fSopenharmony_ci return 0; 220d9f0492fSopenharmony_ci} 221d9f0492fSopenharmony_ci 222d9f0492fSopenharmony_cistatic void ParseJobHookExecute(const char *name, const cJSON *jobNode) 223d9f0492fSopenharmony_ci{ 224d9f0492fSopenharmony_ci JOB_PARSE_CTX context; 225d9f0492fSopenharmony_ci 226d9f0492fSopenharmony_ci context.jobName = name; 227d9f0492fSopenharmony_ci context.jobNode = jobNode; 228d9f0492fSopenharmony_ci 229d9f0492fSopenharmony_ci (void)HookMgrExecute(GetBootStageHookMgr(), INIT_JOB_PARSE, (void *)(&context), NULL); 230d9f0492fSopenharmony_ci} 231d9f0492fSopenharmony_ci 232d9f0492fSopenharmony_cistatic int ParseTrigger_(const TriggerWorkSpace *workSpace, 233d9f0492fSopenharmony_ci const cJSON *triggerItem, int (*checkJobValid)(const char *jobName), const ConfigContext *cfgContext) 234d9f0492fSopenharmony_ci{ 235d9f0492fSopenharmony_ci PARAM_CHECK(triggerItem != NULL, return -1, "Invalid file"); 236d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list"); 237d9f0492fSopenharmony_ci char *name = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "name")); 238d9f0492fSopenharmony_ci PARAM_CHECK(name != NULL, return -1, "Can not get name from cfg"); 239d9f0492fSopenharmony_ci char *condition = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "condition")); 240d9f0492fSopenharmony_ci int type = GetTriggerType(name); 241d9f0492fSopenharmony_ci PARAM_CHECK(type <= TRIGGER_UNKNOW, return -1, "Failed to get trigger index"); 242d9f0492fSopenharmony_ci if (type != TRIGGER_BOOT && checkJobValid != NULL && checkJobValid(name) != 0) { 243d9f0492fSopenharmony_ci PARAM_LOGI("Trigger %s not exist in group", name); 244d9f0492fSopenharmony_ci return 0; 245d9f0492fSopenharmony_ci } 246d9f0492fSopenharmony_ci 247d9f0492fSopenharmony_ci TriggerHeader *header = GetTriggerHeader(workSpace, type); 248d9f0492fSopenharmony_ci PARAM_CHECK(header != NULL, return -1, "Failed to get header %d", type); 249d9f0492fSopenharmony_ci JobNode *trigger = UpdateJobTrigger(workSpace, type, condition, name); 250d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return -1, "Failed to create trigger %s", name); 251d9f0492fSopenharmony_ci PARAM_LOGV("ParseTrigger %s type %d count %d", name, type, header->triggerCount); 252d9f0492fSopenharmony_ci cJSON *cmdItems = cJSON_GetObjectItem(triggerItem, CMDS_ARR_NAME_IN_JSON); 253d9f0492fSopenharmony_ci if (cmdItems == NULL || !cJSON_IsArray(cmdItems)) { 254d9f0492fSopenharmony_ci return 0; 255d9f0492fSopenharmony_ci } 256d9f0492fSopenharmony_ci int cmdLinesCnt = cJSON_GetArraySize(cmdItems); 257d9f0492fSopenharmony_ci PARAM_CHECK(cmdLinesCnt > 0, return -1, "Command array size must positive %s", name); 258d9f0492fSopenharmony_ci 259d9f0492fSopenharmony_ci int ret; 260d9f0492fSopenharmony_ci int cmdKeyIndex = 0; 261d9f0492fSopenharmony_ci for (int i = 0; (i < cmdLinesCnt) && (i < TRIGGER_MAX_CMD); ++i) { 262d9f0492fSopenharmony_ci char *cmdLineStr = cJSON_GetStringValue(cJSON_GetArrayItem(cmdItems, i)); 263d9f0492fSopenharmony_ci PARAM_CHECK(cmdLineStr != NULL, continue, "Command is null"); 264d9f0492fSopenharmony_ci 265d9f0492fSopenharmony_ci char *content = NULL; 266d9f0492fSopenharmony_ci ret = GetCommandInfo(cmdLineStr, &cmdKeyIndex, &content); 267d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, continue, "Command not support %s", cmdLineStr); 268d9f0492fSopenharmony_ci ret = AddCommand(trigger, (uint32_t)cmdKeyIndex, content, cfgContext); 269d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, continue, "Failed to add command %s", cmdLineStr); 270d9f0492fSopenharmony_ci header->cmdNodeCount++; 271d9f0492fSopenharmony_ci } 272d9f0492fSopenharmony_ci return 0; 273d9f0492fSopenharmony_ci} 274d9f0492fSopenharmony_ci 275d9f0492fSopenharmony_ciint ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *jobName), void *context) 276d9f0492fSopenharmony_ci{ 277d9f0492fSopenharmony_ci PARAM_CHECK(g_triggerWorkSpace.eventHandle != NULL, return -1, "Invalid trigger data"); 278d9f0492fSopenharmony_ci PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file"); 279d9f0492fSopenharmony_ci ConfigContext *cfgContext = (ConfigContext *)context; 280d9f0492fSopenharmony_ci cJSON *triggers = cJSON_GetObjectItemCaseSensitive(fileRoot, TRIGGER_ARR_NAME_IN_JSON); 281d9f0492fSopenharmony_ci if (triggers == NULL || !cJSON_IsArray(triggers)) { 282d9f0492fSopenharmony_ci return 0; 283d9f0492fSopenharmony_ci } 284d9f0492fSopenharmony_ci int size = cJSON_GetArraySize(triggers); 285d9f0492fSopenharmony_ci PARAM_CHECK(size > 0, return -1, "Trigger array size must positive"); 286d9f0492fSopenharmony_ci 287d9f0492fSopenharmony_ci for (int i = 0; i < size && i < TRIGGER_MAX_CMD; ++i) { 288d9f0492fSopenharmony_ci cJSON *item = cJSON_GetArrayItem(triggers, i); 289d9f0492fSopenharmony_ci ParseTrigger_(&g_triggerWorkSpace, item, checkJobValid, cfgContext); 290d9f0492fSopenharmony_ci /* 291d9f0492fSopenharmony_ci * execute job parsing hooks 292d9f0492fSopenharmony_ci */ 293d9f0492fSopenharmony_ci ParseJobHookExecute(cJSON_GetStringValue(cJSON_GetObjectItem(item, "name")), item); 294d9f0492fSopenharmony_ci } 295d9f0492fSopenharmony_ci return 0; 296d9f0492fSopenharmony_ci} 297d9f0492fSopenharmony_ci 298d9f0492fSopenharmony_ciint CheckAndMarkTrigger(int type, const char *name) 299d9f0492fSopenharmony_ci{ 300d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(&g_triggerWorkSpace, type); 301d9f0492fSopenharmony_ci if (triggerHead) { 302d9f0492fSopenharmony_ci return triggerHead->checkAndMarkTrigger(&g_triggerWorkSpace, type, name); 303d9f0492fSopenharmony_ci } 304d9f0492fSopenharmony_ci return 0; 305d9f0492fSopenharmony_ci} 306d9f0492fSopenharmony_ci 307d9f0492fSopenharmony_ciint InitTriggerWorkSpace(void) 308d9f0492fSopenharmony_ci{ 309d9f0492fSopenharmony_ci if (g_triggerWorkSpace.eventHandle != NULL) { 310d9f0492fSopenharmony_ci return 0; 311d9f0492fSopenharmony_ci } 312d9f0492fSopenharmony_ci g_triggerWorkSpace.bootStateChange = NULL; 313d9f0492fSopenharmony_ci ParamEventTaskCreate(&g_triggerWorkSpace.eventHandle, ProcessBeforeEvent); 314d9f0492fSopenharmony_ci PARAM_CHECK(g_triggerWorkSpace.eventHandle != NULL, return -1, "Failed to event handle"); 315d9f0492fSopenharmony_ci 316d9f0492fSopenharmony_ci // executeQueue 317d9f0492fSopenharmony_ci g_triggerWorkSpace.executeQueue.executeQueue = calloc(1, TRIGGER_EXECUTE_QUEUE * sizeof(TriggerNode *)); 318d9f0492fSopenharmony_ci PARAM_CHECK(g_triggerWorkSpace.executeQueue.executeQueue != NULL, 319d9f0492fSopenharmony_ci return -1, "Failed to alloc memory for executeQueue"); 320d9f0492fSopenharmony_ci g_triggerWorkSpace.executeQueue.queueCount = TRIGGER_EXECUTE_QUEUE; 321d9f0492fSopenharmony_ci g_triggerWorkSpace.executeQueue.startIndex = 0; 322d9f0492fSopenharmony_ci g_triggerWorkSpace.executeQueue.endIndex = 0; 323d9f0492fSopenharmony_ci InitTriggerHead(&g_triggerWorkSpace); 324d9f0492fSopenharmony_ci RegisterTriggerExec(TRIGGER_BOOT, DoTriggerExecute_); 325d9f0492fSopenharmony_ci RegisterTriggerExec(TRIGGER_PARAM, DoTriggerExecute_); 326d9f0492fSopenharmony_ci RegisterTriggerExec(TRIGGER_UNKNOW, DoTriggerExecute_); 327d9f0492fSopenharmony_ci PARAM_LOGV("InitTriggerWorkSpace success"); 328d9f0492fSopenharmony_ci return 0; 329d9f0492fSopenharmony_ci} 330d9f0492fSopenharmony_ci 331d9f0492fSopenharmony_civoid CloseTriggerWorkSpace(void) 332d9f0492fSopenharmony_ci{ 333d9f0492fSopenharmony_ci for (size_t i = 0; i < sizeof(g_triggerWorkSpace.triggerHead) / sizeof(g_triggerWorkSpace.triggerHead[0]); i++) { 334d9f0492fSopenharmony_ci ClearTrigger(&g_triggerWorkSpace, i); 335d9f0492fSopenharmony_ci } 336d9f0492fSopenharmony_ci OH_HashMapDestory(g_triggerWorkSpace.hashMap, NULL); 337d9f0492fSopenharmony_ci g_triggerWorkSpace.hashMap = NULL; 338d9f0492fSopenharmony_ci free(g_triggerWorkSpace.executeQueue.executeQueue); 339d9f0492fSopenharmony_ci g_triggerWorkSpace.executeQueue.executeQueue = NULL; 340d9f0492fSopenharmony_ci ParamTaskClose(g_triggerWorkSpace.eventHandle); 341d9f0492fSopenharmony_ci g_triggerWorkSpace.eventHandle = NULL; 342d9f0492fSopenharmony_ci} 343d9f0492fSopenharmony_ci 344d9f0492fSopenharmony_ciTriggerWorkSpace *GetTriggerWorkSpace(void) 345d9f0492fSopenharmony_ci{ 346d9f0492fSopenharmony_ci return &g_triggerWorkSpace; 347d9f0492fSopenharmony_ci} 348d9f0492fSopenharmony_ci 349d9f0492fSopenharmony_civoid RegisterTriggerExec(int type, 350d9f0492fSopenharmony_ci int32_t (*executeTrigger)(const struct tagTriggerNode_ *, const char *, uint32_t)) 351d9f0492fSopenharmony_ci{ 352d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(&g_triggerWorkSpace, type); 353d9f0492fSopenharmony_ci if (triggerHead != NULL) { 354d9f0492fSopenharmony_ci triggerHead->executeTrigger = executeTrigger; 355d9f0492fSopenharmony_ci } 356d9f0492fSopenharmony_ci} 357d9f0492fSopenharmony_ci 358d9f0492fSopenharmony_civoid DoTriggerExec(const char *triggerName) 359d9f0492fSopenharmony_ci{ 360d9f0492fSopenharmony_ci PARAM_CHECK(g_triggerWorkSpace.eventHandle != NULL, return, "Invalid trigger data"); 361d9f0492fSopenharmony_ci PARAM_CHECK(triggerName != NULL, return, "Invalid param"); 362d9f0492fSopenharmony_ci JobNode *trigger = GetTriggerByName(&g_triggerWorkSpace, triggerName); 363d9f0492fSopenharmony_ci if (trigger != NULL && !TRIGGER_IN_QUEUE((TriggerNode *)trigger)) { 364d9f0492fSopenharmony_ci PARAM_LOGV("Trigger job %s", trigger->name); 365d9f0492fSopenharmony_ci TRIGGER_SET_FLAG((TriggerNode *)trigger, TRIGGER_FLAGS_QUEUE); 366d9f0492fSopenharmony_ci ExecuteQueuePush(&g_triggerWorkSpace, (TriggerNode *)trigger); 367d9f0492fSopenharmony_ci } else { 368d9f0492fSopenharmony_ci PARAM_LOGW("Can not find trigger %s", triggerName); 369d9f0492fSopenharmony_ci } 370d9f0492fSopenharmony_ci} 371d9f0492fSopenharmony_ci 372d9f0492fSopenharmony_civoid DoJobExecNow(const char *triggerName) 373d9f0492fSopenharmony_ci{ 374d9f0492fSopenharmony_ci PARAM_CHECK(g_triggerWorkSpace.eventHandle != NULL, return, "Invalid trigger data"); 375d9f0492fSopenharmony_ci PARAM_CHECK(triggerName != NULL, return, "Invalid param"); 376d9f0492fSopenharmony_ci JobNode *trigger = GetTriggerByName(&g_triggerWorkSpace, triggerName); 377d9f0492fSopenharmony_ci if (trigger != NULL) { 378d9f0492fSopenharmony_ci if (strncmp(triggerName, "reboot", strlen("reboot")) == 0) { 379d9f0492fSopenharmony_ci HookMgrExecute(GetBootStageHookMgr(), INIT_SHUT_DETECTOR, NULL, NULL); 380d9f0492fSopenharmony_ci } 381d9f0492fSopenharmony_ci StartTriggerExecute_((TriggerNode *)trigger, NULL, 0); 382d9f0492fSopenharmony_ci } 383d9f0492fSopenharmony_ci} 384d9f0492fSopenharmony_ci 385d9f0492fSopenharmony_ciint AddCompleteJob(const char *name, const char *condition, const char *cmdContent) 386d9f0492fSopenharmony_ci{ 387d9f0492fSopenharmony_ci PARAM_CHECK(g_triggerWorkSpace.eventHandle != NULL, return -1, "Invalid trigger data"); 388d9f0492fSopenharmony_ci PARAM_CHECK(name != NULL, return -1, "Invalid name"); 389d9f0492fSopenharmony_ci PARAM_CHECK(cmdContent != NULL, return -1, "Invalid cmdContent"); 390d9f0492fSopenharmony_ci int type = GetTriggerType(name); 391d9f0492fSopenharmony_ci PARAM_CHECK(type <= TRIGGER_UNKNOW, return -1, "Failed to get trigger index"); 392d9f0492fSopenharmony_ci TriggerHeader *header = GetTriggerHeader(&g_triggerWorkSpace, type); 393d9f0492fSopenharmony_ci PARAM_CHECK(header != NULL, return -1, "Failed to get header %d", type); 394d9f0492fSopenharmony_ci 395d9f0492fSopenharmony_ci JobNode *trigger = UpdateJobTrigger(&g_triggerWorkSpace, type, condition, name); 396d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return -1, "Failed to create trigger"); 397d9f0492fSopenharmony_ci char *content = NULL; 398d9f0492fSopenharmony_ci int cmdKeyIndex = 0; 399d9f0492fSopenharmony_ci int ret = GetCommandInfo(cmdContent, &cmdKeyIndex, &content); 400d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Command not support %s", cmdContent); 401d9f0492fSopenharmony_ci ret = AddCommand(trigger, (uint32_t)cmdKeyIndex, content, NULL); // use default context 402d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Failed to add command %s", cmdContent); 403d9f0492fSopenharmony_ci header->cmdNodeCount++; 404d9f0492fSopenharmony_ci PARAM_LOGV("AddCompleteJob %s type %d count %d", name, type, header->triggerCount); 405d9f0492fSopenharmony_ci return 0; 406d9f0492fSopenharmony_ci} 407d9f0492fSopenharmony_ci 408d9f0492fSopenharmony_civoid RegisterBootStateChange(void (*bootStateChange)(int, const char *)) 409d9f0492fSopenharmony_ci{ 410d9f0492fSopenharmony_ci if (bootStateChange != NULL) { 411d9f0492fSopenharmony_ci g_triggerWorkSpace.bootStateChange = bootStateChange; 412d9f0492fSopenharmony_ci } 413d9f0492fSopenharmony_ci} 414