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(¬ify->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}