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 16d9f0492fSopenharmony_ci#include "trigger_manager.h" 17d9f0492fSopenharmony_ci 18d9f0492fSopenharmony_ci#include <string.h> 19d9f0492fSopenharmony_ci#include <sys/types.h> 20d9f0492fSopenharmony_ci 21d9f0492fSopenharmony_ci#include "init_cmds.h" 22d9f0492fSopenharmony_ci#include "param_manager.h" 23d9f0492fSopenharmony_ci#include "trigger_checker.h" 24d9f0492fSopenharmony_ci#include "securec.h" 25d9f0492fSopenharmony_ci 26d9f0492fSopenharmony_cistatic DUMP_PRINTF g_printf = printf; 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_ciint AddCommand(JobNode *trigger, uint32_t cmdKeyIndex, const char *content, const ConfigContext *cfgContext) 29d9f0492fSopenharmony_ci{ 30d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return -1, "trigger is null"); 31d9f0492fSopenharmony_ci uint32_t size = sizeof(CommandNode); 32d9f0492fSopenharmony_ci size += (content == NULL) ? 1 : (strlen(content) + 1); 33d9f0492fSopenharmony_ci size = PARAM_ALIGN(size); 34d9f0492fSopenharmony_ci 35d9f0492fSopenharmony_ci CommandNode *node = (CommandNode *)calloc(1, size); 36d9f0492fSopenharmony_ci PARAM_CHECK(node != NULL, return -1, "Failed to alloc memory for command"); 37d9f0492fSopenharmony_ci node->cmdKeyIndex = cmdKeyIndex; 38d9f0492fSopenharmony_ci node->next = NULL; 39d9f0492fSopenharmony_ci node->content[0] = '\0'; 40d9f0492fSopenharmony_ci if (content != NULL && strlen(content) != 0) { 41d9f0492fSopenharmony_ci int ret = memcpy_s(node->content, size, content, strlen(content)); 42d9f0492fSopenharmony_ci node->content[strlen(content)] = '\0'; 43d9f0492fSopenharmony_ci PARAM_CHECK(ret == EOK, free(node); 44d9f0492fSopenharmony_ci return 0, "Failed to copy command"); 45d9f0492fSopenharmony_ci } 46d9f0492fSopenharmony_ci node->cfgContext.type = INIT_CONTEXT_MAIN; 47d9f0492fSopenharmony_ci if (cfgContext != NULL) { 48d9f0492fSopenharmony_ci node->cfgContext.type = cfgContext->type; 49d9f0492fSopenharmony_ci } 50d9f0492fSopenharmony_ci if (trigger->firstCmd == NULL) { 51d9f0492fSopenharmony_ci trigger->firstCmd = node; 52d9f0492fSopenharmony_ci trigger->lastCmd = node; 53d9f0492fSopenharmony_ci } else { 54d9f0492fSopenharmony_ci PARAM_CHECK(trigger->lastCmd != NULL, free(node); 55d9f0492fSopenharmony_ci return 0, "Invalid last cmd"); 56d9f0492fSopenharmony_ci trigger->lastCmd->next = node; 57d9f0492fSopenharmony_ci trigger->lastCmd = node; 58d9f0492fSopenharmony_ci } 59d9f0492fSopenharmony_ci return 0; 60d9f0492fSopenharmony_ci} 61d9f0492fSopenharmony_ci 62d9f0492fSopenharmony_ciCommandNode *GetNextCmdNode(const JobNode *trigger, const CommandNode *curr) 63d9f0492fSopenharmony_ci{ 64d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return NULL, "trigger is null"); 65d9f0492fSopenharmony_ci if (curr == NULL) { 66d9f0492fSopenharmony_ci return trigger->firstCmd; 67d9f0492fSopenharmony_ci } 68d9f0492fSopenharmony_ci return curr->next; 69d9f0492fSopenharmony_ci} 70d9f0492fSopenharmony_ci 71d9f0492fSopenharmony_cistatic int CopyCondition(TriggerNode *node, const char *condition) 72d9f0492fSopenharmony_ci{ 73d9f0492fSopenharmony_ci if (condition == NULL || strlen(condition) == 0) { 74d9f0492fSopenharmony_ci return 0; 75d9f0492fSopenharmony_ci } 76d9f0492fSopenharmony_ci uint32_t buffSize = 0; 77d9f0492fSopenharmony_ci char *cond = GetTriggerCache(&buffSize); 78d9f0492fSopenharmony_ci int ret = ConvertInfixToPrefix(condition, cond, buffSize); 79d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Failed to convert condition for trigger"); 80d9f0492fSopenharmony_ci node->condition = strdup(cond); 81d9f0492fSopenharmony_ci PARAM_CHECK(node->condition != NULL, return -1, "Failed to dup conditition"); 82d9f0492fSopenharmony_ci return 0; 83d9f0492fSopenharmony_ci} 84d9f0492fSopenharmony_ci 85d9f0492fSopenharmony_cistatic TriggerNode *AddTriggerNode_(TriggerHeader *triggerHead, 86d9f0492fSopenharmony_ci uint32_t type, const char *condition, uint32_t dataSize) 87d9f0492fSopenharmony_ci{ 88d9f0492fSopenharmony_ci TriggerNode *node = (TriggerNode *)calloc(1, dataSize); 89d9f0492fSopenharmony_ci PARAM_CHECK(node != NULL, return NULL, "Failed to alloc memory for trigger"); 90d9f0492fSopenharmony_ci node->condition = NULL; 91d9f0492fSopenharmony_ci int ret = CopyCondition(node, condition); 92d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, free(node); 93d9f0492fSopenharmony_ci return NULL, "Failed to copy conditition"); 94d9f0492fSopenharmony_ci node->type = type; 95d9f0492fSopenharmony_ci node->flags = 0; 96d9f0492fSopenharmony_ci OH_ListInit(&node->node); 97d9f0492fSopenharmony_ci OH_ListAddTail(&triggerHead->triggerList, &node->node); 98d9f0492fSopenharmony_ci triggerHead->triggerCount++; 99d9f0492fSopenharmony_ci return node; 100d9f0492fSopenharmony_ci} 101d9f0492fSopenharmony_ci 102d9f0492fSopenharmony_cistatic int32_t AddJobNode_(TriggerNode *trigger, const TriggerExtInfo *extInfo) 103d9f0492fSopenharmony_ci{ 104d9f0492fSopenharmony_ci JobNode *node = (JobNode *)trigger; 105d9f0492fSopenharmony_ci int ret = strcpy_s(node->name, strlen(extInfo->info.name) + 1, extInfo->info.name); 106d9f0492fSopenharmony_ci PARAM_CHECK(ret == EOK, return -1, "Failed to copy name for trigger"); 107d9f0492fSopenharmony_ci node->firstCmd = NULL; 108d9f0492fSopenharmony_ci node->lastCmd = NULL; 109d9f0492fSopenharmony_ci ret = OH_HashMapAdd(GetTriggerWorkSpace()->hashMap, &node->hashNode); 110d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Failed to add hash node"); 111d9f0492fSopenharmony_ci return 0; 112d9f0492fSopenharmony_ci} 113d9f0492fSopenharmony_ci 114d9f0492fSopenharmony_cistatic TriggerNode *AddJobTrigger_(const TriggerWorkSpace *workSpace, 115d9f0492fSopenharmony_ci const char *condition, const TriggerExtInfo *extInfo) 116d9f0492fSopenharmony_ci{ 117d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return NULL, "workSpace is null"); 118d9f0492fSopenharmony_ci PARAM_CHECK(extInfo != NULL && extInfo->addNode != NULL, return NULL, "extInfo is null"); 119d9f0492fSopenharmony_ci PARAM_CHECK(extInfo->type <= TRIGGER_UNKNOW, return NULL, "Invalid type"); 120d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(workSpace, extInfo->type); 121d9f0492fSopenharmony_ci PARAM_CHECK(triggerHead != NULL, return NULL, "Failed to get header %d", extInfo->type); 122d9f0492fSopenharmony_ci uint32_t nameLen = strlen(extInfo->info.name); 123d9f0492fSopenharmony_ci uint32_t triggerNodeLen = PARAM_ALIGN(nameLen + 1) + sizeof(JobNode); 124d9f0492fSopenharmony_ci TriggerNode *node = (TriggerNode *)AddTriggerNode_(triggerHead, extInfo->type, condition, triggerNodeLen); 125d9f0492fSopenharmony_ci PARAM_CHECK(node != NULL, return NULL, "Failed to alloc jobnode"); 126d9f0492fSopenharmony_ci int ret = extInfo->addNode(node, extInfo); 127d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, FreeTrigger(workSpace, node); 128d9f0492fSopenharmony_ci return NULL, "Failed to add hash node"); 129d9f0492fSopenharmony_ci if (extInfo->type == TRIGGER_BOOT) { 130d9f0492fSopenharmony_ci TRIGGER_SET_FLAG(node, TRIGGER_FLAGS_ONCE); 131d9f0492fSopenharmony_ci if (strncmp("boot-service:", extInfo->info.name, strlen("boot-service:")) != 0) { 132d9f0492fSopenharmony_ci TRIGGER_SET_FLAG(node, TRIGGER_FLAGS_SUBTRIGGER); 133d9f0492fSopenharmony_ci } 134d9f0492fSopenharmony_ci } 135d9f0492fSopenharmony_ci return node; 136d9f0492fSopenharmony_ci} 137d9f0492fSopenharmony_ci 138d9f0492fSopenharmony_cistatic void DelJobTrigger_(const TriggerWorkSpace *workSpace, TriggerNode *trigger) 139d9f0492fSopenharmony_ci{ 140d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return, "Param is null"); 141d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return, "Trigger is null"); 142d9f0492fSopenharmony_ci JobNode *jobNode = (JobNode *)trigger; 143d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(workSpace, trigger->type); 144d9f0492fSopenharmony_ci PARAM_CHECK(triggerHead != NULL, return, "Failed to get header %d", trigger->type); 145d9f0492fSopenharmony_ci CommandNode *cmd = jobNode->firstCmd; 146d9f0492fSopenharmony_ci while (cmd != NULL) { 147d9f0492fSopenharmony_ci CommandNode *next = cmd->next; 148d9f0492fSopenharmony_ci free(cmd); 149d9f0492fSopenharmony_ci triggerHead->cmdNodeCount--; 150d9f0492fSopenharmony_ci cmd = next; 151d9f0492fSopenharmony_ci } 152d9f0492fSopenharmony_ci if (jobNode->condition != NULL) { 153d9f0492fSopenharmony_ci free(jobNode->condition); 154d9f0492fSopenharmony_ci jobNode->condition = NULL; 155d9f0492fSopenharmony_ci } 156d9f0492fSopenharmony_ci jobNode->lastCmd = NULL; 157d9f0492fSopenharmony_ci jobNode->firstCmd = NULL; 158d9f0492fSopenharmony_ci OH_ListRemove(&trigger->node); 159d9f0492fSopenharmony_ci triggerHead->triggerCount--; 160d9f0492fSopenharmony_ci OH_HashMapRemove(workSpace->hashMap, jobNode->name); 161d9f0492fSopenharmony_ci 162d9f0492fSopenharmony_ci if (!TRIGGER_IN_QUEUE(trigger)) { 163d9f0492fSopenharmony_ci free(jobNode); 164d9f0492fSopenharmony_ci return; 165d9f0492fSopenharmony_ci } 166d9f0492fSopenharmony_ci TriggerExecuteQueue *executeQueue = (TriggerExecuteQueue *)&workSpace->executeQueue; 167d9f0492fSopenharmony_ci for (uint32_t i = executeQueue->startIndex; i < executeQueue->endIndex; i++) { 168d9f0492fSopenharmony_ci if (executeQueue->executeQueue[i] == trigger) { 169d9f0492fSopenharmony_ci executeQueue->executeQueue[i] = NULL; 170d9f0492fSopenharmony_ci break; 171d9f0492fSopenharmony_ci } 172d9f0492fSopenharmony_ci } 173d9f0492fSopenharmony_ci free(jobNode); 174d9f0492fSopenharmony_ci} 175d9f0492fSopenharmony_ci 176d9f0492fSopenharmony_cistatic TriggerNode *AddWatchTrigger_(const TriggerWorkSpace *workSpace, 177d9f0492fSopenharmony_ci const char *condition, const TriggerExtInfo *extInfo) 178d9f0492fSopenharmony_ci{ 179d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return NULL, "workSpace is null"); 180d9f0492fSopenharmony_ci PARAM_CHECK(extInfo != NULL && extInfo->addNode != NULL, return NULL, "extInfo is null"); 181d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(workSpace, extInfo->type); 182d9f0492fSopenharmony_ci PARAM_CHECK(triggerHead != NULL, return NULL, "Failed to get header %d", extInfo->type); 183d9f0492fSopenharmony_ci uint32_t size = 0; 184d9f0492fSopenharmony_ci if (extInfo->type == TRIGGER_PARAM_WATCH) { 185d9f0492fSopenharmony_ci size = sizeof(WatchNode); 186d9f0492fSopenharmony_ci } else if (extInfo->type == TRIGGER_PARAM_WAIT) { 187d9f0492fSopenharmony_ci size = sizeof(WaitNode); 188d9f0492fSopenharmony_ci } else { 189d9f0492fSopenharmony_ci PARAM_LOGE("Invalid trigger type %d", extInfo->type); 190d9f0492fSopenharmony_ci return NULL; 191d9f0492fSopenharmony_ci } 192d9f0492fSopenharmony_ci TriggerNode *node = AddTriggerNode_(triggerHead, extInfo->type, condition, size); 193d9f0492fSopenharmony_ci PARAM_CHECK(node != NULL, return NULL, "Failed to alloc memory for trigger"); 194d9f0492fSopenharmony_ci int ret = extInfo->addNode(node, extInfo); 195d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, FreeTrigger(workSpace, node); 196d9f0492fSopenharmony_ci return NULL, "Failed to add node"); 197d9f0492fSopenharmony_ci if (extInfo->type == TRIGGER_PARAM_WAIT) { 198d9f0492fSopenharmony_ci TRIGGER_SET_FLAG(node, TRIGGER_FLAGS_ONCE); 199d9f0492fSopenharmony_ci } 200d9f0492fSopenharmony_ci return node; 201d9f0492fSopenharmony_ci} 202d9f0492fSopenharmony_ci 203d9f0492fSopenharmony_cistatic void DelWatchTrigger_(const TriggerWorkSpace *workSpace, TriggerNode *trigger) 204d9f0492fSopenharmony_ci{ 205d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && trigger != NULL, return, "Param is null"); 206d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(workSpace, trigger->type); 207d9f0492fSopenharmony_ci PARAM_CHECK(triggerHead != NULL, return, "Failed to get header %d", trigger->type); 208d9f0492fSopenharmony_ci OH_ListRemove(&trigger->node); 209d9f0492fSopenharmony_ci if (trigger->type == TRIGGER_PARAM_WAIT) { 210d9f0492fSopenharmony_ci WaitNode *node = (WaitNode *)trigger; 211d9f0492fSopenharmony_ci OH_ListRemove(&node->item); 212d9f0492fSopenharmony_ci } else if (trigger->type == TRIGGER_PARAM_WATCH) { 213d9f0492fSopenharmony_ci WatchNode *node = (WatchNode *)trigger; 214d9f0492fSopenharmony_ci OH_ListRemove(&node->item); 215d9f0492fSopenharmony_ci } 216d9f0492fSopenharmony_ci PARAM_LOGV("DelWatchTrigger_ %s count %d", GetTriggerName(trigger), triggerHead->triggerCount); 217d9f0492fSopenharmony_ci triggerHead->triggerCount--; 218d9f0492fSopenharmony_ci if (trigger->condition != NULL) { 219d9f0492fSopenharmony_ci free(trigger->condition); 220d9f0492fSopenharmony_ci trigger->condition = NULL; 221d9f0492fSopenharmony_ci } 222d9f0492fSopenharmony_ci free(trigger); 223d9f0492fSopenharmony_ci} 224d9f0492fSopenharmony_ci 225d9f0492fSopenharmony_cistatic TriggerNode *GetNextTrigger_(const TriggerHeader *triggerHead, const TriggerNode *curr) 226d9f0492fSopenharmony_ci{ 227d9f0492fSopenharmony_ci PARAM_CHECK(triggerHead != NULL, return NULL, "Invalid triggerHead"); 228d9f0492fSopenharmony_ci ListNode *node = NULL; 229d9f0492fSopenharmony_ci if (curr != NULL) { 230d9f0492fSopenharmony_ci node = curr->node.next; 231d9f0492fSopenharmony_ci } else { 232d9f0492fSopenharmony_ci node = triggerHead->triggerList.next; 233d9f0492fSopenharmony_ci } 234d9f0492fSopenharmony_ci if (node != &triggerHead->triggerList) { 235d9f0492fSopenharmony_ci return ListEntry(node, TriggerNode, node); 236d9f0492fSopenharmony_ci } 237d9f0492fSopenharmony_ci return NULL; 238d9f0492fSopenharmony_ci} 239d9f0492fSopenharmony_ci 240d9f0492fSopenharmony_cistatic const char *GetTriggerCondition_(const TriggerNode *trigger) 241d9f0492fSopenharmony_ci{ 242d9f0492fSopenharmony_ci return (trigger == NULL || trigger->condition == NULL) ? "" : trigger->condition; 243d9f0492fSopenharmony_ci} 244d9f0492fSopenharmony_ci 245d9f0492fSopenharmony_cistatic const char *GetBootCondition_(const TriggerNode *trigger) 246d9f0492fSopenharmony_ci{ 247d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return "", "Invalid trigger"); 248d9f0492fSopenharmony_ci PARAM_CHECK(trigger->type == TRIGGER_BOOT, return "", "Invalid type"); 249d9f0492fSopenharmony_ci const JobNode *node = (const JobNode *)trigger; 250d9f0492fSopenharmony_ci return node->name; 251d9f0492fSopenharmony_ci} 252d9f0492fSopenharmony_ci 253d9f0492fSopenharmony_cistatic const char *GetJobName_(const TriggerNode *trigger) 254d9f0492fSopenharmony_ci{ 255d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return "", "Invalid trigger"); 256d9f0492fSopenharmony_ci PARAM_CHECK(trigger->type <= TRIGGER_UNKNOW, return "", "Invalid type"); 257d9f0492fSopenharmony_ci const JobNode *node = (const JobNode *)trigger; 258d9f0492fSopenharmony_ci return node->name; 259d9f0492fSopenharmony_ci} 260d9f0492fSopenharmony_ci 261d9f0492fSopenharmony_cistatic const char *GetWatchName_(const TriggerNode *trigger) 262d9f0492fSopenharmony_ci{ 263d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return "", "Invalid trigger"); 264d9f0492fSopenharmony_ci PARAM_CHECK(trigger->type < TRIGGER_MAX && trigger->type > TRIGGER_UNKNOW, 265d9f0492fSopenharmony_ci return "", "Invalid type"); 266d9f0492fSopenharmony_ci return trigger->condition; 267d9f0492fSopenharmony_ci} 268d9f0492fSopenharmony_ci 269d9f0492fSopenharmony_ciJobNode *UpdateJobTrigger(const TriggerWorkSpace *workSpace, 270d9f0492fSopenharmony_ci int type, const char *condition, const char *name) 271d9f0492fSopenharmony_ci{ 272d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && name != NULL, return NULL, "name is null"); 273d9f0492fSopenharmony_ci PARAM_CHECK(type <= TRIGGER_UNKNOW, return NULL, "Invalid type"); 274d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(workSpace, type); 275d9f0492fSopenharmony_ci PARAM_CHECK(triggerHead != NULL, return NULL, "Failed to get header %d", type); 276d9f0492fSopenharmony_ci JobNode *jobNode = GetTriggerByName(workSpace, name); 277d9f0492fSopenharmony_ci if (jobNode == NULL) { 278d9f0492fSopenharmony_ci TriggerExtInfo extInfo = {}; 279d9f0492fSopenharmony_ci extInfo.info.name = (char *)name; 280d9f0492fSopenharmony_ci extInfo.type = type; 281d9f0492fSopenharmony_ci extInfo.addNode = AddJobNode_; 282d9f0492fSopenharmony_ci return (JobNode *)triggerHead->addTrigger(workSpace, condition, &extInfo); 283d9f0492fSopenharmony_ci } else if (jobNode->condition == NULL && condition != NULL) { 284d9f0492fSopenharmony_ci int ret = CopyCondition((TriggerNode *)jobNode, condition); 285d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, FreeTrigger(workSpace, (TriggerNode*)jobNode); 286d9f0492fSopenharmony_ci return NULL, "Failed to copy conditition"); 287d9f0492fSopenharmony_ci } 288d9f0492fSopenharmony_ci return jobNode; 289d9f0492fSopenharmony_ci} 290d9f0492fSopenharmony_ci 291d9f0492fSopenharmony_ciJobNode *GetTriggerByName(const TriggerWorkSpace *workSpace, const char *triggerName) 292d9f0492fSopenharmony_ci{ 293d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && triggerName != NULL, return NULL, "Invalid param"); 294d9f0492fSopenharmony_ci HashNode *node = OH_HashMapGet(workSpace->hashMap, triggerName); 295d9f0492fSopenharmony_ci if (node == NULL) { 296d9f0492fSopenharmony_ci return NULL; 297d9f0492fSopenharmony_ci } 298d9f0492fSopenharmony_ci JobNode *trigger = HASHMAP_ENTRY(node, JobNode, hashNode); 299d9f0492fSopenharmony_ci return trigger; 300d9f0492fSopenharmony_ci} 301d9f0492fSopenharmony_ci 302d9f0492fSopenharmony_civoid FreeTrigger(const TriggerWorkSpace *workSpace, TriggerNode *trigger) 303d9f0492fSopenharmony_ci{ 304d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && trigger != NULL, return, "Invalid param"); 305d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(workSpace, trigger->type); 306d9f0492fSopenharmony_ci if (head != NULL) { 307d9f0492fSopenharmony_ci head->delTrigger(workSpace, trigger); 308d9f0492fSopenharmony_ci } 309d9f0492fSopenharmony_ci} 310d9f0492fSopenharmony_ci 311d9f0492fSopenharmony_civoid ClearTrigger(const TriggerWorkSpace *workSpace, int8_t type) 312d9f0492fSopenharmony_ci{ 313d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return, "head is null"); 314d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(workSpace, type); 315d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL, return, "Failed to get header %d", type); 316d9f0492fSopenharmony_ci TriggerNode *trigger = head->nextTrigger(head, NULL); 317d9f0492fSopenharmony_ci while (trigger != NULL) { 318d9f0492fSopenharmony_ci TriggerNode *next = head->nextTrigger(head, trigger); 319d9f0492fSopenharmony_ci FreeTrigger(workSpace, trigger); 320d9f0492fSopenharmony_ci trigger = next; 321d9f0492fSopenharmony_ci } 322d9f0492fSopenharmony_ci OH_ListInit(&head->triggerList); 323d9f0492fSopenharmony_ci} 324d9f0492fSopenharmony_ci 325d9f0492fSopenharmony_ciint ExecuteQueuePush(TriggerWorkSpace *workSpace, const TriggerNode *trigger) 326d9f0492fSopenharmony_ci{ 327d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return -1, "Invalid workSpace"); 328d9f0492fSopenharmony_ci uint32_t index = workSpace->executeQueue.endIndex++ % workSpace->executeQueue.queueCount; 329d9f0492fSopenharmony_ci workSpace->executeQueue.executeQueue[index] = (TriggerNode *)trigger; 330d9f0492fSopenharmony_ci return 0; 331d9f0492fSopenharmony_ci} 332d9f0492fSopenharmony_ci 333d9f0492fSopenharmony_ciTriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace) 334d9f0492fSopenharmony_ci{ 335d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return NULL, "Invalid workSpace"); 336d9f0492fSopenharmony_ci TriggerNode *trigger = NULL; 337d9f0492fSopenharmony_ci do { 338d9f0492fSopenharmony_ci if (workSpace->executeQueue.endIndex <= workSpace->executeQueue.startIndex) { 339d9f0492fSopenharmony_ci return NULL; 340d9f0492fSopenharmony_ci } 341d9f0492fSopenharmony_ci uint32_t currIndex = workSpace->executeQueue.startIndex % workSpace->executeQueue.queueCount; 342d9f0492fSopenharmony_ci trigger = workSpace->executeQueue.executeQueue[currIndex]; 343d9f0492fSopenharmony_ci workSpace->executeQueue.executeQueue[currIndex] = NULL; 344d9f0492fSopenharmony_ci workSpace->executeQueue.startIndex++; 345d9f0492fSopenharmony_ci } while (trigger == NULL); 346d9f0492fSopenharmony_ci return trigger; 347d9f0492fSopenharmony_ci} 348d9f0492fSopenharmony_ci 349d9f0492fSopenharmony_cistatic int CheckBootCondition_(LogicCalculator *calculator, 350d9f0492fSopenharmony_ci const char *condition, const char *content, uint32_t contentSize) 351d9f0492fSopenharmony_ci{ 352d9f0492fSopenharmony_ci UNUSED(calculator); 353d9f0492fSopenharmony_ci if (strncmp(condition, content, contentSize) == 0) { 354d9f0492fSopenharmony_ci return 1; 355d9f0492fSopenharmony_ci } 356d9f0492fSopenharmony_ci return 0; 357d9f0492fSopenharmony_ci} 358d9f0492fSopenharmony_ci 359d9f0492fSopenharmony_cistatic int CheckWatchCondition_(LogicCalculator *calculator, 360d9f0492fSopenharmony_ci const char *condition, const char *content, uint32_t contentSize) 361d9f0492fSopenharmony_ci{ 362d9f0492fSopenharmony_ci UNUSED(calculator); 363d9f0492fSopenharmony_ci UNUSED(contentSize); 364d9f0492fSopenharmony_ci if (strncmp(condition, content, strlen(condition)) == 0) { 365d9f0492fSopenharmony_ci return 1; 366d9f0492fSopenharmony_ci } 367d9f0492fSopenharmony_ci return 0; 368d9f0492fSopenharmony_ci} 369d9f0492fSopenharmony_ci 370d9f0492fSopenharmony_cistatic int CheckParamCondition_(LogicCalculator *calculator, 371d9f0492fSopenharmony_ci const char *condition, const char *content, uint32_t contentSize) 372d9f0492fSopenharmony_ci{ 373d9f0492fSopenharmony_ci UNUSED(content); 374d9f0492fSopenharmony_ci UNUSED(contentSize); 375d9f0492fSopenharmony_ci if (calculator->inputName != NULL) { 376d9f0492fSopenharmony_ci if (!CheckMatchSubCondition(condition, calculator->inputName, strlen(calculator->inputName))) { 377d9f0492fSopenharmony_ci return 0; 378d9f0492fSopenharmony_ci } 379d9f0492fSopenharmony_ci } 380d9f0492fSopenharmony_ci return ComputeCondition(calculator, condition); 381d9f0492fSopenharmony_ci} 382d9f0492fSopenharmony_ci 383d9f0492fSopenharmony_cistatic int CheckUnknowCondition_(LogicCalculator *calculator, 384d9f0492fSopenharmony_ci const char *condition, const char *content, uint32_t contentSize) 385d9f0492fSopenharmony_ci{ 386d9f0492fSopenharmony_ci if (condition != NULL && content != NULL && strcmp(content, condition) == 0) { 387d9f0492fSopenharmony_ci return 1; 388d9f0492fSopenharmony_ci } 389d9f0492fSopenharmony_ci return ComputeCondition(calculator, condition); 390d9f0492fSopenharmony_ci} 391d9f0492fSopenharmony_ci 392d9f0492fSopenharmony_cistatic int ExecTriggerMatch_(const TriggerWorkSpace *workSpace, 393d9f0492fSopenharmony_ci int type, LogicCalculator *calculator, const char *content, uint32_t contentSize) 394d9f0492fSopenharmony_ci{ 395d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(workSpace, type); 396d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL, return 0, "Failed to get header %d", type); 397d9f0492fSopenharmony_ci TriggerNode *trigger = head->nextTrigger(head, NULL); 398d9f0492fSopenharmony_ci while (trigger != NULL) { 399d9f0492fSopenharmony_ci TriggerNode *next = head->nextTrigger(head, trigger); 400d9f0492fSopenharmony_ci const char *condition = head->getCondition(trigger); 401d9f0492fSopenharmony_ci if (head->checkCondition(calculator, condition, content, contentSize) == 1) { 402d9f0492fSopenharmony_ci calculator->triggerCheckDone(trigger, content, contentSize); 403d9f0492fSopenharmony_ci } 404d9f0492fSopenharmony_ci trigger = next; 405d9f0492fSopenharmony_ci } 406d9f0492fSopenharmony_ci return 0; 407d9f0492fSopenharmony_ci} 408d9f0492fSopenharmony_ci 409d9f0492fSopenharmony_cistatic int CheckBootMatch_(const TriggerWorkSpace *workSpace, 410d9f0492fSopenharmony_ci int type, LogicCalculator *calculator, const char *content, uint32_t contentSize) 411d9f0492fSopenharmony_ci{ 412d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return -1, "Invalid space"); 413d9f0492fSopenharmony_ci PARAM_CHECK((type == TRIGGER_BOOT) || (type == TRIGGER_PARAM_WATCH), return -1, "Invalid type"); 414d9f0492fSopenharmony_ci return ExecTriggerMatch_(workSpace, type, calculator, content, contentSize); 415d9f0492fSopenharmony_ci} 416d9f0492fSopenharmony_ci 417d9f0492fSopenharmony_cistatic int CheckParamMatch_(const TriggerWorkSpace *workSpace, 418d9f0492fSopenharmony_ci int type, LogicCalculator *calculator, const char *content, uint32_t contentSize) 419d9f0492fSopenharmony_ci{ 420d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return -1, "Invalid space"); 421d9f0492fSopenharmony_ci PARAM_CHECK((type == TRIGGER_PARAM) || (type == TRIGGER_PARAM_WAIT), return -1, "Invalid type"); 422d9f0492fSopenharmony_ci 423d9f0492fSopenharmony_ci CalculatorInit(calculator, MAX_CONDITION_NUMBER, sizeof(LogicData), 1); 424d9f0492fSopenharmony_ci int ret = GetValueFromContent(content, contentSize, 0, calculator->inputName, SUPPORT_DATA_BUFFER_MAX); 425d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Failed parse content name"); 426d9f0492fSopenharmony_ci ret = GetValueFromContent(content, contentSize, 427d9f0492fSopenharmony_ci strlen(calculator->inputName) + 1, calculator->inputContent, SUPPORT_DATA_BUFFER_MAX); 428d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Failed parse content value"); 429d9f0492fSopenharmony_ci return ExecTriggerMatch_(workSpace, type, calculator, content, contentSize); 430d9f0492fSopenharmony_ci} 431d9f0492fSopenharmony_ci 432d9f0492fSopenharmony_cistatic int CheckUnknowMatch_(const TriggerWorkSpace *workSpace, 433d9f0492fSopenharmony_ci int type, LogicCalculator *calculator, const char *content, uint32_t contentSize) 434d9f0492fSopenharmony_ci{ 435d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && content != NULL, return -1, "Failed arg for trigger"); 436d9f0492fSopenharmony_ci PARAM_CHECK(type == TRIGGER_UNKNOW, return -1, "Invalid type"); 437d9f0492fSopenharmony_ci 438d9f0492fSopenharmony_ci CalculatorInit(calculator, MAX_CONDITION_NUMBER, sizeof(LogicData), 1); 439d9f0492fSopenharmony_ci int ret = memcpy_s(calculator->triggerContent, sizeof(calculator->triggerContent), content, contentSize); 440d9f0492fSopenharmony_ci PARAM_CHECK(ret == EOK, return -1, "Failed to memcpy"); 441d9f0492fSopenharmony_ci calculator->inputName = NULL; 442d9f0492fSopenharmony_ci calculator->inputContent = NULL; 443d9f0492fSopenharmony_ci return ExecTriggerMatch_(workSpace, type, calculator, content, contentSize); 444d9f0492fSopenharmony_ci} 445d9f0492fSopenharmony_ci 446d9f0492fSopenharmony_ciint32_t CheckAndMarkTrigger_(const TriggerWorkSpace *workSpace, int type, const char *name) 447d9f0492fSopenharmony_ci{ 448d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && name != NULL, return 0, "Failed arg for trigger"); 449d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(workSpace, type); 450d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL, return 0, "Failed to get header %d", type); 451d9f0492fSopenharmony_ci int ret = 0; 452d9f0492fSopenharmony_ci TriggerNode *trigger = head->nextTrigger(head, NULL); 453d9f0492fSopenharmony_ci while (trigger != NULL) { 454d9f0492fSopenharmony_ci if (head->getCondition(trigger) == NULL) { 455d9f0492fSopenharmony_ci trigger = head->nextTrigger(head, trigger); 456d9f0492fSopenharmony_ci continue; 457d9f0492fSopenharmony_ci } 458d9f0492fSopenharmony_ci if (CheckMatchSubCondition(head->getCondition(trigger), name, strlen(name)) == 1) { 459d9f0492fSopenharmony_ci TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_RELATED); 460d9f0492fSopenharmony_ci ret = 1; 461d9f0492fSopenharmony_ci } 462d9f0492fSopenharmony_ci trigger = head->nextTrigger(head, trigger); 463d9f0492fSopenharmony_ci } 464d9f0492fSopenharmony_ci return ret; 465d9f0492fSopenharmony_ci} 466d9f0492fSopenharmony_ci 467d9f0492fSopenharmony_ciint CheckTrigger(TriggerWorkSpace *workSpace, int type, 468d9f0492fSopenharmony_ci const char *content, uint32_t contentSize, PARAM_CHECK_DONE triggerCheckDone) 469d9f0492fSopenharmony_ci{ 470d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL && content != NULL && triggerCheckDone != NULL, 471d9f0492fSopenharmony_ci return -1, "Failed arg for trigger"); 472d9f0492fSopenharmony_ci PARAM_LOGV("CheckTrigger_ type: %d content: %s ", type, content); 473d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(workSpace, type); 474d9f0492fSopenharmony_ci if (triggerHead != NULL) { 475d9f0492fSopenharmony_ci LogicCalculator calculator = {{0}}; 476d9f0492fSopenharmony_ci calculator.triggerCheckDone = triggerCheckDone; 477d9f0492fSopenharmony_ci int ret = triggerHead->checkTriggerMatch(workSpace, type, &calculator, content, contentSize); 478d9f0492fSopenharmony_ci CalculatorFree(&calculator); 479d9f0492fSopenharmony_ci return ret; 480d9f0492fSopenharmony_ci } 481d9f0492fSopenharmony_ci return 0; 482d9f0492fSopenharmony_ci} 483d9f0492fSopenharmony_ci 484d9f0492fSopenharmony_cistatic void DumpJobTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode *trigger) 485d9f0492fSopenharmony_ci{ 486d9f0492fSopenharmony_ci const JobNode *node = (const JobNode *)trigger; 487d9f0492fSopenharmony_ci PARAM_DUMP("trigger flags: 0x%08x \n", trigger->flags); 488d9f0492fSopenharmony_ci PARAM_DUMP("trigger name: %s \n", node->name); 489d9f0492fSopenharmony_ci PARAM_DUMP("trigger condition: %s \n", node->condition); 490d9f0492fSopenharmony_ci const int maxCmd = 1024; 491d9f0492fSopenharmony_ci int count = 0; 492d9f0492fSopenharmony_ci CommandNode *cmd = GetNextCmdNode(node, NULL); 493d9f0492fSopenharmony_ci while (cmd != NULL && count < maxCmd) { 494d9f0492fSopenharmony_ci PARAM_DUMP(" command name: %s (%s) \n", GetCmdKey(cmd->cmdKeyIndex), 495d9f0492fSopenharmony_ci (cmd->cfgContext.type == INIT_CONTEXT_CHIPSET) ? "chipset" : "system"); 496d9f0492fSopenharmony_ci PARAM_DUMP(" command args : %s \n", cmd->content); 497d9f0492fSopenharmony_ci cmd = GetNextCmdNode(node, cmd); 498d9f0492fSopenharmony_ci count++; 499d9f0492fSopenharmony_ci } 500d9f0492fSopenharmony_ci} 501d9f0492fSopenharmony_ci 502d9f0492fSopenharmony_cistatic void DumpWatchTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode *trigger) 503d9f0492fSopenharmony_ci{ 504d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return, "Empty trigger"); 505d9f0492fSopenharmony_ci const WatchNode *node = (const WatchNode *)trigger; 506d9f0492fSopenharmony_ci PARAM_DUMP("trigger flags: 0x%08x \n", trigger->flags); 507d9f0492fSopenharmony_ci PARAM_DUMP("trigger condition: %s \n", trigger->condition); 508d9f0492fSopenharmony_ci PARAM_DUMP("trigger watchId: %d \n", node->watchId); 509d9f0492fSopenharmony_ci} 510d9f0492fSopenharmony_ci 511d9f0492fSopenharmony_cistatic void DumpWaitTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode *trigger) 512d9f0492fSopenharmony_ci{ 513d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return, "Empty trigger"); 514d9f0492fSopenharmony_ci const WaitNode *node = (const WaitNode *)trigger; 515d9f0492fSopenharmony_ci PARAM_DUMP("trigger flags: 0x%08x \n", trigger->flags); 516d9f0492fSopenharmony_ci PARAM_DUMP("trigger name: %s \n", GetTriggerName(trigger)); 517d9f0492fSopenharmony_ci PARAM_DUMP("trigger condition: %s \n", trigger->condition); 518d9f0492fSopenharmony_ci PARAM_DUMP("trigger waitId: %d \n", node->waitId); 519d9f0492fSopenharmony_ci PARAM_DUMP("trigger timeout: %d \n", node->timeout); 520d9f0492fSopenharmony_ci} 521d9f0492fSopenharmony_ci 522d9f0492fSopenharmony_cistatic void DumpTrigger_(const TriggerWorkSpace *workSpace, int type) 523d9f0492fSopenharmony_ci{ 524d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return, "Invalid workSpace "); 525d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(workSpace, type); 526d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL, return, "Failed to get header %d", type); 527d9f0492fSopenharmony_ci TriggerNode *trigger = head->nextTrigger(head, NULL); 528d9f0492fSopenharmony_ci while (trigger != NULL) { 529d9f0492fSopenharmony_ci head->dumpTrigger(workSpace, trigger); 530d9f0492fSopenharmony_ci trigger = head->nextTrigger(head, trigger); 531d9f0492fSopenharmony_ci } 532d9f0492fSopenharmony_ci} 533d9f0492fSopenharmony_ci 534d9f0492fSopenharmony_civoid SystemDumpTriggers(int verbose, int (*dump)(const char *fmt, ...)) 535d9f0492fSopenharmony_ci{ 536d9f0492fSopenharmony_ci if (dump != NULL) { 537d9f0492fSopenharmony_ci g_printf = dump; 538d9f0492fSopenharmony_ci } else { 539d9f0492fSopenharmony_ci g_printf = printf; 540d9f0492fSopenharmony_ci } 541d9f0492fSopenharmony_ci TriggerWorkSpace *workSpace = GetTriggerWorkSpace(); 542d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return, "Invalid workSpace "); 543d9f0492fSopenharmony_ci PARAM_DUMP("workspace queue BOOT info:\n"); 544d9f0492fSopenharmony_ci DumpTrigger_(workSpace, TRIGGER_BOOT); 545d9f0492fSopenharmony_ci PARAM_DUMP("workspace queue parameter info:\n"); 546d9f0492fSopenharmony_ci DumpTrigger_(workSpace, TRIGGER_PARAM); 547d9f0492fSopenharmony_ci PARAM_DUMP("workspace queue other info:\n"); 548d9f0492fSopenharmony_ci DumpTrigger_(workSpace, TRIGGER_UNKNOW); 549d9f0492fSopenharmony_ci PARAM_DUMP("workspace queue watch info:\n"); 550d9f0492fSopenharmony_ci DumpTrigger_(workSpace, TRIGGER_PARAM_WATCH); 551d9f0492fSopenharmony_ci PARAM_DUMP("workspace queue wait info:\n"); 552d9f0492fSopenharmony_ci DumpTrigger_(workSpace, TRIGGER_PARAM_WAIT); 553d9f0492fSopenharmony_ci 554d9f0492fSopenharmony_ci PARAM_DUMP("workspace queue execute info:\n"); 555d9f0492fSopenharmony_ci PARAM_DUMP("queue info count: %u start: %u end: %u\n", 556d9f0492fSopenharmony_ci workSpace->executeQueue.queueCount, workSpace->executeQueue.startIndex, workSpace->executeQueue.endIndex); 557d9f0492fSopenharmony_ci for (uint32_t index = workSpace->executeQueue.startIndex; index < workSpace->executeQueue.endIndex; index++) { 558d9f0492fSopenharmony_ci TriggerNode *trigger = workSpace->executeQueue.executeQueue[index % workSpace->executeQueue.queueCount]; 559d9f0492fSopenharmony_ci if (trigger != 0) { 560d9f0492fSopenharmony_ci PARAM_DUMP(" queue node trigger name: %s \n", GetTriggerName(trigger)); 561d9f0492fSopenharmony_ci } 562d9f0492fSopenharmony_ci } 563d9f0492fSopenharmony_ci} 564d9f0492fSopenharmony_ci 565d9f0492fSopenharmony_cistatic int32_t CompareData_(const struct tagTriggerNode_ *trigger, const void *data) 566d9f0492fSopenharmony_ci{ 567d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL && data != NULL, return -1, "Invalid trigger"); 568d9f0492fSopenharmony_ci if (trigger->type == TRIGGER_PARAM_WAIT) { 569d9f0492fSopenharmony_ci WaitNode *node = (WaitNode *)trigger; 570d9f0492fSopenharmony_ci return node->waitId - *(uint32_t *)data; 571d9f0492fSopenharmony_ci } else if (trigger->type == TRIGGER_PARAM_WATCH) { 572d9f0492fSopenharmony_ci WatchNode *node = (WatchNode *)trigger; 573d9f0492fSopenharmony_ci return node->watchId - *(uint32_t *)data; 574d9f0492fSopenharmony_ci } 575d9f0492fSopenharmony_ci return -1; 576d9f0492fSopenharmony_ci} 577d9f0492fSopenharmony_ci 578d9f0492fSopenharmony_cistatic void TriggerHeadSetDefault(TriggerHeader *head) 579d9f0492fSopenharmony_ci{ 580d9f0492fSopenharmony_ci OH_ListInit(&head->triggerList); 581d9f0492fSopenharmony_ci head->triggerCount = 0; 582d9f0492fSopenharmony_ci head->cmdNodeCount = 0; 583d9f0492fSopenharmony_ci head->addTrigger = AddJobTrigger_; 584d9f0492fSopenharmony_ci head->nextTrigger = GetNextTrigger_; 585d9f0492fSopenharmony_ci head->delTrigger = DelJobTrigger_; 586d9f0492fSopenharmony_ci head->executeTrigger = NULL; 587d9f0492fSopenharmony_ci head->checkAndMarkTrigger = CheckAndMarkTrigger_; 588d9f0492fSopenharmony_ci head->checkTriggerMatch = CheckBootMatch_; 589d9f0492fSopenharmony_ci head->checkCondition = CheckBootCondition_; 590d9f0492fSopenharmony_ci head->getCondition = GetBootCondition_; 591d9f0492fSopenharmony_ci head->getTriggerName = GetJobName_; 592d9f0492fSopenharmony_ci head->dumpTrigger = DumpJobTrigger_; 593d9f0492fSopenharmony_ci head->compareData = CompareData_; 594d9f0492fSopenharmony_ci} 595d9f0492fSopenharmony_ci 596d9f0492fSopenharmony_cistatic int JobNodeNodeCompare(const HashNode *node1, const HashNode *node2) 597d9f0492fSopenharmony_ci{ 598d9f0492fSopenharmony_ci JobNode *jobNode1 = HASHMAP_ENTRY(node1, JobNode, hashNode); 599d9f0492fSopenharmony_ci JobNode *jobNode2 = HASHMAP_ENTRY(node2, JobNode, hashNode); 600d9f0492fSopenharmony_ci return strcmp(jobNode1->name, jobNode2->name); 601d9f0492fSopenharmony_ci} 602d9f0492fSopenharmony_ci 603d9f0492fSopenharmony_cistatic int JobNodeKeyCompare(const HashNode *node1, const void *key) 604d9f0492fSopenharmony_ci{ 605d9f0492fSopenharmony_ci JobNode *jobNode1 = HASHMAP_ENTRY(node1, JobNode, hashNode); 606d9f0492fSopenharmony_ci return strcmp(jobNode1->name, (char *)key); 607d9f0492fSopenharmony_ci} 608d9f0492fSopenharmony_ci 609d9f0492fSopenharmony_cistatic int JobNodeGetNodeHasCode(const HashNode *node) 610d9f0492fSopenharmony_ci{ 611d9f0492fSopenharmony_ci JobNode *jobNode = HASHMAP_ENTRY(node, JobNode, hashNode); 612d9f0492fSopenharmony_ci int code = 0; 613d9f0492fSopenharmony_ci size_t nameLen = strlen(jobNode->name); 614d9f0492fSopenharmony_ci for (size_t i = 0; i < nameLen; i++) { 615d9f0492fSopenharmony_ci code += jobNode->name[i] - 'A'; 616d9f0492fSopenharmony_ci } 617d9f0492fSopenharmony_ci return code; 618d9f0492fSopenharmony_ci} 619d9f0492fSopenharmony_ci 620d9f0492fSopenharmony_cistatic int JobNodeGetKeyHasCode(const void *key) 621d9f0492fSopenharmony_ci{ 622d9f0492fSopenharmony_ci int code = 0; 623d9f0492fSopenharmony_ci const char *buff = (char *)key; 624d9f0492fSopenharmony_ci size_t buffLen = strlen(buff); 625d9f0492fSopenharmony_ci for (size_t i = 0; i < buffLen; i++) { 626d9f0492fSopenharmony_ci code += buff[i] - 'A'; 627d9f0492fSopenharmony_ci } 628d9f0492fSopenharmony_ci return code; 629d9f0492fSopenharmony_ci} 630d9f0492fSopenharmony_ci 631d9f0492fSopenharmony_cistatic void JobNodeFree(const HashNode *node, void *context) 632d9f0492fSopenharmony_ci{ 633d9f0492fSopenharmony_ci JobNode *jobNode = HASHMAP_ENTRY(node, JobNode, hashNode); 634d9f0492fSopenharmony_ci FreeTrigger(GetTriggerWorkSpace(), (TriggerNode *)jobNode); 635d9f0492fSopenharmony_ci} 636d9f0492fSopenharmony_ci 637d9f0492fSopenharmony_civoid InitTriggerHead(const TriggerWorkSpace *workSpace) 638d9f0492fSopenharmony_ci{ 639d9f0492fSopenharmony_ci HashInfo info = { 640d9f0492fSopenharmony_ci JobNodeNodeCompare, 641d9f0492fSopenharmony_ci JobNodeKeyCompare, 642d9f0492fSopenharmony_ci JobNodeGetNodeHasCode, 643d9f0492fSopenharmony_ci JobNodeGetKeyHasCode, 644d9f0492fSopenharmony_ci JobNodeFree, 645d9f0492fSopenharmony_ci 64 646d9f0492fSopenharmony_ci }; 647d9f0492fSopenharmony_ci PARAM_CHECK(workSpace != NULL, return, "Invalid workSpace"); 648d9f0492fSopenharmony_ci int ret = OH_HashMapCreate((HashMapHandle *)&workSpace->hashMap, &info); 649d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return, "Failed to create hash map"); 650d9f0492fSopenharmony_ci 651d9f0492fSopenharmony_ci TriggerHeader *head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_BOOT]; 652d9f0492fSopenharmony_ci TriggerHeadSetDefault(head); 653d9f0492fSopenharmony_ci // param trigger 654d9f0492fSopenharmony_ci head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_PARAM]; 655d9f0492fSopenharmony_ci TriggerHeadSetDefault(head); 656d9f0492fSopenharmony_ci head->checkTriggerMatch = CheckParamMatch_; 657d9f0492fSopenharmony_ci head->checkCondition = CheckParamCondition_; 658d9f0492fSopenharmony_ci head->getCondition = GetTriggerCondition_; 659d9f0492fSopenharmony_ci // unknown trigger 660d9f0492fSopenharmony_ci head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_UNKNOW]; 661d9f0492fSopenharmony_ci TriggerHeadSetDefault(head); 662d9f0492fSopenharmony_ci head->checkTriggerMatch = CheckUnknowMatch_; 663d9f0492fSopenharmony_ci head->checkCondition = CheckUnknowCondition_; 664d9f0492fSopenharmony_ci head->getCondition = GetTriggerCondition_; 665d9f0492fSopenharmony_ci // wait trigger 666d9f0492fSopenharmony_ci head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_PARAM_WAIT]; 667d9f0492fSopenharmony_ci TriggerHeadSetDefault(head); 668d9f0492fSopenharmony_ci head->addTrigger = AddWatchTrigger_; 669d9f0492fSopenharmony_ci head->delTrigger = DelWatchTrigger_; 670d9f0492fSopenharmony_ci head->checkTriggerMatch = CheckParamMatch_; 671d9f0492fSopenharmony_ci head->checkCondition = CheckParamCondition_; 672d9f0492fSopenharmony_ci head->getCondition = GetTriggerCondition_; 673d9f0492fSopenharmony_ci head->dumpTrigger = DumpWaitTrigger_; 674d9f0492fSopenharmony_ci head->getTriggerName = GetWatchName_; 675d9f0492fSopenharmony_ci // watch trigger 676d9f0492fSopenharmony_ci head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_PARAM_WATCH]; 677d9f0492fSopenharmony_ci TriggerHeadSetDefault(head); 678d9f0492fSopenharmony_ci head->addTrigger = AddWatchTrigger_; 679d9f0492fSopenharmony_ci head->delTrigger = DelWatchTrigger_; 680d9f0492fSopenharmony_ci head->checkTriggerMatch = CheckBootMatch_; 681d9f0492fSopenharmony_ci head->checkCondition = CheckWatchCondition_; 682d9f0492fSopenharmony_ci head->getCondition = GetTriggerCondition_; 683d9f0492fSopenharmony_ci head->dumpTrigger = DumpWatchTrigger_; 684d9f0492fSopenharmony_ci head->getTriggerName = GetWatchName_; 685d9f0492fSopenharmony_ci} 686d9f0492fSopenharmony_ci 687d9f0492fSopenharmony_civoid DelWatchTrigger(int type, const void *data) 688d9f0492fSopenharmony_ci{ 689d9f0492fSopenharmony_ci PARAM_CHECK(data != NULL, return, "Invalid data"); 690d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(GetTriggerWorkSpace(), type); 691d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL, return, "Failed to get header %d", type); 692d9f0492fSopenharmony_ci PARAM_CHECK(head->compareData != NULL, return, "Invalid compareData"); 693d9f0492fSopenharmony_ci TriggerNode *trigger = head->nextTrigger(head, NULL); 694d9f0492fSopenharmony_ci while (trigger != NULL) { 695d9f0492fSopenharmony_ci if (head->compareData(trigger, data) == 0) { 696d9f0492fSopenharmony_ci head->delTrigger(GetTriggerWorkSpace(), trigger); 697d9f0492fSopenharmony_ci return; 698d9f0492fSopenharmony_ci } 699d9f0492fSopenharmony_ci trigger = head->nextTrigger(head, trigger); 700d9f0492fSopenharmony_ci } 701d9f0492fSopenharmony_ci} 702d9f0492fSopenharmony_ci 703d9f0492fSopenharmony_civoid ClearWatchTrigger(ParamWatcher *watcher, int type) 704d9f0492fSopenharmony_ci{ 705d9f0492fSopenharmony_ci PARAM_CHECK(watcher != NULL, return, "Invalid watcher"); 706d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(GetTriggerWorkSpace(), type); 707d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL, return, "Failed to get header %d", type); 708d9f0492fSopenharmony_ci ListNode *node = watcher->triggerHead.next; 709d9f0492fSopenharmony_ci while (node != &watcher->triggerHead) { 710d9f0492fSopenharmony_ci TriggerNode *trigger = NULL; 711d9f0492fSopenharmony_ci if (type == TRIGGER_PARAM_WAIT) { 712d9f0492fSopenharmony_ci trigger = (TriggerNode *)ListEntry(node, WaitNode, item); 713d9f0492fSopenharmony_ci } else if (type == TRIGGER_PARAM_WATCH) { 714d9f0492fSopenharmony_ci trigger = (TriggerNode *)ListEntry(node, WatchNode, item); 715d9f0492fSopenharmony_ci } 716d9f0492fSopenharmony_ci if (trigger == NULL || type != trigger->type) { 717d9f0492fSopenharmony_ci PARAM_LOGE("ClearWatchTrigger %s error type %d", GetTriggerName(trigger), type); 718d9f0492fSopenharmony_ci return; 719d9f0492fSopenharmony_ci } 720d9f0492fSopenharmony_ci PARAM_LOGV("ClearWatchTrigger %s", GetTriggerName(trigger)); 721d9f0492fSopenharmony_ci ListNode *next = node->next; 722d9f0492fSopenharmony_ci FreeTrigger(GetTriggerWorkSpace(), trigger); 723d9f0492fSopenharmony_ci node = next; 724d9f0492fSopenharmony_ci } 725d9f0492fSopenharmony_ci} 726d9f0492fSopenharmony_ci 727d9f0492fSopenharmony_ciint CheckWatchTriggerTimeout(void) 728d9f0492fSopenharmony_ci{ 729d9f0492fSopenharmony_ci TriggerHeader *head = GetTriggerHeader(GetTriggerWorkSpace(), TRIGGER_PARAM_WAIT); 730d9f0492fSopenharmony_ci PARAM_CHECK(head != NULL && head->nextTrigger != NULL, return 0, "Invalid header"); 731d9f0492fSopenharmony_ci int hasNode = 0; 732d9f0492fSopenharmony_ci WaitNode *node = (WaitNode *)head->nextTrigger(head, NULL); 733d9f0492fSopenharmony_ci while (node != NULL) { 734d9f0492fSopenharmony_ci WaitNode *next = (WaitNode *)head->nextTrigger(head, (TriggerNode *)node); 735d9f0492fSopenharmony_ci if (node->timeout > 0) { 736d9f0492fSopenharmony_ci node->timeout--; 737d9f0492fSopenharmony_ci } else { 738d9f0492fSopenharmony_ci head->executeTrigger((TriggerNode*)node, NULL, 0); 739d9f0492fSopenharmony_ci FreeTrigger(GetTriggerWorkSpace(), (TriggerNode *)node); 740d9f0492fSopenharmony_ci } 741d9f0492fSopenharmony_ci hasNode = 1; 742d9f0492fSopenharmony_ci node = next; 743d9f0492fSopenharmony_ci } 744d9f0492fSopenharmony_ci return hasNode; 745d9f0492fSopenharmony_ci} 746d9f0492fSopenharmony_ci 747d9f0492fSopenharmony_ciTriggerHeader *GetTriggerHeader(const TriggerWorkSpace *workSpace, int type) 748d9f0492fSopenharmony_ci{ 749d9f0492fSopenharmony_ci if (workSpace == NULL || type >= TRIGGER_MAX) { 750d9f0492fSopenharmony_ci return NULL; 751d9f0492fSopenharmony_ci } 752d9f0492fSopenharmony_ci return (TriggerHeader *)&workSpace->triggerHead[type]; 753d9f0492fSopenharmony_ci} 754d9f0492fSopenharmony_ci 755d9f0492fSopenharmony_cichar *GetTriggerCache(uint32_t *size) 756d9f0492fSopenharmony_ci{ 757d9f0492fSopenharmony_ci TriggerWorkSpace *space = GetTriggerWorkSpace(); 758d9f0492fSopenharmony_ci if (space == NULL) { 759d9f0492fSopenharmony_ci return NULL; 760d9f0492fSopenharmony_ci } 761d9f0492fSopenharmony_ci if (size != NULL) { 762d9f0492fSopenharmony_ci *size = sizeof(space->cache) / sizeof(space->cache[0]); 763d9f0492fSopenharmony_ci } 764d9f0492fSopenharmony_ci return space->cache; 765d9f0492fSopenharmony_ci} 766d9f0492fSopenharmony_ci 767d9f0492fSopenharmony_ciconst char *GetTriggerName(const TriggerNode *trigger) 768d9f0492fSopenharmony_ci{ 769d9f0492fSopenharmony_ci PARAM_CHECK(trigger != NULL, return "", "Invalid trigger"); 770d9f0492fSopenharmony_ci TriggerHeader *triggerHead = GetTriggerHeader(GetTriggerWorkSpace(), trigger->type); 771d9f0492fSopenharmony_ci if (triggerHead) { 772d9f0492fSopenharmony_ci return triggerHead->getTriggerName(trigger); 773d9f0492fSopenharmony_ci } 774d9f0492fSopenharmony_ci return ""; 775d9f0492fSopenharmony_ci} 776