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#ifndef STARTUP_TRIGER_MANAGER_H
17d9f0492fSopenharmony_ci#define STARTUP_TRIGER_MANAGER_H
18d9f0492fSopenharmony_ci#include <stdint.h>
19d9f0492fSopenharmony_ci
20d9f0492fSopenharmony_ci#include "cJSON.h"
21d9f0492fSopenharmony_ci#include "init_cmds.h"
22d9f0492fSopenharmony_ci#include "init_hashmap.h"
23d9f0492fSopenharmony_ci#include "list.h"
24d9f0492fSopenharmony_ci#include "param_message.h"
25d9f0492fSopenharmony_ci#include "param_utils.h"
26d9f0492fSopenharmony_ci#include "trigger_checker.h"
27d9f0492fSopenharmony_ci
28d9f0492fSopenharmony_ci#ifdef __cplusplus
29d9f0492fSopenharmony_ci#if __cplusplus
30d9f0492fSopenharmony_ciextern "C" {
31d9f0492fSopenharmony_ci#endif
32d9f0492fSopenharmony_ci#endif
33d9f0492fSopenharmony_ci
34d9f0492fSopenharmony_ci#define TRIGGER_CMD "trigger "
35d9f0492fSopenharmony_ci#define TRIGGER_ARR_NAME_IN_JSON "jobs"
36d9f0492fSopenharmony_ci#define CMDS_ARR_NAME_IN_JSON "cmds"
37d9f0492fSopenharmony_ci#define TRIGGER_MAX_CMD 4096
38d9f0492fSopenharmony_ci
39d9f0492fSopenharmony_ci#define TRIGGER_EXECUTE_QUEUE 64
40d9f0492fSopenharmony_ci#define MAX_CONDITION_NUMBER 64
41d9f0492fSopenharmony_ci
42d9f0492fSopenharmony_ci#define TRIGGER_FLAGS_QUEUE 0x01
43d9f0492fSopenharmony_ci#define TRIGGER_FLAGS_RELATED 0x02
44d9f0492fSopenharmony_ci#define TRIGGER_FLAGS_ONCE 0x04       // 执行完成后释放
45d9f0492fSopenharmony_ci#define TRIGGER_FLAGS_SUBTRIGGER 0x08 // 对init执行后,需要执行的init:xxx=aaa的trigger
46d9f0492fSopenharmony_ci
47d9f0492fSopenharmony_ci#define CMD_INDEX_FOR_PARA_WAIT 0xfffE
48d9f0492fSopenharmony_ci#define CMD_INDEX_FOR_PARA_WATCH 0xffff
49d9f0492fSopenharmony_ci#define CMD_INDEX_FOR_PARA_TEST 0x10000
50d9f0492fSopenharmony_ci
51d9f0492fSopenharmony_ci#define TRIGGER_IN_QUEUE(trigger) (((trigger)->flags & TRIGGER_FLAGS_QUEUE) == TRIGGER_FLAGS_QUEUE)
52d9f0492fSopenharmony_ci#define TRIGGER_SET_FLAG(trigger, flag) ((trigger)->flags |= (flag))
53d9f0492fSopenharmony_ci#define TRIGGER_CLEAR_FLAG(trigger, flag) ((trigger)->flags &= ~(flag))
54d9f0492fSopenharmony_ci#define TRIGGER_TEST_FLAG(trigger, flag) (((trigger)->flags & (flag)) == (flag))
55d9f0492fSopenharmony_ci
56d9f0492fSopenharmony_citypedef enum {
57d9f0492fSopenharmony_ci    TRIGGER_BOOT = 0,
58d9f0492fSopenharmony_ci    TRIGGER_PARAM,
59d9f0492fSopenharmony_ci    TRIGGER_UNKNOW,
60d9f0492fSopenharmony_ci    TRIGGER_PARAM_WAIT,
61d9f0492fSopenharmony_ci    TRIGGER_PARAM_WATCH,
62d9f0492fSopenharmony_ci    TRIGGER_MAX,
63d9f0492fSopenharmony_ci} TriggerType;
64d9f0492fSopenharmony_ci
65d9f0492fSopenharmony_ci#define PARAM_TRIGGER_FOR_WAIT 0
66d9f0492fSopenharmony_ci#define PARAM_TRIGGER_FOR_WATCH 1
67d9f0492fSopenharmony_ci
68d9f0492fSopenharmony_cistruct tagTriggerNode_;
69d9f0492fSopenharmony_cistruct TriggerWorkSpace_;
70d9f0492fSopenharmony_citypedef struct TriggerExtInfo_ {
71d9f0492fSopenharmony_ci    int8_t type;
72d9f0492fSopenharmony_ci    ParamTaskPtr stream;
73d9f0492fSopenharmony_ci    union {
74d9f0492fSopenharmony_ci        char *name;
75d9f0492fSopenharmony_ci        struct {
76d9f0492fSopenharmony_ci            uint32_t watchId;
77d9f0492fSopenharmony_ci        } watchInfo;
78d9f0492fSopenharmony_ci        struct {
79d9f0492fSopenharmony_ci            uint32_t timeout;
80d9f0492fSopenharmony_ci            uint32_t waitId;
81d9f0492fSopenharmony_ci        } waitInfo;
82d9f0492fSopenharmony_ci    } info;
83d9f0492fSopenharmony_ci    int32_t (*addNode)(struct tagTriggerNode_ *, const struct TriggerExtInfo_ *);
84d9f0492fSopenharmony_ci} TriggerExtInfo;
85d9f0492fSopenharmony_ci
86d9f0492fSopenharmony_citypedef struct TriggerHeader_ {
87d9f0492fSopenharmony_ci    ListNode triggerList;
88d9f0492fSopenharmony_ci    uint32_t triggerCount;
89d9f0492fSopenharmony_ci    uint32_t cmdNodeCount;
90d9f0492fSopenharmony_ci    struct tagTriggerNode_ *(*addTrigger)(const struct TriggerWorkSpace_ *workSpace,
91d9f0492fSopenharmony_ci        const char *condition, const TriggerExtInfo *extInfo);
92d9f0492fSopenharmony_ci    struct tagTriggerNode_ *(*nextTrigger)(const struct TriggerHeader_ *, const struct tagTriggerNode_ *);
93d9f0492fSopenharmony_ci    int32_t (*executeTrigger)(const struct tagTriggerNode_ *trigger, const char *content, uint32_t size);
94d9f0492fSopenharmony_ci
95d9f0492fSopenharmony_ci    int32_t (*checkAndMarkTrigger)(const struct TriggerWorkSpace_ *workSpace, int type, const char *name);
96d9f0492fSopenharmony_ci    int32_t (*checkTriggerMatch)(const struct TriggerWorkSpace_ *workSpace, int type,
97d9f0492fSopenharmony_ci        LogicCalculator *calculator, const char *content, uint32_t contentSize);
98d9f0492fSopenharmony_ci    int32_t (*checkCondition)(LogicCalculator *calculator,
99d9f0492fSopenharmony_ci        const char *condition, const char *content, uint32_t contentSize);
100d9f0492fSopenharmony_ci
101d9f0492fSopenharmony_ci    const char *(*getTriggerName)(const struct tagTriggerNode_ *trigger);
102d9f0492fSopenharmony_ci    const char *(*getCondition)(const struct tagTriggerNode_ *trigger);
103d9f0492fSopenharmony_ci    void (*delTrigger)(const struct TriggerWorkSpace_ *workSpace, struct tagTriggerNode_ *trigger);
104d9f0492fSopenharmony_ci    void (*dumpTrigger)(const struct TriggerWorkSpace_ *workSpace,
105d9f0492fSopenharmony_ci        const struct tagTriggerNode_ *trigger);
106d9f0492fSopenharmony_ci    int32_t (*compareData)(const struct tagTriggerNode_ *trigger, const void *data);
107d9f0492fSopenharmony_ci} TriggerHeader;
108d9f0492fSopenharmony_ci
109d9f0492fSopenharmony_citypedef struct CommandNode_ {
110d9f0492fSopenharmony_ci    struct CommandNode_ *next;
111d9f0492fSopenharmony_ci    ConfigContext cfgContext;
112d9f0492fSopenharmony_ci    uint32_t cmdKeyIndex;
113d9f0492fSopenharmony_ci    char content[0];
114d9f0492fSopenharmony_ci} CommandNode;
115d9f0492fSopenharmony_ci
116d9f0492fSopenharmony_ci#define NODE_BASE \
117d9f0492fSopenharmony_ci    ListNode node; \
118d9f0492fSopenharmony_ci    uint32_t flags : 24; \
119d9f0492fSopenharmony_ci    uint32_t type : 4; \
120d9f0492fSopenharmony_ci    char *condition
121d9f0492fSopenharmony_ci
122d9f0492fSopenharmony_citypedef struct tagTriggerNode_ {
123d9f0492fSopenharmony_ci    NODE_BASE;
124d9f0492fSopenharmony_ci} TriggerNode;
125d9f0492fSopenharmony_ci
126d9f0492fSopenharmony_citypedef struct tagTriggerJobNode_ {
127d9f0492fSopenharmony_ci    NODE_BASE;
128d9f0492fSopenharmony_ci    CommandNode *firstCmd;
129d9f0492fSopenharmony_ci    CommandNode *lastCmd;
130d9f0492fSopenharmony_ci    HashNode hashNode;
131d9f0492fSopenharmony_ci    char name[0];
132d9f0492fSopenharmony_ci} JobNode;
133d9f0492fSopenharmony_ci
134d9f0492fSopenharmony_citypedef struct WatchNode_ {
135d9f0492fSopenharmony_ci    NODE_BASE;
136d9f0492fSopenharmony_ci    ListNode item;
137d9f0492fSopenharmony_ci    uint32_t watchId;
138d9f0492fSopenharmony_ci} WatchNode;
139d9f0492fSopenharmony_ci
140d9f0492fSopenharmony_citypedef struct WaitNode_ {
141d9f0492fSopenharmony_ci    NODE_BASE;
142d9f0492fSopenharmony_ci    ListNode item;
143d9f0492fSopenharmony_ci    uint32_t timeout;
144d9f0492fSopenharmony_ci    uint32_t waitId;
145d9f0492fSopenharmony_ci    ParamTaskPtr stream;
146d9f0492fSopenharmony_ci} WaitNode;
147d9f0492fSopenharmony_ci
148d9f0492fSopenharmony_citypedef struct {
149d9f0492fSopenharmony_ci    uint32_t queueCount;
150d9f0492fSopenharmony_ci    uint32_t startIndex;
151d9f0492fSopenharmony_ci    uint32_t endIndex;
152d9f0492fSopenharmony_ci    TriggerNode **executeQueue;
153d9f0492fSopenharmony_ci} TriggerExecuteQueue;
154d9f0492fSopenharmony_ci
155d9f0492fSopenharmony_citypedef struct {
156d9f0492fSopenharmony_ci    ListHead triggerHead;
157d9f0492fSopenharmony_ci    ParamTaskPtr stream;
158d9f0492fSopenharmony_ci} ParamWatcher;
159d9f0492fSopenharmony_ci
160d9f0492fSopenharmony_citypedef struct TriggerWorkSpace_ {
161d9f0492fSopenharmony_ci    TriggerExecuteQueue executeQueue;
162d9f0492fSopenharmony_ci    TriggerHeader triggerHead[TRIGGER_MAX];
163d9f0492fSopenharmony_ci    HashMapHandle hashMap;
164d9f0492fSopenharmony_ci    ParamTaskPtr eventHandle;
165d9f0492fSopenharmony_ci    void (*bootStateChange)(int start, const char *);
166d9f0492fSopenharmony_ci    char cache[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX];
167d9f0492fSopenharmony_ci} TriggerWorkSpace;
168d9f0492fSopenharmony_ci
169d9f0492fSopenharmony_ciint InitTriggerWorkSpace(void);
170d9f0492fSopenharmony_civoid CloseTriggerWorkSpace(void);
171d9f0492fSopenharmony_ciTriggerWorkSpace *GetTriggerWorkSpace(void);
172d9f0492fSopenharmony_cichar *GetTriggerCache(uint32_t *size);
173d9f0492fSopenharmony_ciTriggerHeader *GetTriggerHeader(const TriggerWorkSpace *workSpace, int type);
174d9f0492fSopenharmony_civoid InitTriggerHead(const TriggerWorkSpace *workSpace);
175d9f0492fSopenharmony_ci
176d9f0492fSopenharmony_ciint CheckTrigger(TriggerWorkSpace *workSpace, int type,
177d9f0492fSopenharmony_ci    const char *content, uint32_t contentSize, PARAM_CHECK_DONE triggerCheckDone);
178d9f0492fSopenharmony_ciint CheckAndMarkTrigger(int type, const char *name);
179d9f0492fSopenharmony_ci
180d9f0492fSopenharmony_ciTriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace);
181d9f0492fSopenharmony_ciint ExecuteQueuePush(TriggerWorkSpace *workSpace, const TriggerNode *trigger);
182d9f0492fSopenharmony_ci
183d9f0492fSopenharmony_ciJobNode *UpdateJobTrigger(const TriggerWorkSpace *workSpace,
184d9f0492fSopenharmony_ci    int type, const char *condition, const char *name);
185d9f0492fSopenharmony_ciJobNode *GetTriggerByName(const TriggerWorkSpace *workSpace, const char *triggerName);
186d9f0492fSopenharmony_civoid FreeTrigger(const TriggerWorkSpace *workSpace, TriggerNode *trigger);
187d9f0492fSopenharmony_civoid ClearTrigger(const TriggerWorkSpace *workSpace, int8_t type);
188d9f0492fSopenharmony_ciint AddCommand(JobNode *trigger, uint32_t cmdIndex, const char *content, const ConfigContext *cfgContext);
189d9f0492fSopenharmony_ciCommandNode *GetNextCmdNode(const JobNode *trigger, const CommandNode *curr);
190d9f0492fSopenharmony_ci
191d9f0492fSopenharmony_civoid PostParamTrigger(int type, const char *name, const char *value);
192d9f0492fSopenharmony_ci
193d9f0492fSopenharmony_civoid ClearWatchTrigger(ParamWatcher *watcher, int type);
194d9f0492fSopenharmony_civoid DelWatchTrigger(int type, const void *data);
195d9f0492fSopenharmony_ciint CheckWatchTriggerTimeout(void);
196d9f0492fSopenharmony_ci
197d9f0492fSopenharmony_ciconst char *GetTriggerName(const TriggerNode *trigger);
198d9f0492fSopenharmony_civoid RegisterTriggerExec(int type, int32_t (*executeTrigger)(const TriggerNode *, const char *, uint32_t));
199d9f0492fSopenharmony_ci
200d9f0492fSopenharmony_ci#ifdef STARTUP_INIT_TEST
201d9f0492fSopenharmony_civoid ProcessBeforeEvent(const ParamTaskPtr stream, uint64_t eventId, const uint8_t *content, uint32_t size);
202d9f0492fSopenharmony_ci#endif
203d9f0492fSopenharmony_ci#ifdef __cplusplus
204d9f0492fSopenharmony_ci#if __cplusplus
205d9f0492fSopenharmony_ci}
206d9f0492fSopenharmony_ci#endif
207d9f0492fSopenharmony_ci#endif
208d9f0492fSopenharmony_ci#endif // STARTUP_TRIGER_MANAGER_H
209