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_hidumper.h"
172ee81decSopenharmony_ci
182ee81decSopenharmony_ci#include <stdio.h>
192ee81decSopenharmony_ci#include <stdlib.h>
202ee81decSopenharmony_ci#include <sys/time.h>
212ee81decSopenharmony_ci
222ee81decSopenharmony_ci#include "securec.h"
232ee81decSopenharmony_ci
242ee81decSopenharmony_ci#include "utils_datetime.h"
252ee81decSopenharmony_ci#include "utils_log.h"
262ee81decSopenharmony_ci
272ee81decSopenharmony_ci#include "dslm_credential.h"
282ee81decSopenharmony_ci#include "dslm_device_list.h"
292ee81decSopenharmony_ci#include "dslm_fsm_process.h"
302ee81decSopenharmony_ci#include "dslm_messenger_wrapper.h"
312ee81decSopenharmony_ci#include "dslm_notify_node.h"
322ee81decSopenharmony_ci
332ee81decSopenharmony_ci#define SPLIT_LINE "------------------------------------------------------"
342ee81decSopenharmony_ci#define END_LINE "\n"
352ee81decSopenharmony_ci
362ee81decSopenharmony_ci#define TIME_STRING_LEN 256
372ee81decSopenharmony_ci#define COST_STRING_LEN 64
382ee81decSopenharmony_ci#define NOTIFY_NODE_MAX_CNT 1024
392ee81decSopenharmony_ci
402ee81decSopenharmony_cistatic pthread_mutex_t g_buffMutex = PTHREAD_MUTEX_INITIALIZER;
412ee81decSopenharmony_ci
422ee81decSopenharmony_cistatic const char *GetTimeStringFromTimeStamp(uint64_t timeStamp)
432ee81decSopenharmony_ci{
442ee81decSopenharmony_ci    static char timeBuff[TIME_STRING_LEN] = {0};
452ee81decSopenharmony_ci    DateTime dateTime = {0};
462ee81decSopenharmony_ci    bool success = false;
472ee81decSopenharmony_ci    int lockRet = pthread_mutex_lock(&g_buffMutex);
482ee81decSopenharmony_ci    if (lockRet != 0) {
492ee81decSopenharmony_ci        SECURITY_LOG_ERROR("pthread_mutex_lock error");
502ee81decSopenharmony_ci        return "";
512ee81decSopenharmony_ci    }
522ee81decSopenharmony_ci    do {
532ee81decSopenharmony_ci        (void)memset_s(timeBuff, TIME_STRING_LEN, 0, TIME_STRING_LEN);
542ee81decSopenharmony_ci        if (timeStamp == 0) {
552ee81decSopenharmony_ci            break;
562ee81decSopenharmony_ci        }
572ee81decSopenharmony_ci        if (!GetDateTimeByMillisecondSinceBoot(timeStamp, &dateTime)) {
582ee81decSopenharmony_ci            SECURITY_LOG_ERROR("GetTimeStringFromTimeStamp GetDateTimeByMillisecondSinceBoot error");
592ee81decSopenharmony_ci            break;
602ee81decSopenharmony_ci        }
612ee81decSopenharmony_ci        int ret =
622ee81decSopenharmony_ci            snprintf_s(timeBuff, TIME_STRING_LEN, TIME_STRING_LEN - 1, "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.%03hu",
632ee81decSopenharmony_ci                dateTime.year, dateTime.mon, dateTime.day, dateTime.hour, dateTime.min, dateTime.sec, dateTime.msec);
642ee81decSopenharmony_ci        if (ret < 0) {
652ee81decSopenharmony_ci            break;
662ee81decSopenharmony_ci        }
672ee81decSopenharmony_ci        success = true;
682ee81decSopenharmony_ci    } while (0);
692ee81decSopenharmony_ci
702ee81decSopenharmony_ci    if (!success) {
712ee81decSopenharmony_ci        if (snprintf_s(timeBuff, TIME_STRING_LEN, TIME_STRING_LEN - 1, "-") < 0) {
722ee81decSopenharmony_ci            SECURITY_LOG_ERROR("GetTimeStringFromTimeStamp snprintf_s error");
732ee81decSopenharmony_ci        }
742ee81decSopenharmony_ci    }
752ee81decSopenharmony_ci
762ee81decSopenharmony_ci    lockRet = pthread_mutex_unlock(&g_buffMutex);
772ee81decSopenharmony_ci    if (lockRet != 0) {
782ee81decSopenharmony_ci        SECURITY_LOG_ERROR("pthread_mutex_unlock error");
792ee81decSopenharmony_ci    }
802ee81decSopenharmony_ci    return timeBuff;
812ee81decSopenharmony_ci}
822ee81decSopenharmony_ci
832ee81decSopenharmony_cistatic const char *GetCostTime(const uint64_t beginTime, const uint64_t endTime)
842ee81decSopenharmony_ci{
852ee81decSopenharmony_ci    static char costBuff[COST_STRING_LEN] = {0};
862ee81decSopenharmony_ci
872ee81decSopenharmony_ci    if (beginTime == 0 || endTime == 0) {
882ee81decSopenharmony_ci        return "";
892ee81decSopenharmony_ci    }
902ee81decSopenharmony_ci
912ee81decSopenharmony_ci    if (endTime < beginTime) {
922ee81decSopenharmony_ci        return "";
932ee81decSopenharmony_ci    }
942ee81decSopenharmony_ci    uint32_t cost = (uint32_t)(endTime - beginTime);
952ee81decSopenharmony_ci
962ee81decSopenharmony_ci    int ret = pthread_mutex_lock(&g_buffMutex);
972ee81decSopenharmony_ci    if (ret != 0) {
982ee81decSopenharmony_ci        SECURITY_LOG_ERROR("pthread_mutex_lock error");
992ee81decSopenharmony_ci        return "";
1002ee81decSopenharmony_ci    }
1012ee81decSopenharmony_ci
1022ee81decSopenharmony_ci    if (snprintf_s(costBuff, COST_STRING_LEN, COST_STRING_LEN - 1, "(cost %ums)", cost) < 0) {
1032ee81decSopenharmony_ci        ret = pthread_mutex_unlock(&g_buffMutex);
1042ee81decSopenharmony_ci        if (ret != 0) {
1052ee81decSopenharmony_ci            SECURITY_LOG_ERROR("pthread_mutex_unlock error");
1062ee81decSopenharmony_ci        }
1072ee81decSopenharmony_ci        return "";
1082ee81decSopenharmony_ci    };
1092ee81decSopenharmony_ci
1102ee81decSopenharmony_ci    ret = pthread_mutex_unlock(&g_buffMutex);
1112ee81decSopenharmony_ci    if (ret != 0) {
1122ee81decSopenharmony_ci        SECURITY_LOG_ERROR("pthread_mutex_unlock error");
1132ee81decSopenharmony_ci    }
1142ee81decSopenharmony_ci    return costBuff;
1152ee81decSopenharmony_ci}
1162ee81decSopenharmony_ci
1172ee81decSopenharmony_cistatic const char *GetMachineState(const DslmDeviceInfo *info)
1182ee81decSopenharmony_ci{
1192ee81decSopenharmony_ci    uint32_t state = GetCurrentMachineState(info);
1202ee81decSopenharmony_ci    switch (state) {
1212ee81decSopenharmony_ci        case STATE_INIT:
1222ee81decSopenharmony_ci            return "STATE_INIT";
1232ee81decSopenharmony_ci        case STATE_WAITING_CRED_RSP:
1242ee81decSopenharmony_ci            return "STATE_WAITING_CRED_RSP";
1252ee81decSopenharmony_ci        case STATE_SUCCESS:
1262ee81decSopenharmony_ci            return "STATE_SUCCESS";
1272ee81decSopenharmony_ci        case STATE_FAILED:
1282ee81decSopenharmony_ci            return "STATE_FAILED";
1292ee81decSopenharmony_ci        default:
1302ee81decSopenharmony_ci            return "STATE_UNKOWN";
1312ee81decSopenharmony_ci    }
1322ee81decSopenharmony_ci}
1332ee81decSopenharmony_ci
1342ee81decSopenharmony_cistatic const char *GetCreadType(const DslmDeviceInfo *info)
1352ee81decSopenharmony_ci{
1362ee81decSopenharmony_ci    switch (info->credInfo.credType) {
1372ee81decSopenharmony_ci        case CRED_TYPE_MINI:
1382ee81decSopenharmony_ci            return "mini";
1392ee81decSopenharmony_ci        case CRED_TYPE_SMALL:
1402ee81decSopenharmony_ci            return "small";
1412ee81decSopenharmony_ci        case CRED_TYPE_STANDARD:
1422ee81decSopenharmony_ci            return "standard";
1432ee81decSopenharmony_ci        case CRED_TYPE_LARGE:
1442ee81decSopenharmony_ci            return "large";
1452ee81decSopenharmony_ci        default:
1462ee81decSopenharmony_ci            return "default";
1472ee81decSopenharmony_ci    }
1482ee81decSopenharmony_ci}
1492ee81decSopenharmony_ci
1502ee81decSopenharmony_cistatic int32_t GetPendingNotifyNodeCnt(const DslmDeviceInfo *info)
1512ee81decSopenharmony_ci{
1522ee81decSopenharmony_ci    int result = 0;
1532ee81decSopenharmony_ci    LockDslmStateMachine((DslmDeviceInfo *)info);
1542ee81decSopenharmony_ci    ListNode *node = NULL;
1552ee81decSopenharmony_ci    FOREACH_LIST_NODE (node, &info->notifyList) {
1562ee81decSopenharmony_ci        result++;
1572ee81decSopenharmony_ci        if (result >= NOTIFY_NODE_MAX_CNT) {
1582ee81decSopenharmony_ci            break;
1592ee81decSopenharmony_ci        }
1602ee81decSopenharmony_ci    }
1612ee81decSopenharmony_ci    UnLockDslmStateMachine((DslmDeviceInfo *)info);
1622ee81decSopenharmony_ci    return result;
1632ee81decSopenharmony_ci}
1642ee81decSopenharmony_ci
1652ee81decSopenharmony_cistatic void GetDefaultStatus(int32_t *requestResult, int32_t *verifyResult, uint32_t *credLevel)
1662ee81decSopenharmony_ci{
1672ee81decSopenharmony_ci    if (requestResult == NULL || verifyResult == NULL || credLevel == NULL) {
1682ee81decSopenharmony_ci        return;
1692ee81decSopenharmony_ci    }
1702ee81decSopenharmony_ci
1712ee81decSopenharmony_ci    int32_t level = 0;
1722ee81decSopenharmony_ci    const DeviceIdentify *device = GetSelfDevice(&level);
1732ee81decSopenharmony_ci    RequestObject object;
1742ee81decSopenharmony_ci
1752ee81decSopenharmony_ci    object.arraySize = (uint32_t)GetSupportedCredTypes(object.credArray, MAX_CRED_ARRAY_SIZE);
1762ee81decSopenharmony_ci    object.challenge = 0x0;
1772ee81decSopenharmony_ci    object.version = GetCurrentVersion();
1782ee81decSopenharmony_ci
1792ee81decSopenharmony_ci    DslmCredBuff *cred = NULL;
1802ee81decSopenharmony_ci    *requestResult = DefaultRequestDslmCred(device, &object, &cred);
1812ee81decSopenharmony_ci
1822ee81decSopenharmony_ci    DslmCredInfo info;
1832ee81decSopenharmony_ci    (void)memset_s(&info, sizeof(DslmCredInfo), 0, sizeof(DslmCredInfo));
1842ee81decSopenharmony_ci
1852ee81decSopenharmony_ci    *verifyResult = DefaultVerifyDslmCred(device, object.challenge, cred, &info);
1862ee81decSopenharmony_ci    *credLevel = info.credLevel;
1872ee81decSopenharmony_ci    DestroyDslmCred(cred);
1882ee81decSopenharmony_ci}
1892ee81decSopenharmony_ci
1902ee81decSopenharmony_cistatic void PrintBanner(int fd)
1912ee81decSopenharmony_ci{
1922ee81decSopenharmony_ci    dprintf(fd, " ___  ___ _    __  __   ___  _   _ __  __ ___ ___ ___ " END_LINE);
1932ee81decSopenharmony_ci    dprintf(fd, "|   \\/ __| |  |  \\/  | |   \\| | | |  \\/  | _ \\ __| _ \\" END_LINE);
1942ee81decSopenharmony_ci    dprintf(fd, "| |) \\__ \\ |__| |\\/| | | |) | |_| | |\\/| |  _/ __|   /" END_LINE);
1952ee81decSopenharmony_ci    dprintf(fd, "|___/|___/____|_|  |_| |___/ \\___/|_|  |_|_| |___|_|_\\" END_LINE);
1962ee81decSopenharmony_ci}
1972ee81decSopenharmony_ci
1982ee81decSopenharmony_cistatic void DumpDeviceDetails(const DslmDeviceInfo *info, int32_t fd)
1992ee81decSopenharmony_ci{
2002ee81decSopenharmony_ci    dprintf(fd, "DEVICE_ID                 : %x" END_LINE, info->machine.machineId);
2012ee81decSopenharmony_ci    dprintf(fd, END_LINE);
2022ee81decSopenharmony_ci
2032ee81decSopenharmony_ci    dprintf(fd, "DEVICE_ONLINE_STATUS      : %s" END_LINE, (info->onlineStatus != 0) ? "online" : "offline");
2042ee81decSopenharmony_ci    dprintf(fd, "DEVICE_ONLINE_TIME        : %s" END_LINE, GetTimeStringFromTimeStamp(info->lastOnlineTime));
2052ee81decSopenharmony_ci    dprintf(fd, "DEVICE_OFFLINE_TIME       : %s" END_LINE, GetTimeStringFromTimeStamp(info->lastOfflineTime));
2062ee81decSopenharmony_ci    dprintf(fd, "DEVICE_REQUEST_TIME       : %s" END_LINE, GetTimeStringFromTimeStamp(info->lastRequestTime));
2072ee81decSopenharmony_ci    dprintf(fd, "DEVICE_RESPONSE_TIME      : %s%s" END_LINE, GetTimeStringFromTimeStamp(info->lastResponseTime),
2082ee81decSopenharmony_ci        GetCostTime(info->lastRequestTime, info->lastResponseTime));
2092ee81decSopenharmony_ci    dprintf(fd, "DEVICE_VERIFY_TIME        : %s%s" END_LINE, GetTimeStringFromTimeStamp(info->lastVerifyTime),
2102ee81decSopenharmony_ci        GetCostTime(info->lastResponseTime, info->lastVerifyTime));
2112ee81decSopenharmony_ci    dprintf(fd, END_LINE);
2122ee81decSopenharmony_ci
2132ee81decSopenharmony_ci    dprintf(fd, "DEVICE_PENDING_CNT        : %d" END_LINE, GetPendingNotifyNodeCnt(info));
2142ee81decSopenharmony_ci    dprintf(fd, "DEVICE_MACHINE_STATUS     : %s" END_LINE, GetMachineState(info));
2152ee81decSopenharmony_ci    dprintf(fd, "DEVICE_VERIFIED_LEVEL     : %u" END_LINE, info->credInfo.credLevel);
2162ee81decSopenharmony_ci    dprintf(fd, "DEVICE_VERIFIED_RESULT    : %s" END_LINE, (info->result == 0) ? "success" : "failed");
2172ee81decSopenharmony_ci    dprintf(fd, END_LINE);
2182ee81decSopenharmony_ci
2192ee81decSopenharmony_ci    dprintf(fd, "CRED_TYPE                 : %s" END_LINE, GetCreadType(info));
2202ee81decSopenharmony_ci    dprintf(fd, "CRED_RELEASE_TYPE         : %s" END_LINE, info->credInfo.releaseType);
2212ee81decSopenharmony_ci    dprintf(fd, "CRED_SIGN_TIME            : %s" END_LINE, info->credInfo.signTime);
2222ee81decSopenharmony_ci    dprintf(fd, "CRED_MANUFACTURE          : %s" END_LINE, info->credInfo.manufacture);
2232ee81decSopenharmony_ci    dprintf(fd, "CRED_BAND                 : %s" END_LINE, info->credInfo.brand);
2242ee81decSopenharmony_ci    dprintf(fd, "CRED_MODEL                : %s" END_LINE, info->credInfo.model);
2252ee81decSopenharmony_ci    dprintf(fd, "CRED_SOFTWARE_VERSION     : %s" END_LINE, info->credInfo.softwareVersion);
2262ee81decSopenharmony_ci    dprintf(fd, "CRED_SECURITY_LEVEL       : %s" END_LINE, info->credInfo.securityLevel);
2272ee81decSopenharmony_ci    dprintf(fd, "CRED_VERSION              : %s" END_LINE, info->credInfo.version);
2282ee81decSopenharmony_ci    dprintf(fd, END_LINE);
2292ee81decSopenharmony_ci}
2302ee81decSopenharmony_ci
2312ee81decSopenharmony_cistatic void DumpHistoryCalls(const DslmDeviceInfo *info, int32_t fd)
2322ee81decSopenharmony_ci{
2332ee81decSopenharmony_ci    dprintf(fd, "SDK_CALL_HISTORY: " END_LINE);
2342ee81decSopenharmony_ci    ListNode *node = NULL;
2352ee81decSopenharmony_ci    int32_t index = 0;
2362ee81decSopenharmony_ci    FOREACH_LIST_NODE (node, &info->historyList) {
2372ee81decSopenharmony_ci        index++;
2382ee81decSopenharmony_ci        DslmNotifyListNode *notifyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode);
2392ee81decSopenharmony_ci
2402ee81decSopenharmony_ci        char timeStart[TIME_STRING_LEN] = {0};
2412ee81decSopenharmony_ci        if (strcpy_s(timeStart, TIME_STRING_LEN, GetTimeStringFromTimeStamp(notifyNode->start)) != EOK) {
2422ee81decSopenharmony_ci            continue;
2432ee81decSopenharmony_ci        }
2442ee81decSopenharmony_ci        char timeStop[TIME_STRING_LEN] = {0};
2452ee81decSopenharmony_ci        if (strcpy_s(timeStop, TIME_STRING_LEN, GetTimeStringFromTimeStamp(notifyNode->stop)) != EOK) {
2462ee81decSopenharmony_ci            continue;
2472ee81decSopenharmony_ci        }
2482ee81decSopenharmony_ci
2492ee81decSopenharmony_ci        uint32_t cost = (notifyNode->stop > notifyNode->start) ? (notifyNode->stop - notifyNode->start) : 0;
2502ee81decSopenharmony_ci        dprintf(fd, "#%-4d pid:%-6u seq:%-4u req:%-26s res:%-26s ret:%-4u cost:%ums" END_LINE, index, notifyNode->owner,
2512ee81decSopenharmony_ci            notifyNode->cookie, timeStart, timeStop, notifyNode->result, cost);
2522ee81decSopenharmony_ci
2532ee81decSopenharmony_ci        if (index >= NOTIFY_NODE_MAX_CNT) {
2542ee81decSopenharmony_ci            break;
2552ee81decSopenharmony_ci        }
2562ee81decSopenharmony_ci    }
2572ee81decSopenharmony_ci}
2582ee81decSopenharmony_ci
2592ee81decSopenharmony_cistatic void DumpOneDevice(const DslmDeviceInfo *info, int32_t fd)
2602ee81decSopenharmony_ci{
2612ee81decSopenharmony_ci    if (info == NULL) {
2622ee81decSopenharmony_ci        return;
2632ee81decSopenharmony_ci    }
2642ee81decSopenharmony_ci
2652ee81decSopenharmony_ci    dprintf(fd, SPLIT_LINE END_LINE);
2662ee81decSopenharmony_ci    DumpDeviceDetails(info, fd);
2672ee81decSopenharmony_ci    DumpHistoryCalls(info, fd);
2682ee81decSopenharmony_ci    dprintf(fd, SPLIT_LINE END_LINE);
2692ee81decSopenharmony_ci}
2702ee81decSopenharmony_ci
2712ee81decSopenharmony_cistatic void PrintAllDevices(int fd)
2722ee81decSopenharmony_ci{
2732ee81decSopenharmony_ci    ForEachDeviceDump(DumpOneDevice, fd);
2742ee81decSopenharmony_ci}
2752ee81decSopenharmony_ci
2762ee81decSopenharmony_cistatic void PrintDefaultStatus(int fd)
2772ee81decSopenharmony_ci{
2782ee81decSopenharmony_ci    int32_t requestResult = 0;
2792ee81decSopenharmony_ci    int32_t verifyResult = 0;
2802ee81decSopenharmony_ci    uint32_t credLevel = 0;
2812ee81decSopenharmony_ci
2822ee81decSopenharmony_ci    GetDefaultStatus(&requestResult, &verifyResult, &credLevel);
2832ee81decSopenharmony_ci
2842ee81decSopenharmony_ci    const time_t YEAR_TIME_2023 = 1699977600;
2852ee81decSopenharmony_ci    struct timeval timeVal = {0};
2862ee81decSopenharmony_ci    gettimeofday(&timeVal, NULL);
2872ee81decSopenharmony_ci    char *notice = timeVal.tv_sec <= YEAR_TIME_2023 ? "(please check the system time)" : "";
2882ee81decSopenharmony_ci
2892ee81decSopenharmony_ci    dprintf(fd, SPLIT_LINE END_LINE);
2902ee81decSopenharmony_ci    dprintf(fd, "REQUEST_TEST              : %s" END_LINE, requestResult == SUCCESS ? "success" : "failed");
2912ee81decSopenharmony_ci    dprintf(fd, "VERIFY_TEST               : %s%s" END_LINE, verifyResult == SUCCESS ? "success" : "failed", notice);
2922ee81decSopenharmony_ci    dprintf(fd, "SELF_CRED_LEVEL           : %u" END_LINE, credLevel);
2932ee81decSopenharmony_ci    dprintf(fd, SPLIT_LINE END_LINE);
2942ee81decSopenharmony_ci}
2952ee81decSopenharmony_ci
2962ee81decSopenharmony_civoid DslmDumper(int fd)
2972ee81decSopenharmony_ci{
2982ee81decSopenharmony_ci    PrintBanner(fd);
2992ee81decSopenharmony_ci    PrintDefaultStatus(fd);
3002ee81decSopenharmony_ci    PrintAllDevices(fd);
3012ee81decSopenharmony_ci}