trigger_manager.c 29.2 KB
Newer Older
Z
zhong_ning 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "trigger_manager.h"

S
sun_fan 已提交
18
#include <string.h>
Z
zhong_ning 已提交
19 20 21
#include <sys/types.h>

#include "init_cmds.h"
S
sun_fan 已提交
22
#include "param_manager.h"
Z
zhong_ning 已提交
23
#include "trigger_checker.h"
M
Mupceet 已提交
24
#include "securec.h"
Z
zhong_ning 已提交
25

C
cheng_jinsong 已提交
26 27
static DUMP_PRINTF g_printf = printf;

X
xionglei6 已提交
28
int AddCommand(JobNode *trigger, uint32_t cmdKeyIndex, const char *content)
Z
zhong_ning 已提交
29
{
X
xionglei6 已提交
30
    PARAM_CHECK(trigger != NULL, return -1, "trigger is null");
S
sun_fan 已提交
31
    uint32_t size = sizeof(CommandNode);
4
411148299@qq.com 已提交
32
    size += (content == NULL) ? 1 : (strlen(content) + 1);
S
sun_fan 已提交
33 34
    size = PARAM_ALIGN(size);

4
411148299@qq.com 已提交
35
    CommandNode *node = (CommandNode *)calloc(1, size);
S
sun_fan 已提交
36 37 38 39 40 41 42
    PARAM_CHECK(node != NULL, return -1, "Failed to alloc memory for command");
    node->cmdKeyIndex = cmdKeyIndex;
    node->next = NULL;
    node->content[0] = '\0';
    if (content != NULL && strlen(content) != 0) {
        int ret = memcpy_s(node->content, size, content, strlen(content));
        node->content[strlen(content)] = '\0';
4
411148299@qq.com 已提交
43
        PARAM_CHECK(ret == EOK, free(node);
44
            return 0, "Failed to copy command");
Z
zhong_ning 已提交
45
    }
C
cheng_jinsong 已提交
46

S
sun_fan 已提交
47 48 49 50
    if (trigger->firstCmd == NULL) {
        trigger->firstCmd = node;
        trigger->lastCmd = node;
    } else {
S
sun_fan 已提交
51 52
        PARAM_CHECK(trigger->lastCmd != NULL, free(node);
            return 0, "Invalid last cmd");
S
sun_fan 已提交
53 54
        trigger->lastCmd->next = node;
        trigger->lastCmd = node;
Z
zhong_ning 已提交
55 56 57 58
    }
    return 0;
}

X
xionglei6 已提交
59
CommandNode *GetNextCmdNode(const JobNode *trigger, const CommandNode *curr)
Z
zhong_ning 已提交
60
{
4
411148299@qq.com 已提交
61
    PARAM_CHECK(trigger != NULL, return NULL, "trigger is null");
S
sun_fan 已提交
62 63
    if (curr == NULL) {
        return trigger->firstCmd;
Z
zhong_ning 已提交
64
    }
S
sun_fan 已提交
65
    return curr->next;
Z
zhong_ning 已提交
66 67
}

X
xionglei6 已提交
68
static int CopyCondition(TriggerNode *node, const char *condition)
Z
zhong_ning 已提交
69
{
X
xionglei6 已提交
70 71
    if (condition == NULL || strlen(condition) == 0) {
        return 0;
Z
zhong_ning 已提交
72
    }
X
xionglei6 已提交
73 74 75 76 77 78 79 80
    uint32_t buffSize = 0;
    char *cond = GetTriggerCache(&buffSize);
    int ret = ConvertInfixToPrefix(condition, cond, buffSize);
    PARAM_CHECK(ret == 0, return -1, "Failed to convert condition for trigger");
    node->condition = strdup(cond);
    PARAM_CHECK(node->condition != NULL, return -1, "Failed to dup conditition");
    return 0;
}
Z
zhong_ning 已提交
81

X
xionglei6 已提交
82 83 84 85
static TriggerNode *AddTriggerNode_(TriggerHeader *triggerHead,
    uint32_t type, const char *condition, uint32_t dataSize)
{
    TriggerNode *node = (TriggerNode *)calloc(1, dataSize);
S
sun_fan 已提交
86 87
    PARAM_CHECK(node != NULL, return NULL, "Failed to alloc memory for trigger");
    node->condition = NULL;
X
xionglei6 已提交
88 89 90 91
    int ret = CopyCondition(node, condition);
    PARAM_CHECK(ret == 0, free(node);
            return NULL, "Failed to copy conditition");
    node->type = type;
S
sun_fan 已提交
92
    node->flags = 0;
93 94
    OH_ListInit(&node->node);
    OH_ListAddTail(&triggerHead->triggerList, &node->node);
S
sun_fan 已提交
95 96
    triggerHead->triggerCount++;
    return node;
Z
zhong_ning 已提交
97 98
}

X
xionglei6 已提交
99
static int32_t AddJobNode_(TriggerNode *trigger, const TriggerExtInfo *extInfo)
Z
zhong_ning 已提交
100
{
X
xionglei6 已提交
101 102 103 104 105
    JobNode *node = (JobNode *)trigger;
    int ret = strcpy_s(node->name, strlen(extInfo->info.name) + 1, extInfo->info.name);
    PARAM_CHECK(ret == EOK, return -1, "Failed to copy name for trigger");
    node->firstCmd = NULL;
    node->lastCmd = NULL;
106
    ret = OH_HashMapAdd(GetTriggerWorkSpace()->hashMap, &node->hashNode);
X
xionglei6 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    PARAM_CHECK(ret == 0, return -1, "Failed to add hash node");
    return 0;
}

static TriggerNode *AddJobTrigger_(const TriggerWorkSpace *workSpace,
    const char *condition, const TriggerExtInfo *extInfo)
{
    PARAM_CHECK(workSpace != NULL, return NULL, "workSpace is null");
    PARAM_CHECK(extInfo != NULL && extInfo->addNode != NULL, return NULL, "extInfo is null");
    PARAM_CHECK(extInfo->type <= TRIGGER_UNKNOW, return NULL, "Invalid type");
    TriggerHeader *triggerHead = GetTriggerHeader(workSpace, extInfo->type);
    PARAM_CHECK(triggerHead != NULL, return NULL, "Failed to get header %d", extInfo->type);
    uint32_t nameLen = strlen(extInfo->info.name);
    uint32_t triggerNodeLen = PARAM_ALIGN(nameLen + 1) + sizeof(JobNode);
    TriggerNode *node = (TriggerNode *)AddTriggerNode_(triggerHead, extInfo->type, condition, triggerNodeLen);
    PARAM_CHECK(node != NULL, return NULL, "Failed to alloc jobnode");
    int ret = extInfo->addNode(node, extInfo);
    PARAM_CHECK(ret == 0, FreeTrigger(workSpace, node);
        return NULL, "Failed to add hash node");
    if (extInfo->type == TRIGGER_BOOT) {
        TRIGGER_SET_FLAG(node, TRIGGER_FLAGS_ONCE);
C
cheng_jinsong 已提交
128 129 130
        if (strncmp("boot-service:", extInfo->info.name, strlen("boot-service:")) != 0) {
            TRIGGER_SET_FLAG(node, TRIGGER_FLAGS_SUBTRIGGER);
        }
Z
zhong_ning 已提交
131
    }
X
xionglei6 已提交
132
    return node;
Z
zhong_ning 已提交
133 134
}

X
xionglei6 已提交
135
static void DelJobTrigger_(const TriggerWorkSpace *workSpace, TriggerNode *trigger)
Z
zhong_ning 已提交
136
{
X
xionglei6 已提交
137 138 139 140 141 142
    PARAM_CHECK(workSpace != NULL, return, "Param is null");
    PARAM_CHECK(trigger != NULL, return, "Trigger is null");
    JobNode *jobNode = (JobNode *)trigger;
    TriggerHeader *triggerHead = GetTriggerHeader(workSpace, trigger->type);
    PARAM_CHECK(triggerHead != NULL, return, "Failed to get header %d", trigger->type);
    CommandNode *cmd = jobNode->firstCmd;
S
sun_fan 已提交
143 144 145
    while (cmd != NULL) {
        CommandNode *next = cmd->next;
        free(cmd);
X
xionglei6 已提交
146
        triggerHead->cmdNodeCount--;
S
sun_fan 已提交
147
        cmd = next;
Z
zhong_ning 已提交
148
    }
X
xionglei6 已提交
149 150 151
    if (jobNode->condition != NULL) {
        free(jobNode->condition);
        jobNode->condition = NULL;
X
xionglei6 已提交
152
    }
X
xionglei6 已提交
153 154
    jobNode->lastCmd = NULL;
    jobNode->firstCmd = NULL;
155
    OH_ListRemove(&trigger->node);
X
xionglei6 已提交
156
    triggerHead->triggerCount--;
157
    OH_HashMapRemove(workSpace->hashMap, jobNode->name);
S
sun_fan 已提交
158 159

    if (!TRIGGER_IN_QUEUE(trigger)) {
X
xionglei6 已提交
160
        free(jobNode);
S
sun_fan 已提交
161
        return;
Z
zhong_ning 已提交
162
    }
X
xionglei6 已提交
163
    TriggerExecuteQueue *executeQueue = (TriggerExecuteQueue *)&workSpace->executeQueue;
S
sun_fan 已提交
164 165 166 167
    for (uint32_t i = executeQueue->startIndex; i < executeQueue->endIndex; i++) {
        if (executeQueue->executeQueue[i] == trigger) {
            executeQueue->executeQueue[i] = NULL;
            break;
Z
zhong_ning 已提交
168 169
        }
    }
X
xionglei6 已提交
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
    free(jobNode);
}

static TriggerNode *AddWatchTrigger_(const TriggerWorkSpace *workSpace,
    const char *condition, const TriggerExtInfo *extInfo)
{
    PARAM_CHECK(workSpace != NULL, return NULL, "workSpace is null");
    PARAM_CHECK(extInfo != NULL && extInfo->addNode != NULL, return NULL, "extInfo is null");
    TriggerHeader *triggerHead = GetTriggerHeader(workSpace, extInfo->type);
    PARAM_CHECK(triggerHead != NULL, return NULL, "Failed to get header %d", extInfo->type);
    uint32_t size = 0;
    if (extInfo->type == TRIGGER_PARAM_WATCH) {
        size = sizeof(WatchNode);
    } else if (extInfo->type == TRIGGER_PARAM_WAIT) {
        size = sizeof(WaitNode);
    } else {
        PARAM_LOGE("Invalid trigger type %d", extInfo->type);
        return NULL;
    }
    TriggerNode *node = AddTriggerNode_(triggerHead, extInfo->type, condition, size);
    PARAM_CHECK(node != NULL, return NULL, "Failed to alloc memory for trigger");
    int ret = extInfo->addNode(node, extInfo);
    PARAM_CHECK(ret == 0, FreeTrigger(workSpace, node);
        return NULL, "Failed to add node");
    if (extInfo->type == TRIGGER_PARAM_WAIT) {
        TRIGGER_SET_FLAG(node, TRIGGER_FLAGS_ONCE);
    }
    return node;
}

static void DelWatchTrigger_(const TriggerWorkSpace *workSpace, TriggerNode *trigger)
{
    PARAM_CHECK(workSpace != NULL, return, "Param is null");
    TriggerHeader *triggerHead = GetTriggerHeader(workSpace, trigger->type);
    PARAM_CHECK(triggerHead != NULL, return, "Failed to get header %d", trigger->type);
205
    OH_ListRemove(&trigger->node);
X
xionglei6 已提交
206 207
    if (trigger->type == TRIGGER_PARAM_WAIT) {
        WaitNode *node = (WaitNode *)trigger;
208
        OH_ListRemove(&node->item);
X
xionglei6 已提交
209 210
    } else if (trigger->type == TRIGGER_PARAM_WATCH) {
        WatchNode *node = (WatchNode *)trigger;
211
        OH_ListRemove(&node->item);
X
xionglei6 已提交
212 213 214
    }
    PARAM_LOGV("DelWatchTrigger_ %s count %d", GetTriggerName(trigger), triggerHead->triggerCount);
    triggerHead->triggerCount--;
S
sun_fan 已提交
215
    free(trigger);
Z
zhong_ning 已提交
216 217
}

X
xionglei6 已提交
218
static TriggerNode *GetNextTrigger_(const TriggerHeader *triggerHead, const TriggerNode *curr)
Z
zhong_ning 已提交
219
{
4
411148299@qq.com 已提交
220
    PARAM_CHECK(triggerHead != NULL, return NULL, "Invalid triggerHead");
S
sun_fan 已提交
221 222 223 224 225
    ListNode *node = NULL;
    if (curr != NULL) {
        node = curr->node.next;
    } else {
        node = triggerHead->triggerList.next;
Z
zhong_ning 已提交
226
    }
S
sun_fan 已提交
227 228
    if (node != &triggerHead->triggerList) {
        return ListEntry(node, TriggerNode, node);
Z
zhong_ning 已提交
229
    }
S
sun_fan 已提交
230
    return NULL;
Z
zhong_ning 已提交
231 232
}

X
xionglei6 已提交
233
static const char *GetTriggerCondition_(const TriggerNode *trigger)
Z
zhong_ning 已提交
234
{
4
411148299@qq.com 已提交
235
    return (trigger == NULL || trigger->condition == NULL) ? "" : trigger->condition;
Z
zhong_ning 已提交
236 237
}

X
xionglei6 已提交
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
static const char *GetBootCondition_(const TriggerNode *trigger)
{
    PARAM_CHECK(trigger != NULL, return "", "Invalid trigger");
    PARAM_CHECK(trigger->type == TRIGGER_BOOT, return "", "Invalid type");
    const JobNode *node = (const JobNode *)trigger;
    return node->name;
}

static const char *GetJobName_(const TriggerNode *trigger)
{
    PARAM_CHECK(trigger != NULL, return "", "Invalid trigger");
    PARAM_CHECK(trigger->type <= TRIGGER_UNKNOW, return "", "Invalid type");
    const JobNode *node = (const JobNode *)trigger;
    return node->name;
}

static const char *GetWatchName_(const TriggerNode *trigger)
{
    PARAM_CHECK(trigger != NULL, return "", "Invalid trigger");
    PARAM_CHECK(trigger->type < TRIGGER_MAX && trigger->type > TRIGGER_UNKNOW,
        return "", "Invalid type");
    return trigger->condition;
}

JobNode *UpdateJobTrigger(const TriggerWorkSpace *workSpace,
    int type, const char *condition, const char *name)
{
    PARAM_CHECK(workSpace != NULL && name != NULL, return NULL, "name is null");
    PARAM_CHECK(type <= TRIGGER_UNKNOW, return NULL, "Invalid type");
    TriggerHeader *triggerHead = GetTriggerHeader(workSpace, type);
    PARAM_CHECK(triggerHead != NULL, return NULL, "Failed to get header %d", type);
    JobNode *jobNode = GetTriggerByName(workSpace, name);
    if (jobNode == NULL) {
        TriggerExtInfo extInfo = {};
        extInfo.info.name = (char *)name;
        extInfo.type = type;
        extInfo.addNode = AddJobNode_;
        return (JobNode *)triggerHead->addTrigger(workSpace, condition, &extInfo);
    } else if (jobNode->condition == NULL && condition != NULL) {
        int ret = CopyCondition((TriggerNode *)jobNode, condition);
        PARAM_CHECK(ret == 0, FreeTrigger(workSpace, (TriggerNode*)jobNode);
            return NULL, "Failed to copy conditition");
    }
    return jobNode;
}

JobNode *GetTriggerByName(const TriggerWorkSpace *workSpace, const char *triggerName)
Z
zhong_ning 已提交
285
{
S
sun_fan 已提交
286
    PARAM_CHECK(workSpace != NULL && triggerName != NULL, return NULL, "Invalid param");
287
    HashNode *node = OH_HashMapGet(workSpace->hashMap, triggerName);
X
xionglei6 已提交
288 289
    if (node == NULL) {
        return NULL;
Z
zhong_ning 已提交
290
    }
X
xionglei6 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
    JobNode *trigger = HASHMAP_ENTRY(node, JobNode, hashNode);
    return trigger;
}

void FreeTrigger(const TriggerWorkSpace *workSpace, TriggerNode *trigger)
{
    PARAM_CHECK(workSpace != NULL && trigger != NULL, return, "Invalid param");
    TriggerHeader *head = GetTriggerHeader(workSpace, trigger->type);
    if (head != NULL) {
        head->delTrigger(workSpace, trigger);
    }
}

void ClearTrigger(const TriggerWorkSpace *workSpace, int8_t type)
{
    PARAM_CHECK(workSpace != NULL, return, "head is null");
    TriggerHeader *head = GetTriggerHeader(workSpace, type);
    PARAM_CHECK(head != NULL, return, "Failed to get header %d", type);
    TriggerNode *trigger = head->nextTrigger(head, NULL);
    while (trigger != NULL) {
        TriggerNode *next = head->nextTrigger(head, trigger);
        FreeTrigger(workSpace, trigger);
        trigger = next;
    }
315
    OH_ListInit(&head->triggerList);
Z
zhong_ning 已提交
316 317
}

4
411148299@qq.com 已提交
318
int ExecuteQueuePush(TriggerWorkSpace *workSpace, const TriggerNode *trigger)
Z
zhong_ning 已提交
319
{
4
411148299@qq.com 已提交
320
    PARAM_CHECK(workSpace != NULL, return -1, "Invalid workSpace");
S
sun_fan 已提交
321
    uint32_t index = workSpace->executeQueue.endIndex++ % workSpace->executeQueue.queueCount;
4
411148299@qq.com 已提交
322
    workSpace->executeQueue.executeQueue[index] = (TriggerNode *)trigger;
Z
zhong_ning 已提交
323 324 325 326 327
    return 0;
}

TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace)
{
4
411148299@qq.com 已提交
328
    PARAM_CHECK(workSpace != NULL, return NULL, "Invalid workSpace");
S
sun_fan 已提交
329 330 331 332 333 334 335 336 337 338 339
    TriggerNode *trigger = NULL;
    do {
        if (workSpace->executeQueue.endIndex <= workSpace->executeQueue.startIndex) {
            return NULL;
        }
        uint32_t currIndex = workSpace->executeQueue.startIndex % workSpace->executeQueue.queueCount;
        trigger = workSpace->executeQueue.executeQueue[currIndex];
        workSpace->executeQueue.executeQueue[currIndex] = NULL;
        workSpace->executeQueue.startIndex++;
    } while (trigger == NULL);
    return trigger;
Z
zhong_ning 已提交
340 341
}

X
xionglei6 已提交
342 343
static int CheckBootCondition_(LogicCalculator *calculator,
    const char *condition, const char *content, uint32_t contentSize)
Z
zhong_ning 已提交
344
{
4
411148299@qq.com 已提交
345
    UNUSED(calculator);
X
xionglei6 已提交
346
    if (strncmp(condition, content, contentSize) == 0) {
Z
zhong_ning 已提交
347 348 349 350 351
        return 1;
    }
    return 0;
}

X
xionglei6 已提交
352 353
static int CheckWatchCondition_(LogicCalculator *calculator,
    const char *condition, const char *content, uint32_t contentSize)
Z
zhong_ning 已提交
354
{
4
411148299@qq.com 已提交
355 356
    UNUSED(calculator);
    UNUSED(contentSize);
X
xionglei6 已提交
357
    if (strncmp(condition, content, strlen(condition)) == 0) {
S
sun_fan 已提交
358 359 360 361 362
        return 1;
    }
    return 0;
}

X
xionglei6 已提交
363 364
static int CheckParamCondition_(LogicCalculator *calculator,
    const char *condition, const char *content, uint32_t contentSize)
S
sun_fan 已提交
365 366 367
{
    UNUSED(content);
    UNUSED(contentSize);
X
xionglei6 已提交
368
    if (calculator->inputName != NULL) {
S
sun_fan 已提交
369
        if (!CheckMatchSubCondition(condition, calculator->inputName, strlen(calculator->inputName))) {
Z
zhong_ning 已提交
370 371 372
            return 0;
        }
    }
S
sun_fan 已提交
373 374 375
    return ComputeCondition(calculator, condition);
}

X
xionglei6 已提交
376 377
static int CheckUnknowCondition_(LogicCalculator *calculator,
    const char *condition, const char *content, uint32_t contentSize)
S
sun_fan 已提交
378
{
379 380 381
    if (condition != NULL && content != NULL && strcmp(content, condition) == 0) {
        return 1;
    }
S
sun_fan 已提交
382 383 384
    return ComputeCondition(calculator, condition);
}

X
xionglei6 已提交
385 386
static int ExecTriggerMatch_(const TriggerWorkSpace *workSpace,
    int type, LogicCalculator *calculator, const char *content, uint32_t contentSize)
S
sun_fan 已提交
387
{
X
xionglei6 已提交
388 389 390 391
    TriggerHeader *head = GetTriggerHeader(workSpace, type);
    PARAM_CHECK(head != NULL, return 0, "Failed to get header %d", type);
    TriggerNode *trigger = head->nextTrigger(head, NULL);
    while (trigger != NULL) {
X
xionglei6 已提交
392
        TriggerNode *next = head->nextTrigger(head, trigger);
X
xionglei6 已提交
393 394 395
        const char *condition = head->getCondition(trigger);
        if (head->checkCondition(calculator, condition, content, contentSize) == 1) {
            calculator->triggerCheckDone(trigger, content, contentSize);
S
sun_fan 已提交
396
        }
X
xionglei6 已提交
397
        trigger = next;
S
sun_fan 已提交
398 399
    }
    return 0;
Z
zhong_ning 已提交
400 401
}

X
xionglei6 已提交
402 403
static int CheckBootMatch_(const TriggerWorkSpace *workSpace,
    int type, LogicCalculator *calculator, const char *content, uint32_t contentSize)
Z
zhong_ning 已提交
404
{
W
Wen liumin 已提交
405 406
    PARAM_CHECK(workSpace != NULL, return -1, "Invalid space");
    PARAM_CHECK((type == TRIGGER_BOOT) || (type == TRIGGER_PARAM_WATCH), return -1, "Invalid type");
X
xionglei6 已提交
407
    return ExecTriggerMatch_(workSpace, type, calculator, content, contentSize);
Z
zhong_ning 已提交
408 409
}

X
xionglei6 已提交
410 411
static int CheckParamMatch_(const TriggerWorkSpace *workSpace,
    int type, LogicCalculator *calculator, const char *content, uint32_t contentSize)
Z
zhong_ning 已提交
412
{
W
Wen liumin 已提交
413 414
    PARAM_CHECK(workSpace != NULL, return -1, "Invalid space");
    PARAM_CHECK((type == TRIGGER_PARAM) || (type == TRIGGER_PARAM_WAIT), return -1, "Invalid type");
X
xionglei6 已提交
415 416

    CalculatorInit(calculator, MAX_CONDITION_NUMBER, sizeof(LogicData), 1);
X
xionglei6 已提交
417
    int ret = GetValueFromContent(content, contentSize, 0, calculator->inputName, SUPPORT_DATA_BUFFER_MAX);
X
xionglei6 已提交
418 419 420 421 422
    PARAM_CHECK(ret == 0, return -1, "Failed parse content name");
    ret = GetValueFromContent(content, contentSize,
        strlen(calculator->inputName) + 1, calculator->inputContent, SUPPORT_DATA_BUFFER_MAX);
    PARAM_CHECK(ret == 0, return -1, "Failed parse content value");
    return ExecTriggerMatch_(workSpace, type, calculator, content, contentSize);
Z
zhong_ning 已提交
423 424
}

X
xionglei6 已提交
425 426
static int CheckUnknowMatch_(const TriggerWorkSpace *workSpace,
    int type, LogicCalculator *calculator, const char *content, uint32_t contentSize)
Z
zhong_ning 已提交
427
{
X
xionglei6 已提交
428
    PARAM_CHECK(workSpace != NULL && content != NULL, return -1, "Failed arg for trigger");
W
Wen liumin 已提交
429
    PARAM_CHECK(type == TRIGGER_UNKNOW, return -1, "Invalid type");
X
xionglei6 已提交
430 431 432 433 434 435 436

    CalculatorInit(calculator, MAX_CONDITION_NUMBER, sizeof(LogicData), 1);
    int ret = memcpy_s(calculator->triggerContent, sizeof(calculator->triggerContent), content, contentSize);
    PARAM_CHECK(ret == EOK, return -1, "Failed to memcpy");
    calculator->inputName = NULL;
    calculator->inputContent = NULL;
    return ExecTriggerMatch_(workSpace, type, calculator, content, contentSize);
Z
zhong_ning 已提交
437 438
}

X
xionglei6 已提交
439
int32_t CheckAndMarkTrigger_(const TriggerWorkSpace *workSpace, int type, const char *name)
Z
zhong_ning 已提交
440
{
X
xionglei6 已提交
441 442 443
    PARAM_CHECK(workSpace != NULL && name != NULL, return 0, "Failed arg for trigger");
    TriggerHeader *head = GetTriggerHeader(workSpace, type);
    PARAM_CHECK(head != NULL, return 0, "Failed to get header %d", type);
S
sun_fan 已提交
444
    int ret = 0;
X
xionglei6 已提交
445
    TriggerNode *trigger = head->nextTrigger(head, NULL);
S
sun_fan 已提交
446
    while (trigger != NULL) {
X
xionglei6 已提交
447 448
        if (head->getCondition(trigger) == NULL) {
            trigger = head->nextTrigger(head, trigger);
4
411148299@qq.com 已提交
449 450
            continue;
        }
C
cheng_jinsong 已提交
451
        if (CheckMatchSubCondition(head->getCondition(trigger), name, strlen(name)) == 1) {
S
sun_fan 已提交
452 453 454
            TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_RELATED);
            ret = 1;
        }
X
xionglei6 已提交
455
        trigger = head->nextTrigger(head, trigger);
S
sun_fan 已提交
456 457 458
    }
    return ret;
}
Z
zhong_ning 已提交
459

X
xionglei6 已提交
460 461
int CheckTrigger(TriggerWorkSpace *workSpace, int type,
    const char *content, uint32_t contentSize, PARAM_CHECK_DONE triggerCheckDone)
S
sun_fan 已提交
462
{
X
xionglei6 已提交
463 464 465 466 467
    PARAM_CHECK(workSpace != NULL && content != NULL && triggerCheckDone != NULL,
        return -1, "Failed arg for trigger");
    PARAM_LOGV("CheckTrigger_ type: %d content: %s ", type, content);
    TriggerHeader *triggerHead = GetTriggerHeader(workSpace, type);
    if (triggerHead != NULL) {
Y
yichengzhao 已提交
468
        LogicCalculator calculator = {{0}};
X
xionglei6 已提交
469 470 471 472
        calculator.triggerCheckDone = triggerCheckDone;
        int ret = triggerHead->checkTriggerMatch(workSpace, type, &calculator, content, contentSize);
        CalculatorFree(&calculator);
        return ret;
S
sun_fan 已提交
473
    }
X
xionglei6 已提交
474 475 476 477 478 479
    return 0;
}

static void DumpJobTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode *trigger)
{
    const JobNode *node = (const JobNode *)trigger;
C
cheng_jinsong 已提交
480 481 482
    PARAM_DUMP("trigger     flags: 0x%08x \n", trigger->flags);
    PARAM_DUMP("trigger      name: %s \n", node->name);
    PARAM_DUMP("trigger condition: %s \n", node->condition);
X
xionglei6 已提交
483 484 485 486
    const int maxCmd = 1024;
    int count = 0;
    CommandNode *cmd = GetNextCmdNode(node, NULL);
    while (cmd != NULL && count < maxCmd) {
C
cheng_jinsong 已提交
487 488
        PARAM_DUMP("    command name: %s \n", GetCmdKey(cmd->cmdKeyIndex));
        PARAM_DUMP("    command args: %s \n", cmd->content);
X
xionglei6 已提交
489 490
        cmd = GetNextCmdNode(node, cmd);
        count++;
S
sun_fan 已提交
491
    }
Z
zhong_ning 已提交
492 493
}

X
xionglei6 已提交
494
static void DumpWatchTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode *trigger)
Z
zhong_ning 已提交
495
{
X
xionglei6 已提交
496
    const WatchNode *node = (const WatchNode *)trigger;
C
cheng_jinsong 已提交
497 498 499
    PARAM_DUMP("trigger     flags: 0x%08x \n", trigger->flags);
    PARAM_DUMP("trigger condition: %s \n", trigger->condition);
    PARAM_DUMP("trigger   watchId: %d \n", node->watchId);
X
xionglei6 已提交
500
}
S
sun_fan 已提交
501

X
xionglei6 已提交
502 503 504
static void DumpWaitTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode *trigger)
{
    const WaitNode *node = (const WaitNode *)trigger;
C
cheng_jinsong 已提交
505 506 507 508 509
    PARAM_DUMP("trigger     flags: 0x%08x \n", trigger->flags);
    PARAM_DUMP("trigger      name: %s \n", GetTriggerName(trigger));
    PARAM_DUMP("trigger condition: %s \n", trigger->condition);
    PARAM_DUMP("trigger    waitId: %d \n", node->waitId);
    PARAM_DUMP("trigger   timeout: %d \n", node->timeout);
S
sun_fan 已提交
510
}
Z
zhong_ning 已提交
511

X
xionglei6 已提交
512
static void DumpTrigger_(const TriggerWorkSpace *workSpace, int type)
S
sun_fan 已提交
513
{
X
xionglei6 已提交
514 515 516 517
    PARAM_CHECK(workSpace != NULL, return, "Invalid workSpace ");
    TriggerHeader *head = GetTriggerHeader(workSpace, type);
    PARAM_CHECK(head != NULL, return, "Failed to get header %d", type);
    TriggerNode *trigger = head->nextTrigger(head, NULL);
S
sun_fan 已提交
518
    while (trigger != NULL) {
X
xionglei6 已提交
519 520 521 522 523
        head->dumpTrigger(workSpace, trigger);
        trigger = head->nextTrigger(head, trigger);
    }
}

C
cheng_jinsong 已提交
524
void SystemDumpTriggers(int verbose, int (*dump)(const char *fmt, ...))
X
xionglei6 已提交
525
{
C
cheng_jinsong 已提交
526 527 528 529 530
    if (dump != NULL) {
        g_printf = dump;
    } else {
        g_printf = printf;
    }
M
Mupceet 已提交
531
    TriggerWorkSpace *workSpace = GetTriggerWorkSpace();
X
xionglei6 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
    PARAM_CHECK(workSpace != NULL, return, "Invalid workSpace ");
    PARAM_DUMP("workspace queue BOOT info:\n");
    DumpTrigger_(workSpace, TRIGGER_BOOT);
    PARAM_DUMP("workspace queue parameter info:\n");
    DumpTrigger_(workSpace, TRIGGER_PARAM);
    PARAM_DUMP("workspace queue other info:\n");
    DumpTrigger_(workSpace, TRIGGER_UNKNOW);
    PARAM_DUMP("workspace queue watch info:\n");
    DumpTrigger_(workSpace, TRIGGER_PARAM_WATCH);
    PARAM_DUMP("workspace queue wait info:\n");
    DumpTrigger_(workSpace, TRIGGER_PARAM_WAIT);

    PARAM_DUMP("workspace queue execute info:\n");
    PARAM_DUMP("queue info count: %u start: %u end: %u\n",
        workSpace->executeQueue.queueCount, workSpace->executeQueue.startIndex, workSpace->executeQueue.endIndex);
    for (uint32_t index = workSpace->executeQueue.startIndex; index < workSpace->executeQueue.endIndex; index++) {
        TriggerNode *trigger = workSpace->executeQueue.executeQueue[index % workSpace->executeQueue.queueCount];
        if (trigger != 0) {
C
cheng_jinsong 已提交
550
            PARAM_DUMP("    queue node trigger name: %s \n", GetTriggerName(trigger));
S
sun_fan 已提交
551 552 553
        }
    }
}
Z
zhong_ning 已提交
554

X
xionglei6 已提交
555
static int32_t CompareData_(const struct tagTriggerNode_ *trigger, const void *data)
S
sun_fan 已提交
556
{
X
xionglei6 已提交
557 558 559
    PARAM_CHECK(trigger != NULL && data != NULL, return -1, "Invalid trigger");
    if (trigger->type == TRIGGER_PARAM_WAIT) {
        WaitNode *node = (WaitNode *)trigger;
C
cheng_jinsong 已提交
560
        return node->waitId - *(uint32_t *)data;
X
xionglei6 已提交
561 562
    } else if (trigger->type == TRIGGER_PARAM_WATCH) {
        WatchNode *node = (WatchNode *)trigger;
C
cheng_jinsong 已提交
563
        return node->watchId - *(uint32_t *)data;
S
sun_fan 已提交
564
    }
X
xionglei6 已提交
565
    return -1;
Z
zhong_ning 已提交
566 567
}

X
xionglei6 已提交
568
static void TriggerHeadSetDefault(TriggerHeader *head)
Z
zhong_ning 已提交
569
{
570
    OH_ListInit(&head->triggerList);
X
xionglei6 已提交
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
    head->triggerCount = 0;
    head->cmdNodeCount = 0;
    head->addTrigger = AddJobTrigger_;
    head->nextTrigger = GetNextTrigger_;
    head->delTrigger = DelJobTrigger_;
    head->executeTrigger = NULL;
    head->checkAndMarkTrigger = CheckAndMarkTrigger_;
    head->checkTriggerMatch = CheckBootMatch_;
    head->checkCondition = CheckBootCondition_;
    head->getCondition = GetBootCondition_;
    head->getTriggerName = GetJobName_;
    head->dumpTrigger = DumpJobTrigger_;
    head->compareData = CompareData_;
}

static int JobNodeNodeCompare(const HashNode *node1, const HashNode *node2)
{
    JobNode *jobNode1 = HASHMAP_ENTRY(node1, JobNode, hashNode);
    JobNode *jobNode2 = HASHMAP_ENTRY(node2, JobNode, hashNode);
    return strcmp(jobNode1->name, jobNode2->name);
}

static int JobNodeKeyCompare(const HashNode *node1, const void *key)
{
    JobNode *jobNode1 = HASHMAP_ENTRY(node1, JobNode, hashNode);
    return strcmp(jobNode1->name, (char *)key);
}

static int JobNodeGetNodeHasCode(const HashNode *node)
{
    JobNode *jobNode = HASHMAP_ENTRY(node, JobNode, hashNode);
    int code = 0;
X
xionglei6 已提交
603 604
    size_t nameLen = strlen(jobNode->name);
    for (size_t i = 0; i < nameLen; i++) {
X
xionglei6 已提交
605 606 607 608 609 610 611 612 613
        code += jobNode->name[i] - 'A';
    }
    return code;
}

static int JobNodeGetKeyHasCode(const void *key)
{
    int code = 0;
    const char *buff = (char *)key;
X
xionglei6 已提交
614 615
    size_t buffLen = strlen(buff);
    for (size_t i = 0; i < buffLen; i++) {
X
xionglei6 已提交
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
        code += buff[i] - 'A';
    }
    return code;
}

static void JobNodeFree(const HashNode *node)
{
    JobNode *jobNode = HASHMAP_ENTRY(node, JobNode, hashNode);
    FreeTrigger(GetTriggerWorkSpace(), (TriggerNode *)jobNode);
}

void InitTriggerHead(const TriggerWorkSpace *workSpace)
{
    HashInfo info = {
        JobNodeNodeCompare,
        JobNodeKeyCompare,
        JobNodeGetNodeHasCode,
        JobNodeGetKeyHasCode,
        JobNodeFree,
        64
    };
    PARAM_CHECK(workSpace != NULL, return, "Invalid workSpace");
638
    int ret = OH_HashMapCreate((HashMapHandle *)&workSpace->hashMap, &info);
X
xionglei6 已提交
639 640 641 642 643 644 645 646 647 648
    PARAM_CHECK(ret == 0, return, "Failed to create hash map");

    TriggerHeader *head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_BOOT];
    TriggerHeadSetDefault(head);
    // param trigger
    head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_PARAM];
    TriggerHeadSetDefault(head);
    head->checkTriggerMatch = CheckParamMatch_;
    head->checkCondition = CheckParamCondition_;
    head->getCondition = GetTriggerCondition_;
S
shiyuju 已提交
649
    // unknown trigger
X
xionglei6 已提交
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
    head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_UNKNOW];
    TriggerHeadSetDefault(head);
    head->checkTriggerMatch = CheckUnknowMatch_;
    head->checkCondition = CheckUnknowCondition_;
    head->getCondition = GetTriggerCondition_;
    // wait trigger
    head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_PARAM_WAIT];
    TriggerHeadSetDefault(head);
    head->addTrigger = AddWatchTrigger_;
    head->delTrigger = DelWatchTrigger_;
    head->checkTriggerMatch = CheckParamMatch_;
    head->checkCondition = CheckParamCondition_;
    head->getCondition = GetTriggerCondition_;
    head->dumpTrigger = DumpWaitTrigger_;
    head->getTriggerName = GetWatchName_;
    // watch trigger
    head = (TriggerHeader *)&workSpace->triggerHead[TRIGGER_PARAM_WATCH];
    TriggerHeadSetDefault(head);
    head->addTrigger = AddWatchTrigger_;
    head->delTrigger = DelWatchTrigger_;
    head->checkTriggerMatch = CheckBootMatch_;
    head->checkCondition = CheckWatchCondition_;
    head->getCondition = GetTriggerCondition_;
    head->dumpTrigger = DumpWatchTrigger_;
    head->getTriggerName = GetWatchName_;
}

void DelWatchTrigger(int type, const void *data)
{
    PARAM_CHECK(data != NULL, return, "Invalid data");
    TriggerHeader *head = GetTriggerHeader(GetTriggerWorkSpace(), type);
    PARAM_CHECK(head != NULL, return, "Failed to get header %d", type);
    PARAM_CHECK(head->compareData != NULL, return, "Invalid compareData");
    TriggerNode *trigger = head->nextTrigger(head, NULL);
S
sun_fan 已提交
684
    while (trigger != NULL) {
X
xionglei6 已提交
685 686 687
        if (head->compareData(trigger, data) == 0) {
            head->delTrigger(GetTriggerWorkSpace(), trigger);
            return;
4
411148299@qq.com 已提交
688
        }
X
xionglei6 已提交
689 690 691
        trigger = head->nextTrigger(head, trigger);
    }
}
S
sun_fan 已提交
692

X
xionglei6 已提交
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
void ClearWatchTrigger(ParamWatcher *watcher, int type)
{
    PARAM_CHECK(watcher != NULL, return, "Invalid watcher");
    TriggerHeader *head = GetTriggerHeader(GetTriggerWorkSpace(), type);
    PARAM_CHECK(head != NULL, return, "Failed to get header %d", type);
    ListNode *node = watcher->triggerHead.next;
    while (node != &watcher->triggerHead) {
        TriggerNode *trigger = NULL;
        if (type == TRIGGER_PARAM_WAIT) {
            trigger = (TriggerNode *)ListEntry(node, WaitNode, item);
        } else if (type == TRIGGER_PARAM_WATCH) {
            trigger = (TriggerNode *)ListEntry(node, WatchNode, item);
        }
        if (trigger == NULL || type != trigger->type) {
            PARAM_LOGE("ClearWatchTrigger %s error type %d", GetTriggerName(trigger), type);
            return;
S
sun_fan 已提交
709
        }
X
xionglei6 已提交
710 711 712 713
        PARAM_LOGV("ClearWatchTrigger %p %s", trigger, GetTriggerName(trigger));
        ListNode *next = node->next;
        FreeTrigger(GetTriggerWorkSpace(), trigger);
        node = next;
S
sun_fan 已提交
714 715 716
    }
}

X
xionglei6 已提交
717
int CheckWatchTriggerTimeout(void)
S
sun_fan 已提交
718
{
X
xionglei6 已提交
719 720 721 722 723 724 725 726 727 728 729
    TriggerHeader *head = GetTriggerHeader(GetTriggerWorkSpace(), TRIGGER_PARAM_WAIT);
    PARAM_CHECK(head != NULL && head->nextTrigger != NULL, return 0, "Invalid header");
    int hasNode = 0;
    WaitNode *node = (WaitNode *)head->nextTrigger(head, NULL);
    while (node != NULL) {
        WaitNode *next = (WaitNode *)head->nextTrigger(head, (TriggerNode *)node);
        if (node->timeout > 0) {
            node->timeout--;
        } else {
            head->executeTrigger((TriggerNode*)node, NULL, 0);
            FreeTrigger(GetTriggerWorkSpace(), (TriggerNode *)node);
Z
zhong_ning 已提交
730
        }
X
xionglei6 已提交
731 732 733 734 735 736 737 738
        hasNode = 1;
        node = next;
    }
    return hasNode;
}

TriggerHeader *GetTriggerHeader(const TriggerWorkSpace *workSpace, int type)
{
X
xionglei6 已提交
739
    if (workSpace == NULL || type >= TRIGGER_MAX) {
X
xionglei6 已提交
740 741 742 743 744 745 746 747 748 749 750 751 752
        return NULL;
    }
    return (TriggerHeader *)&workSpace->triggerHead[type];
}

char *GetTriggerCache(uint32_t *size)
{
    TriggerWorkSpace *space = GetTriggerWorkSpace();
    if (space == NULL) {
        return NULL;
    }
    if (size != NULL) {
        *size = sizeof(space->cache) / sizeof(space->cache[0]);
Z
zhong_ning 已提交
753
    }
X
xionglei6 已提交
754
    return space->cache;
755
}
X
xionglei6 已提交
756 757 758 759 760 761 762 763 764

const char *GetTriggerName(const TriggerNode *trigger)
{
    PARAM_CHECK(trigger != NULL, return "", "Invalid trigger");
    TriggerHeader *triggerHead = GetTriggerHeader(GetTriggerWorkSpace(), trigger->type);
    if (triggerHead) {
        return triggerHead->getTriggerName(trigger);
    }
    return "";
W
Wen liumin 已提交
765
}