12ee81decSopenharmony_ci/*
22ee81decSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
32ee81decSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42ee81decSopenharmony_ci * you may not use this file except in compliance with the License.
52ee81decSopenharmony_ci * You may obtain a copy of the License at
62ee81decSopenharmony_ci *
72ee81decSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
82ee81decSopenharmony_ci *
92ee81decSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102ee81decSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112ee81decSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122ee81decSopenharmony_ci * See the License for the specific language governing permissions and
132ee81decSopenharmony_ci * limitations under the License.
142ee81decSopenharmony_ci */
152ee81decSopenharmony_ci
162ee81decSopenharmony_ci#include "dslm_fsm_process.h"
172ee81decSopenharmony_ci
182ee81decSopenharmony_ci#include <securec.h>
192ee81decSopenharmony_ci#include <stdbool.h>
202ee81decSopenharmony_ci#include <stddef.h>
212ee81decSopenharmony_ci
222ee81decSopenharmony_ci#include "device_security_defines.h"
232ee81decSopenharmony_ci#include "utils_datetime.h"
242ee81decSopenharmony_ci#include "utils_dslm_list.h"
252ee81decSopenharmony_ci#include "utils_hexstring.h"
262ee81decSopenharmony_ci#include "utils_log.h"
272ee81decSopenharmony_ci#include "utils_mem.h"
282ee81decSopenharmony_ci#include "utils_mutex.h"
292ee81decSopenharmony_ci#include "utils_state_machine.h"
302ee81decSopenharmony_ci#include "utils_timer.h"
312ee81decSopenharmony_ci
322ee81decSopenharmony_ci#include "dslm_callback_info.h"
332ee81decSopenharmony_ci#include "dslm_core_defines.h"
342ee81decSopenharmony_ci#include "dslm_cred.h"
352ee81decSopenharmony_ci#include "dslm_device_list.h"
362ee81decSopenharmony_ci#include "dslm_hitrace.h"
372ee81decSopenharmony_ci#include "dslm_inner_process.h"
382ee81decSopenharmony_ci#include "dslm_msg_serialize.h"
392ee81decSopenharmony_ci#include "dslm_notify_node.h"
402ee81decSopenharmony_ci
412ee81decSopenharmony_ci#define REQUEST_INTERVAL (24 * 60 * 60 * 1000)
422ee81decSopenharmony_ci#define DEFAULT_TYPE 10
432ee81decSopenharmony_ci#define TYPE_PLACE 8
442ee81decSopenharmony_ci
452ee81decSopenharmony_citypedef bool DslmInfoChecker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo,
462ee81decSopenharmony_ci    uint32_t *result);
472ee81decSopenharmony_ci
482ee81decSopenharmony_cistatic bool SdkTimeoutChecker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo,
492ee81decSopenharmony_ci    uint32_t *result);
502ee81decSopenharmony_cistatic bool RequestDoneChecker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo,
512ee81decSopenharmony_ci    uint32_t *result);
522ee81decSopenharmony_ci
532ee81decSopenharmony_cistatic uint32_t GenerateMachineId(const DeviceIdentify *identity);
542ee81decSopenharmony_cistatic bool CheckTimesAndSendCredRequest(DslmDeviceInfo *info, bool enforce);
552ee81decSopenharmony_cistatic void StopSendDeviceInfoRequestTimer(DslmDeviceInfo *info);
562ee81decSopenharmony_cistatic void ProcessSendDeviceInfoCallback(DslmDeviceInfo *info, DslmInfoChecker checker);
572ee81decSopenharmony_ci
582ee81decSopenharmony_cistatic void TimerProcessSendDeviceInfoRequestTimeOut(const void *context);
592ee81decSopenharmony_cistatic void TimerProcessSdkRequestTimeout(const void *context);
602ee81decSopenharmony_ci
612ee81decSopenharmony_cistatic bool ProcessDeviceOnline(const StateMachine *machine, uint32_t event, const void *para);
622ee81decSopenharmony_cistatic bool ProcessSendCredRequest(const StateMachine *machine, uint32_t event, const void *para);
632ee81decSopenharmony_cistatic bool ProcessSdkRequest(const StateMachine *machine, uint32_t event, const void *para);
642ee81decSopenharmony_cistatic bool ProcessSendRequestFailed(const StateMachine *machine, uint32_t event, const void *para);
652ee81decSopenharmony_cistatic bool ProcessDeviceOffline(const StateMachine *machine, uint32_t event, const void *para);
662ee81decSopenharmony_cistatic bool ProcessVerifyCredMessage(const StateMachine *machine, uint32_t event, const void *para);
672ee81decSopenharmony_cistatic bool ProcessSdkTimeout(const StateMachine *machine, uint32_t event, const void *para);
682ee81decSopenharmony_ci
692ee81decSopenharmony_cistatic void RefreshNotifyList(DslmDeviceInfo *info);
702ee81decSopenharmony_cistatic void RefreshHistoryList(DslmDeviceInfo *info);
712ee81decSopenharmony_ci
722ee81decSopenharmony_cistatic uint32_t GenerateMachineId(const DeviceIdentify *identity)
732ee81decSopenharmony_ci{
742ee81decSopenharmony_ci#define MASK_LOW 0x00ffU
752ee81decSopenharmony_ci#define MACHINE_ID_LENGTH 4U
762ee81decSopenharmony_ci#define SHIFT_LENGTH 8U
772ee81decSopenharmony_ci#define MASK_HIGH 0xff00U
782ee81decSopenharmony_ci    uint16_t machineId = 0;
792ee81decSopenharmony_ci    DslmHexStringToByte((const char *)identity->identity, MACHINE_ID_LENGTH, (uint8_t *)&machineId, sizeof(machineId));
802ee81decSopenharmony_ci    return ((machineId & MASK_HIGH) >> SHIFT_LENGTH) | ((machineId & MASK_LOW) << SHIFT_LENGTH);
812ee81decSopenharmony_ci}
822ee81decSopenharmony_ci
832ee81decSopenharmony_cistatic void TimerProcessSendDeviceInfoRequestTimeOut(const void *context)
842ee81decSopenharmony_ci{
852ee81decSopenharmony_ci    if (context == NULL) {
862ee81decSopenharmony_ci        return;
872ee81decSopenharmony_ci    }
882ee81decSopenharmony_ci    // the context info will never be freed, so feel free use it.
892ee81decSopenharmony_ci    ScheduleDslmStateMachine((DslmDeviceInfo *)context, EVENT_TIME_OUT, NULL);
902ee81decSopenharmony_ci}
912ee81decSopenharmony_ci
922ee81decSopenharmony_cistatic void TimerProcessSdkRequestTimeout(const void *context)
932ee81decSopenharmony_ci{
942ee81decSopenharmony_ci    if (context == NULL) {
952ee81decSopenharmony_ci        return;
962ee81decSopenharmony_ci    }
972ee81decSopenharmony_ci    // the context info will never be freed, so feel free use it.
982ee81decSopenharmony_ci    ScheduleDslmStateMachine((DslmDeviceInfo *)context, EVENT_SDK_TIMEOUT, NULL);
992ee81decSopenharmony_ci}
1002ee81decSopenharmony_ci
1012ee81decSopenharmony_cistatic void StopSendDeviceInfoRequestTimer(DslmDeviceInfo *info)
1022ee81decSopenharmony_ci{
1032ee81decSopenharmony_ci    if (info->timeHandle != 0) {
1042ee81decSopenharmony_ci        DslmUtilsStopTimerTask(info->timeHandle);
1052ee81decSopenharmony_ci        info->timeHandle = 0;
1062ee81decSopenharmony_ci    }
1072ee81decSopenharmony_ci}
1082ee81decSopenharmony_ci
1092ee81decSopenharmony_cistatic void StartSendDeviceInfoRequestTimer(DslmDeviceInfo *info)
1102ee81decSopenharmony_ci{
1112ee81decSopenharmony_ci    info->timeHandle =
1122ee81decSopenharmony_ci        DslmUtilsStartOnceTimerTask(SEND_MSG_TIMEOUT_LEN, TimerProcessSendDeviceInfoRequestTimeOut, info);
1132ee81decSopenharmony_ci}
1142ee81decSopenharmony_ci
1152ee81decSopenharmony_cistatic bool CheckTimesAndSendCredRequest(DslmDeviceInfo *info, bool enforce)
1162ee81decSopenharmony_ci{
1172ee81decSopenharmony_ci#ifndef MAX_SEND_TIMES
1182ee81decSopenharmony_ci#define MAX_SEND_TIMES 5
1192ee81decSopenharmony_ci#endif
1202ee81decSopenharmony_ci
1212ee81decSopenharmony_ci#ifndef SEND_MSG_TIMEOUT_LEN
1222ee81decSopenharmony_ci#define SEND_MSG_TIMEOUT_LEN 40000
1232ee81decSopenharmony_ci#endif
1242ee81decSopenharmony_ci
1252ee81decSopenharmony_ci    if (!enforce && info->queryTimes > MAX_SEND_TIMES) {
1262ee81decSopenharmony_ci        return false;
1272ee81decSopenharmony_ci    }
1282ee81decSopenharmony_ci    DslmStartProcessTraceAsync("SendCredRequest", info->machine.machineId, info->queryTimes + 1);
1292ee81decSopenharmony_ci    CheckAndGenerateChallenge(info);
1302ee81decSopenharmony_ci    SendDeviceInfoRequest(info);
1312ee81decSopenharmony_ci    info->queryTimes++;
1322ee81decSopenharmony_ci    info->lastRequestTime = GetMillisecondSinceBoot();
1332ee81decSopenharmony_ci
1342ee81decSopenharmony_ci    StopSendDeviceInfoRequestTimer(info);
1352ee81decSopenharmony_ci    StartSendDeviceInfoRequestTimer(info);
1362ee81decSopenharmony_ci    return true;
1372ee81decSopenharmony_ci}
1382ee81decSopenharmony_ci
1392ee81decSopenharmony_cistatic void ProcessSendDeviceInfoCallback(DslmDeviceInfo *info, DslmInfoChecker checker)
1402ee81decSopenharmony_ci{
1412ee81decSopenharmony_ci#ifndef MAX_HISTORY_CNT
1422ee81decSopenharmony_ci#define MAX_HISTORY_CNT 30U
1432ee81decSopenharmony_ci#endif
1442ee81decSopenharmony_ci
1452ee81decSopenharmony_ci    if (info == NULL || checker == NULL) {
1462ee81decSopenharmony_ci        return;
1472ee81decSopenharmony_ci    }
1482ee81decSopenharmony_ci    ListNode *node = NULL;
1492ee81decSopenharmony_ci    ListNode *temp = NULL;
1502ee81decSopenharmony_ci    SECURITY_LOG_DEBUG("ProcessSendDeviceInfoCallback for device %{public}x.", info->machine.machineId);
1512ee81decSopenharmony_ci    FOREACH_LIST_NODE_SAFE (node, &info->notifyList, temp) {
1522ee81decSopenharmony_ci        DslmNotifyListNode *notifyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode);
1532ee81decSopenharmony_ci        uint32_t result;
1542ee81decSopenharmony_ci        DslmCallbackInfo cbInfo;
1552ee81decSopenharmony_ci        bool check = checker(info, notifyNode, &cbInfo, &result);
1562ee81decSopenharmony_ci        if (!check) {
1572ee81decSopenharmony_ci            continue;
1582ee81decSopenharmony_ci        }
1592ee81decSopenharmony_ci        SECURITY_LOG_DEBUG("ProcessSendDeviceInfoCallback result %{public}u for device %{public}x, level %{public}u.",
1602ee81decSopenharmony_ci            result, info->machine.machineId, cbInfo.level);
1612ee81decSopenharmony_ci
1622ee81decSopenharmony_ci        notifyNode->requestCallback(notifyNode->owner, notifyNode->cookie, result, &cbInfo);
1632ee81decSopenharmony_ci        notifyNode->stop = GetMillisecondSinceBoot();
1642ee81decSopenharmony_ci        notifyNode->result = result;
1652ee81decSopenharmony_ci
1662ee81decSopenharmony_ci        RemoveListNode(node);
1672ee81decSopenharmony_ci        DslmFinishProcessTraceAsync("SDK_GET", notifyNode->owner, notifyNode->cookie);
1682ee81decSopenharmony_ci
1692ee81decSopenharmony_ci        AddListNodeBefore(node, &info->historyList);
1702ee81decSopenharmony_ci    }
1712ee81decSopenharmony_ci
1722ee81decSopenharmony_ci    RefreshNotifyList(info);
1732ee81decSopenharmony_ci    RefreshHistoryList(info);
1742ee81decSopenharmony_ci}
1752ee81decSopenharmony_ci
1762ee81decSopenharmony_cistatic bool CheckNeedToResend(const DslmDeviceInfo *info)
1772ee81decSopenharmony_ci{
1782ee81decSopenharmony_ci    if (info->credInfo.credLevel > 0) {
1792ee81decSopenharmony_ci        return false;
1802ee81decSopenharmony_ci    }
1812ee81decSopenharmony_ci    if (info->credInfo.credLevel == 0) {
1822ee81decSopenharmony_ci        return true;
1832ee81decSopenharmony_ci    }
1842ee81decSopenharmony_ci    if (info->lastOnlineTime < info->lastRequestTime) {
1852ee81decSopenharmony_ci        return true;
1862ee81decSopenharmony_ci    }
1872ee81decSopenharmony_ci    if (info->lastOnlineTime - info->lastRequestTime > (uint64_t)REQUEST_INTERVAL) {
1882ee81decSopenharmony_ci        return true;
1892ee81decSopenharmony_ci    }
1902ee81decSopenharmony_ci    return false;
1912ee81decSopenharmony_ci}
1922ee81decSopenharmony_ci
1932ee81decSopenharmony_cistatic bool ProcessDeviceOnline(const StateMachine *machine, uint32_t event, const void *para)
1942ee81decSopenharmony_ci{
1952ee81decSopenharmony_ci    DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
1962ee81decSopenharmony_ci    uint32_t deviceAttributes = 0;
1972ee81decSopenharmony_ci    if (para != NULL) {
1982ee81decSopenharmony_ci        deviceAttributes = *(uint32_t *)para;
1992ee81decSopenharmony_ci    }
2002ee81decSopenharmony_ci    uint32_t level = deviceAttributes & 0xFF;
2012ee81decSopenharmony_ci    uint32_t osType = (deviceAttributes & 0xFF00) >> TYPE_PLACE;
2022ee81decSopenharmony_ci    info->osType = osType;
2032ee81decSopenharmony_ci    if (level == 0 && osType == DEFAULT_TYPE) {
2042ee81decSopenharmony_ci        level = 1;
2052ee81decSopenharmony_ci        SECURITY_LOG_INFO("level set 1");
2062ee81decSopenharmony_ci    }
2072ee81decSopenharmony_ci    if (level > 0) {
2082ee81decSopenharmony_ci        info->credInfo.credLevel = level;
2092ee81decSopenharmony_ci        info->result = SUCCESS;
2102ee81decSopenharmony_ci    }
2112ee81decSopenharmony_ci    info->onlineStatus = ONLINE_STATUS_ONLINE;
2122ee81decSopenharmony_ci    info->queryTimes = 0;
2132ee81decSopenharmony_ci    info->lastOnlineTime = GetMillisecondSinceBoot();
2142ee81decSopenharmony_ci    if (!CheckNeedToResend(info)) {
2152ee81decSopenharmony_ci        SECURITY_LOG_INFO("last request time is last than 24 hours");
2162ee81decSopenharmony_ci        ScheduleDslmStateMachine(info, EVENT_TO_SYNC, NULL);
2172ee81decSopenharmony_ci        return true;
2182ee81decSopenharmony_ci    }
2192ee81decSopenharmony_ci    return ProcessSendCredRequest(machine, event, para);
2202ee81decSopenharmony_ci}
2212ee81decSopenharmony_ci
2222ee81decSopenharmony_cistatic bool ProcessSendCredRequest(const StateMachine *machine, uint32_t event, const void *para)
2232ee81decSopenharmony_ci{
2242ee81decSopenharmony_ci    DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
2252ee81decSopenharmony_ci    bool enforce = (para != NULL);
2262ee81decSopenharmony_ci    return CheckTimesAndSendCredRequest(info, enforce);
2272ee81decSopenharmony_ci}
2282ee81decSopenharmony_ci
2292ee81decSopenharmony_cistatic bool ProcessSdkRequest(const StateMachine *machine, uint32_t event, const void *para)
2302ee81decSopenharmony_ci{
2312ee81decSopenharmony_ci    DslmDeviceInfo *deviceInfo = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
2322ee81decSopenharmony_ci    DslmNotifyListNode *inputNotify = (DslmNotifyListNode *)para;
2332ee81decSopenharmony_ci    if (inputNotify == NULL) {
2342ee81decSopenharmony_ci        return false;
2352ee81decSopenharmony_ci    }
2362ee81decSopenharmony_ci
2372ee81decSopenharmony_ci    DslmNotifyListNode *notify = MALLOC(sizeof(DslmNotifyListNode));
2382ee81decSopenharmony_ci    if (notify == NULL) {
2392ee81decSopenharmony_ci        SECURITY_LOG_ERROR("malloc failed, notifyNode is null");
2402ee81decSopenharmony_ci        return false;
2412ee81decSopenharmony_ci    }
2422ee81decSopenharmony_ci    (void)memset_s(notify, sizeof(DslmNotifyListNode), 0, sizeof(DslmNotifyListNode));
2432ee81decSopenharmony_ci    notify->owner = inputNotify->owner;
2442ee81decSopenharmony_ci    notify->cookie = inputNotify->cookie;
2452ee81decSopenharmony_ci    notify->requestCallback = inputNotify->requestCallback;
2462ee81decSopenharmony_ci    notify->start = inputNotify->start;
2472ee81decSopenharmony_ci    notify->keep = inputNotify->keep;
2482ee81decSopenharmony_ci    if (notify->cookie == 0 || notify->requestCallback == NULL) {
2492ee81decSopenharmony_ci        SECURITY_LOG_ERROR("ProcessSdkRequest invalid cookie or callback.");
2502ee81decSopenharmony_ci        FREE(notify);
2512ee81decSopenharmony_ci        notify = NULL;
2522ee81decSopenharmony_ci        return false;
2532ee81decSopenharmony_ci    }
2542ee81decSopenharmony_ci
2552ee81decSopenharmony_ci    DslmStartProcessTraceAsync("SDK_GET", notify->owner, notify->cookie);
2562ee81decSopenharmony_ci    AddListNode(&notify->linkNode, &deviceInfo->notifyList);
2572ee81decSopenharmony_ci    RefreshNotifyList(deviceInfo);
2582ee81decSopenharmony_ci    SECURITY_LOG_DEBUG(
2592ee81decSopenharmony_ci        "ProcessSdkRequest, device is %{public}x, owner is %{public}u, cookie is %{public}u, keep is %{public}u",
2602ee81decSopenharmony_ci        deviceInfo->machine.machineId, notify->owner, notify->cookie, notify->keep);
2612ee81decSopenharmony_ci    uint32_t state = GetCurrentMachineState(deviceInfo);
2622ee81decSopenharmony_ci    if (state == STATE_SUCCESS || state == STATE_FAILED || deviceInfo->credInfo.credLevel != 0) {
2632ee81decSopenharmony_ci        ProcessSendDeviceInfoCallback(deviceInfo, RequestDoneChecker);
2642ee81decSopenharmony_ci        return true;
2652ee81decSopenharmony_ci    }
2662ee81decSopenharmony_ci
2672ee81decSopenharmony_ci    DslmUtilsStartOnceTimerTask(notify->keep, TimerProcessSdkRequestTimeout, deviceInfo);
2682ee81decSopenharmony_ci    return true;
2692ee81decSopenharmony_ci}
2702ee81decSopenharmony_ci
2712ee81decSopenharmony_cistatic bool ProcessSendRequestFailed(const StateMachine *machine, uint32_t event, const void *para)
2722ee81decSopenharmony_ci{
2732ee81decSopenharmony_ci#define ERR_SESSION_OPEN_FAILED 2
2742ee81decSopenharmony_ci    DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
2752ee81decSopenharmony_ci    if (para == NULL) {
2762ee81decSopenharmony_ci        return false;
2772ee81decSopenharmony_ci    }
2782ee81decSopenharmony_ci
2792ee81decSopenharmony_ci    uint32_t reason = *(uint32_t *)para;
2802ee81decSopenharmony_ci    info->result = reason;
2812ee81decSopenharmony_ci    if (reason == ERR_SESSION_OPEN_FAILED) {
2822ee81decSopenharmony_ci        info->result = ERR_MSG_OPEN_SESSION;
2832ee81decSopenharmony_ci        StopSendDeviceInfoRequestTimer(info);
2842ee81decSopenharmony_ci        ProcessSendDeviceInfoCallback(info, RequestDoneChecker);
2852ee81decSopenharmony_ci        return false;
2862ee81decSopenharmony_ci    }
2872ee81decSopenharmony_ci
2882ee81decSopenharmony_ci    return CheckTimesAndSendCredRequest(info, false);
2892ee81decSopenharmony_ci}
2902ee81decSopenharmony_ci
2912ee81decSopenharmony_cistatic bool ProcessDeviceOffline(const StateMachine *machine, uint32_t event, const void *para)
2922ee81decSopenharmony_ci{
2932ee81decSopenharmony_ci    DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
2942ee81decSopenharmony_ci    info->onlineStatus = ONLINE_STATUS_OFFLINE;
2952ee81decSopenharmony_ci    info->queryTimes = 0;
2962ee81decSopenharmony_ci    info->lastOfflineTime = GetMillisecondSinceBoot();
2972ee81decSopenharmony_ci    StopSendDeviceInfoRequestTimer(info);
2982ee81decSopenharmony_ci    ProcessSendDeviceInfoCallback(info, RequestDoneChecker);
2992ee81decSopenharmony_ci    return true;
3002ee81decSopenharmony_ci}
3012ee81decSopenharmony_ci
3022ee81decSopenharmony_cistatic bool ProcessVerifyCredMessage(const StateMachine *machine, uint32_t event, const void *para)
3032ee81decSopenharmony_ci{
3042ee81decSopenharmony_ci    DslmDeviceInfo *deviceInfo = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
3052ee81decSopenharmony_ci    MessageBuff *buff = (MessageBuff *)para;
3062ee81decSopenharmony_ci
3072ee81decSopenharmony_ci    deviceInfo->lastResponseTime = GetMillisecondSinceBoot();
3082ee81decSopenharmony_ci    deviceInfo->result = (uint32_t)VerifyDeviceInfoResponse(deviceInfo, buff);
3092ee81decSopenharmony_ci    deviceInfo->lastVerifyTime = GetMillisecondSinceBoot();
3102ee81decSopenharmony_ci    DslmFinishProcessTraceAsync("SendCredRequest", machine->machineId, deviceInfo->queryTimes);
3112ee81decSopenharmony_ci    ProcessSendDeviceInfoCallback(deviceInfo, RequestDoneChecker);
3122ee81decSopenharmony_ci
3132ee81decSopenharmony_ci    if (deviceInfo->result == SUCCESS) {
3142ee81decSopenharmony_ci        SECURITY_LOG_INFO("ProcessVerifyCredMessage success, level is %{public}u", deviceInfo->credInfo.credLevel);
3152ee81decSopenharmony_ci        StopSendDeviceInfoRequestTimer(deviceInfo);
3162ee81decSopenharmony_ci        return true;
3172ee81decSopenharmony_ci    }
3182ee81decSopenharmony_ci
3192ee81decSopenharmony_ci    (void)CheckTimesAndSendCredRequest(deviceInfo, false);
3202ee81decSopenharmony_ci    return false;
3212ee81decSopenharmony_ci}
3222ee81decSopenharmony_ci
3232ee81decSopenharmony_cistatic bool ProcessSdkTimeout(const StateMachine *machine, uint32_t event, const void *para)
3242ee81decSopenharmony_ci{
3252ee81decSopenharmony_ci    DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine);
3262ee81decSopenharmony_ci    ProcessSendDeviceInfoCallback(info, SdkTimeoutChecker);
3272ee81decSopenharmony_ci    return true;
3282ee81decSopenharmony_ci}
3292ee81decSopenharmony_ci
3302ee81decSopenharmony_cistatic bool SdkTimeoutChecker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo,
3312ee81decSopenharmony_ci    uint32_t *result)
3322ee81decSopenharmony_ci{
3332ee81decSopenharmony_ci    uint64_t curr = GetMillisecondSinceBoot();
3342ee81decSopenharmony_ci    if (node->start + node->keep > curr) {
3352ee81decSopenharmony_ci        return false;
3362ee81decSopenharmony_ci    }
3372ee81decSopenharmony_ci
3382ee81decSopenharmony_ci    SECURITY_LOG_INFO("SdkTimeout, device is %{public}x, owner is %{public}u, cookie is %{public}u, keep is %{public}u",
3392ee81decSopenharmony_ci        devInfo->machine.machineId, node->owner, node->cookie, node->keep);
3402ee81decSopenharmony_ci
3412ee81decSopenharmony_ci    *result = ERR_TIMEOUT;
3422ee81decSopenharmony_ci    cbInfo->level = 0;
3432ee81decSopenharmony_ci    cbInfo->extraLen = 0;
3442ee81decSopenharmony_ci    cbInfo->extraBuff = NULL;
3452ee81decSopenharmony_ci    return true;
3462ee81decSopenharmony_ci}
3472ee81decSopenharmony_ci
3482ee81decSopenharmony_cistatic bool RequestDoneChecker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo,
3492ee81decSopenharmony_ci    uint32_t *result)
3502ee81decSopenharmony_ci{
3512ee81decSopenharmony_ci    *result = devInfo->result;
3522ee81decSopenharmony_ci    cbInfo->level = devInfo->credInfo.credLevel;
3532ee81decSopenharmony_ci    cbInfo->extraLen = 0;
3542ee81decSopenharmony_ci    cbInfo->extraBuff = NULL;
3552ee81decSopenharmony_ci
3562ee81decSopenharmony_ci    SECURITY_LOG_INFO(
3572ee81decSopenharmony_ci        "RequestDone, device is %{public}x, owner is %{public}u, cookie is %{public}u, keep is %{public}u",
3582ee81decSopenharmony_ci        devInfo->machine.machineId, node->owner, node->cookie, node->keep);
3592ee81decSopenharmony_ci
3602ee81decSopenharmony_ci    return true;
3612ee81decSopenharmony_ci}
3622ee81decSopenharmony_ci
3632ee81decSopenharmony_cistatic void RefreshNotifyList(DslmDeviceInfo *info)
3642ee81decSopenharmony_ci{
3652ee81decSopenharmony_ci    if (info == NULL) {
3662ee81decSopenharmony_ci        return;
3672ee81decSopenharmony_ci    }
3682ee81decSopenharmony_ci
3692ee81decSopenharmony_ci    // just refresh the notify list size
3702ee81decSopenharmony_ci    ListNode *node = NULL;
3712ee81decSopenharmony_ci    uint32_t size = 0;
3722ee81decSopenharmony_ci    FOREACH_LIST_NODE (node, &info->notifyList) {
3732ee81decSopenharmony_ci        size++;
3742ee81decSopenharmony_ci    }
3752ee81decSopenharmony_ci    info->notifyListSize = size;
3762ee81decSopenharmony_ci
3772ee81decSopenharmony_ci    SECURITY_LOG_INFO("device %{public}x 's notify list size update to %{public}u", info->machine.machineId,
3782ee81decSopenharmony_ci        info->notifyListSize);
3792ee81decSopenharmony_ci}
3802ee81decSopenharmony_ci
3812ee81decSopenharmony_cistatic void RefreshHistoryList(DslmDeviceInfo *info)
3822ee81decSopenharmony_ci{
3832ee81decSopenharmony_ci    if (info == NULL) {
3842ee81decSopenharmony_ci        return;
3852ee81decSopenharmony_ci    }
3862ee81decSopenharmony_ci
3872ee81decSopenharmony_ci    // only hold the lasted MAX_HISTORY_CNT node
3882ee81decSopenharmony_ci    ListNode *node = NULL;
3892ee81decSopenharmony_ci    ListNode *temp = NULL;
3902ee81decSopenharmony_ci
3912ee81decSopenharmony_ci    uint32_t historyCnt = 0;
3922ee81decSopenharmony_ci    FOREACH_LIST_NODE_SAFE (node, &info->historyList, temp) {
3932ee81decSopenharmony_ci        historyCnt++;
3942ee81decSopenharmony_ci    }
3952ee81decSopenharmony_ci    uint32_t delCnt = historyCnt > MAX_HISTORY_CNT ? (historyCnt - MAX_HISTORY_CNT) : 0;
3962ee81decSopenharmony_ci
3972ee81decSopenharmony_ci    info->historyListSize = historyCnt - delCnt;
3982ee81decSopenharmony_ci
3992ee81decSopenharmony_ci    FOREACH_LIST_NODE_SAFE (node, &info->historyList, temp) {
4002ee81decSopenharmony_ci        if (delCnt <= 0) {
4012ee81decSopenharmony_ci            break;
4022ee81decSopenharmony_ci        }
4032ee81decSopenharmony_ci        delCnt--;
4042ee81decSopenharmony_ci        DslmNotifyListNode *notifyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode);
4052ee81decSopenharmony_ci        RemoveListNode(node);
4062ee81decSopenharmony_ci        FREE(notifyNode);
4072ee81decSopenharmony_ci    }
4082ee81decSopenharmony_ci}
4092ee81decSopenharmony_ci
4102ee81decSopenharmony_civoid InitDslmStateMachine(DslmDeviceInfo *info)
4112ee81decSopenharmony_ci{
4122ee81decSopenharmony_ci    if (info == NULL) {
4132ee81decSopenharmony_ci        return;
4142ee81decSopenharmony_ci    }
4152ee81decSopenharmony_ci    uint32_t machineId = GenerateMachineId(&info->identity);
4162ee81decSopenharmony_ci    InitStateMachine(&info->machine, machineId, STATE_INIT);
4172ee81decSopenharmony_ci    SECURITY_LOG_INFO("InitDslmStateMachine success, machineId is %{public}x", machineId);
4182ee81decSopenharmony_ci}
4192ee81decSopenharmony_ci
4202ee81decSopenharmony_civoid ScheduleDslmStateMachine(DslmDeviceInfo *info, uint32_t event, const void *para)
4212ee81decSopenharmony_ci{
4222ee81decSopenharmony_ci    if (info == NULL) {
4232ee81decSopenharmony_ci        return;
4242ee81decSopenharmony_ci    }
4252ee81decSopenharmony_ci
4262ee81decSopenharmony_ci    static const StateNode stateNodes[] = {
4272ee81decSopenharmony_ci        {STATE_INIT, EVENT_DEVICE_ONLINE, ProcessDeviceOnline, STATE_WAITING_CRED_RSP, STATE_FAILED},
4282ee81decSopenharmony_ci        {STATE_INIT, EVENT_SDK_GET, ProcessSdkRequest, STATE_INIT, STATE_INIT},
4292ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_DEVICE_ONLINE, ProcessDeviceOnline, STATE_WAITING_CRED_RSP, STATE_FAILED},
4302ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_CRED_RSP, ProcessVerifyCredMessage, STATE_SUCCESS, STATE_FAILED},
4312ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_MSG_SEND_FAILED, ProcessSendRequestFailed, STATE_WAITING_CRED_RSP, STATE_FAILED},
4322ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_TIME_OUT, ProcessSendCredRequest, STATE_WAITING_CRED_RSP, STATE_FAILED},
4332ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_DEVICE_OFFLINE, ProcessDeviceOffline, STATE_INIT, STATE_INIT},
4342ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_TO_SYNC, NULL, STATE_SUCCESS, STATE_SUCCESS},
4352ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_SDK_GET, ProcessSdkRequest, STATE_WAITING_CRED_RSP, STATE_WAITING_CRED_RSP},
4362ee81decSopenharmony_ci        {STATE_WAITING_CRED_RSP, EVENT_SDK_TIMEOUT, ProcessSdkTimeout, STATE_WAITING_CRED_RSP, STATE_WAITING_CRED_RSP},
4372ee81decSopenharmony_ci        {STATE_SUCCESS, EVENT_DEVICE_OFFLINE, ProcessDeviceOffline, STATE_INIT, STATE_INIT},
4382ee81decSopenharmony_ci        {STATE_SUCCESS, EVENT_SDK_GET, ProcessSdkRequest, STATE_SUCCESS, STATE_SUCCESS},
4392ee81decSopenharmony_ci        {STATE_FAILED, EVENT_DEVICE_ONLINE, ProcessDeviceOnline, STATE_WAITING_CRED_RSP, STATE_FAILED},
4402ee81decSopenharmony_ci        {STATE_FAILED, EVENT_CRED_RSP, ProcessVerifyCredMessage, STATE_SUCCESS, STATE_FAILED},
4412ee81decSopenharmony_ci        {STATE_FAILED, EVENT_DEVICE_OFFLINE, ProcessDeviceOffline, STATE_INIT, STATE_INIT},
4422ee81decSopenharmony_ci        {STATE_FAILED, EVENT_CHECK, ProcessSendCredRequest, STATE_WAITING_CRED_RSP, STATE_WAITING_CRED_RSP},
4432ee81decSopenharmony_ci        {STATE_FAILED, EVENT_SDK_GET, ProcessSdkRequest, STATE_FAILED, STATE_FAILED},
4442ee81decSopenharmony_ci        {STATE_FAILED, EVENT_SDK_TIMEOUT, ProcessSdkTimeout, STATE_FAILED, STATE_FAILED},
4452ee81decSopenharmony_ci    };
4462ee81decSopenharmony_ci
4472ee81decSopenharmony_ci    static const uint32_t nodeCnt = sizeof(stateNodes) / sizeof(StateNode);
4482ee81decSopenharmony_ci    DslmStartStateMachineTrace(info->machine.machineId, event);
4492ee81decSopenharmony_ci    ScheduleMachine(stateNodes, nodeCnt, &info->machine, event, para);
4502ee81decSopenharmony_ci    DslmFinishProcessTrace();
4512ee81decSopenharmony_ci}
4522ee81decSopenharmony_ci
4532ee81decSopenharmony_ciuint32_t GetCurrentMachineState(const DslmDeviceInfo *info)
4542ee81decSopenharmony_ci{
4552ee81decSopenharmony_ci    if (info == NULL) {
4562ee81decSopenharmony_ci        return STATE_FAILED;
4572ee81decSopenharmony_ci    }
4582ee81decSopenharmony_ci    return info->machine.currState;
4592ee81decSopenharmony_ci}
4602ee81decSopenharmony_ci
4612ee81decSopenharmony_civoid LockDslmStateMachine(DslmDeviceInfo *info)
4622ee81decSopenharmony_ci{
4632ee81decSopenharmony_ci    LockMutex(&info->machine.mutex);
4642ee81decSopenharmony_ci}
4652ee81decSopenharmony_ci
4662ee81decSopenharmony_civoid UnLockDslmStateMachine(DslmDeviceInfo *info)
4672ee81decSopenharmony_ci{
4682ee81decSopenharmony_ci    UnlockMutex(&info->machine.mutex);
4692ee81decSopenharmony_ci}