1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dslm_hidumper.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/time.h>
21
22 #include "securec.h"
23
24 #include "utils_datetime.h"
25 #include "utils_log.h"
26
27 #include "dslm_credential.h"
28 #include "dslm_device_list.h"
29 #include "dslm_fsm_process.h"
30 #include "dslm_notify_node.h"
31
32 #define SPLIT_LINE "------------------------------------------------------"
33 #define END_LINE "\n"
34
35 #define TIME_STRING_LEN 256
36 #define COST_STRING_LEN 64
37 #define NOTIFY_NODE_MAX_CNT 1024
38
GetTimeStringFromTimeStamp(uint64_t timeStamp)39 static const char *GetTimeStringFromTimeStamp(uint64_t timeStamp)
40 {
41 static char timeBuff[TIME_STRING_LEN] = {0};
42 DateTime dateTime = {0};
43 bool success = false;
44 do {
45 (void)memset_s(timeBuff, TIME_STRING_LEN, 0, TIME_STRING_LEN);
46 if (timeStamp == 0) {
47 break;
48 }
49 if (!GetDateTimeByMillisecondSinceBoot(timeStamp, &dateTime)) {
50 SECURITY_LOG_ERROR("GetTimeStringFromTimeStamp GetDateTimeByMillisecondSinceBoot error");
51 break;
52 }
53 int ret =
54 snprintf_s(timeBuff, TIME_STRING_LEN, TIME_STRING_LEN - 1, "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.%03hu",
55 dateTime.year, dateTime.mon, dateTime.day, dateTime.hour, dateTime.min, dateTime.sec, dateTime.msec);
56 if (ret < 0) {
57 break;
58 }
59 success = true;
60 } while (0);
61
62 if (!success) {
63 if (snprintf_s(timeBuff, TIME_STRING_LEN, TIME_STRING_LEN - 1, "-") < 0) {
64 SECURITY_LOG_ERROR("GetTimeStringFromTimeStamp snprintf_s error");
65 }
66 }
67 return timeBuff;
68 }
69
GetCostTime(const uint64_t beginTime,const uint64_t endTime)70 static const char *GetCostTime(const uint64_t beginTime, const uint64_t endTime)
71 {
72 static char costBuff[COST_STRING_LEN] = {0};
73
74 if (beginTime == 0 || endTime == 0) {
75 return "";
76 }
77
78 if (endTime < beginTime) {
79 return "";
80 }
81 uint32_t cost = (uint32_t)(endTime - beginTime);
82 if (snprintf_s(costBuff, COST_STRING_LEN, COST_STRING_LEN - 1, "(cost %ums)", cost) < 0) {
83 return "";
84 };
85 return costBuff;
86 }
87
GetMachineState(const DslmDeviceInfo * info)88 static const char *GetMachineState(const DslmDeviceInfo *info)
89 {
90 uint32_t state = GetCurrentMachineState(info);
91 switch (state) {
92 case STATE_INIT:
93 return "STATE_INIT";
94 case STATE_WAITING_CRED_RSP:
95 return "STATE_WAITING_CRED_RSP";
96 case STATE_SUCCESS:
97 return "STATE_SUCCESS";
98 case STATE_FAILED:
99 return "STATE_FAILED";
100 default:
101 return "STATE_UNKOWN";
102 }
103 }
104
GetCreadType(const DslmDeviceInfo * info)105 static const char *GetCreadType(const DslmDeviceInfo *info)
106 {
107 switch (info->credInfo.credType) {
108 case CRED_TYPE_MINI:
109 return "mini";
110 case CRED_TYPE_SMALL:
111 return "small";
112 case CRED_TYPE_STANDARD:
113 return "standard";
114 case CRED_TYPE_LARGE:
115 return "large";
116 default:
117 return "default";
118 }
119 }
120
GetPendingNotifyNodeCnt(const DslmDeviceInfo * info)121 static int32_t GetPendingNotifyNodeCnt(const DslmDeviceInfo *info)
122 {
123 int result = 0;
124 LockDslmStateMachine((DslmDeviceInfo *)info);
125 ListNode *node = NULL;
126 FOREACH_LIST_NODE (node, &info->notifyList) {
127 result++;
128 if (result >= NOTIFY_NODE_MAX_CNT) {
129 break;
130 }
131 }
132 UnLockDslmStateMachine((DslmDeviceInfo *)info);
133 return result;
134 }
135
GetDefaultStatus(int32_t * requestResult,int32_t * verifyResult,uint32_t * credLevel)136 static void GetDefaultStatus(int32_t *requestResult, int32_t *verifyResult, uint32_t *credLevel)
137 {
138 if (requestResult == NULL || verifyResult == NULL || credLevel == NULL) {
139 return;
140 }
141 const DeviceIdentify identify = {DEVICE_ID_MAX_LEN, {0}};
142 RequestObject object;
143
144 object.arraySize = 1;
145 object.credArray[0] = CRED_TYPE_STANDARD;
146 object.challenge = 0x0;
147 object.version = GetCurrentVersion();
148
149 DslmCredBuff *cred = NULL;
150 *requestResult = DefaultRequestDslmCred(&identify, &object, &cred);
151
152 DslmCredInfo info;
153 (void)memset_s(&info, sizeof(DslmCredInfo), 0, sizeof(DslmCredInfo));
154
155 *verifyResult = DefaultVerifyDslmCred(&identify, object.challenge, cred, &info);
156 *credLevel = info.credLevel;
157 DestroyDslmCred(cred);
158 }
159
PrintBanner(int fd)160 static void PrintBanner(int fd)
161 {
162 dprintf(fd, " ___ ___ _ __ __ ___ _ _ __ __ ___ ___ ___ " END_LINE);
163 dprintf(fd, "| \\/ __| | | \\/ | | \\| | | | \\/ | _ \\ __| _ \\" END_LINE);
164 dprintf(fd, "| |) \\__ \\ |__| |\\/| | | |) | |_| | |\\/| | _/ __| /" END_LINE);
165 dprintf(fd, "|___/|___/____|_| |_| |___/ \\___/|_| |_|_| |___|_|_\\" END_LINE);
166 }
167
DumpDeviceDetails(const DslmDeviceInfo * info,int32_t fd)168 static void DumpDeviceDetails(const DslmDeviceInfo *info, int32_t fd)
169 {
170 dprintf(fd, "DEVICE_ID : %x" END_LINE, info->machine.machineId);
171 dprintf(fd, END_LINE);
172
173 dprintf(fd, "DEVICE_ONLINE_STATUS : %s" END_LINE, (info->onlineStatus != 0) ? "online" : "offline");
174 dprintf(fd, "DEVICE_ONLINE_TIME : %s" END_LINE, GetTimeStringFromTimeStamp(info->lastOnlineTime));
175 dprintf(fd, "DEVICE_OFFLINE_TIME : %s" END_LINE, GetTimeStringFromTimeStamp(info->lastOfflineTime));
176 dprintf(fd, "DEVICE_REQUEST_TIME : %s" END_LINE, GetTimeStringFromTimeStamp(info->lastRequestTime));
177 dprintf(fd, "DEVICE_RESPONSE_TIME : %s%s" END_LINE, GetTimeStringFromTimeStamp(info->lastResponseTime),
178 GetCostTime(info->lastRequestTime, info->lastResponseTime));
179 dprintf(fd, "DEVICE_VERIFY_TIME : %s%s" END_LINE, GetTimeStringFromTimeStamp(info->lastVerifyTime),
180 GetCostTime(info->lastResponseTime, info->lastVerifyTime));
181 dprintf(fd, END_LINE);
182
183 dprintf(fd, "DEVICE_PENDING_CNT : %d" END_LINE, GetPendingNotifyNodeCnt(info));
184 dprintf(fd, "DEVICE_MACHINE_STATUS : %s" END_LINE, GetMachineState(info));
185 dprintf(fd, "DEVICE_VERIFIED_LEVEL : %u" END_LINE, info->credInfo.credLevel);
186 dprintf(fd, "DEVICE_VERIFIED_RESULT : %s" END_LINE, (info->result == 0) ? "success" : "failed");
187 dprintf(fd, END_LINE);
188
189 dprintf(fd, "CRED_TYPE : %s" END_LINE, GetCreadType(info));
190 dprintf(fd, "CRED_RELEASE_TYPE : %s" END_LINE, info->credInfo.releaseType);
191 dprintf(fd, "CRED_SIGN_TIME : %s" END_LINE, info->credInfo.signTime);
192 dprintf(fd, "CRED_MANUFACTURE : %s" END_LINE, info->credInfo.manufacture);
193 dprintf(fd, "CRED_BAND : %s" END_LINE, info->credInfo.brand);
194 dprintf(fd, "CRED_MODEL : %s" END_LINE, info->credInfo.model);
195 dprintf(fd, "CRED_SOFTWARE_VERSION : %s" END_LINE, info->credInfo.softwareVersion);
196 dprintf(fd, "CRED_SECURITY_LEVEL : %s" END_LINE, info->credInfo.securityLevel);
197 dprintf(fd, "CRED_VERSION : %s" END_LINE, info->credInfo.version);
198 dprintf(fd, END_LINE);
199 }
200
DumpHistoryCalls(const DslmDeviceInfo * info,int32_t fd)201 static void DumpHistoryCalls(const DslmDeviceInfo *info, int32_t fd)
202 {
203 dprintf(fd, "SDK_CALL_HISTORY: " END_LINE);
204 ListNode *node = NULL;
205 int32_t index = 0;
206 FOREACH_LIST_NODE (node, &info->historyList) {
207 index++;
208 DslmNotifyListNode *notifyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode);
209
210 char timeStart[TIME_STRING_LEN] = {0};
211 if (strcpy_s(timeStart, TIME_STRING_LEN, GetTimeStringFromTimeStamp(notifyNode->start)) != EOK) {
212 continue;
213 }
214 char timeStop[TIME_STRING_LEN] = {0};
215 if (strcpy_s(timeStop, TIME_STRING_LEN, GetTimeStringFromTimeStamp(notifyNode->stop)) != EOK) {
216 continue;
217 }
218
219 uint32_t cost = (notifyNode->stop > notifyNode->start) ? (notifyNode->stop - notifyNode->start) : 0;
220 dprintf(fd, "#%-4d pid:%-6u seq:%-4u req:%-26s res:%-26s ret:%-4u cost:%ums" END_LINE, index, notifyNode->owner,
221 notifyNode->cookie, timeStart, timeStop, notifyNode->result, cost);
222
223 if (index >= NOTIFY_NODE_MAX_CNT) {
224 break;
225 }
226 }
227 }
228
DumpOneDevice(const DslmDeviceInfo * info,int32_t fd)229 static void DumpOneDevice(const DslmDeviceInfo *info, int32_t fd)
230 {
231 if (info == NULL) {
232 return;
233 }
234
235 dprintf(fd, SPLIT_LINE END_LINE);
236 DumpDeviceDetails(info, fd);
237 DumpHistoryCalls(info, fd);
238 dprintf(fd, SPLIT_LINE END_LINE);
239 }
240
PrintAllDevices(int fd)241 static void PrintAllDevices(int fd)
242 {
243 ForEachDeviceDump(DumpOneDevice, fd);
244 }
245
PrintDefaultStatus(int fd)246 static void PrintDefaultStatus(int fd)
247 {
248 int32_t requestResult = 0;
249 int32_t verifyResult = 0;
250 uint32_t credLevel = 0;
251
252 GetDefaultStatus(&requestResult, &verifyResult, &credLevel);
253
254 const time_t YEAR_TIME_2023 = 1699977600;
255 struct timeval timeVal = {0};
256 gettimeofday(&timeVal, NULL);
257 char *notice = timeVal.tv_sec <= YEAR_TIME_2023 ? "(please check the system time)" : "";
258
259 dprintf(fd, SPLIT_LINE END_LINE);
260 dprintf(fd, "REQUEST_TEST : %s" END_LINE, requestResult == SUCCESS ? "success" : "failed");
261 dprintf(fd, "VERIFY_TEST : %s%s" END_LINE, verifyResult == SUCCESS ? "success" : "failed", notice);
262 dprintf(fd, "SELF_CRED_LEVEL : %u" END_LINE, credLevel);
263 dprintf(fd, SPLIT_LINE END_LINE);
264 }
265
DslmDumper(int fd)266 void DslmDumper(int fd)
267 {
268 PrintBanner(fd);
269 PrintDefaultStatus(fd);
270 PrintAllDevices(fd);
271 }