1 /*
2 * Copyright (C) 2021-2023 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 "nstackx_dfinder_mgt_msg_log.h"
17 #include "nstackx_device.h"
18 #include "nstackx_dfinder_hidump.h"
19 #include "nstackx_dfinder_log.h"
20 #include "nstackx_util.h"
21 #include "json_payload.h"
22
23 #ifdef DFINDER_MGT_MSG_LOG
24
25 #define TAG "nStackXDFinder"
26
27 #define MAKE_STR(x) #x
28
29 static int g_mgtMsgLog = 0;
30
DFinderSetMgtMsgLog(int enable)31 void DFinderSetMgtMsgLog(int enable)
32 {
33 g_mgtMsgLog = enable;
34 if (g_mgtMsgLog == 0) {
35 DFINDER_LOGD(TAG, "disable management message log");
36 return;
37 }
38 DFINDER_LOGD(TAG, "enable management message log");
39 }
40
GetCoapReqTypeStr(uint8_t reqType)41 static char *GetCoapReqTypeStr(uint8_t reqType)
42 {
43 switch (reqType) {
44 case COAP_MESSAGE_CON:
45 return MAKE_STR(COAP_MESSAGE_CON);
46 case COAP_MESSAGE_NON:
47 return MAKE_STR(COAP_MESSAGE_NON);
48 case COAP_MESSAGE_ACK:
49 return MAKE_STR(COAP_MESSAGE_ACK);
50 case COAP_MESSAGE_RST:
51 return MAKE_STR(COAP_MESSAGE_RST);
52 default:
53 return NULL;
54 }
55 }
56
GetBusinessTypeStr(uint8_t businessType)57 static char *GetBusinessTypeStr(uint8_t businessType)
58 {
59 switch (businessType) {
60 case NSTACKX_BUSINESS_TYPE_NULL:
61 return MAKE_STR(NSTACKX_BUSINESS_TYPE_NULL);
62 case NSTACKX_BUSINESS_TYPE_HICOM:
63 return MAKE_STR(NSTACKX_BUSINESS_TYPE_HICOM);
64 case NSTACKX_BUSINESS_TYPE_SOFTBUS:
65 return MAKE_STR(NSTACKX_BUSINESS_TYPE_SOFTBUS);
66 case NSTACKX_BUSINESS_TYPE_NEARBY:
67 return MAKE_STR(NSTACKX_BUSINESS_TYPE_NEARBY);
68 default:
69 return NULL;
70 }
71 }
72
GetModeTypeStr(uint8_t discMode)73 static char *GetModeTypeStr(uint8_t discMode)
74 {
75 switch (discMode) {
76 case DEFAULT_MODE:
77 return MAKE_STR(DEFAULT_MODE);
78 case DISCOVER_MODE:
79 return MAKE_STR(DISCOVER_MODE);
80 case PUBLISH_MODE_UPLINE:
81 return MAKE_STR(PUBLISH_MODE_UPLINE);
82 case PUBLISH_MODE_OFFLINE:
83 return MAKE_STR(PUBLISH_MODE_OFFLINE);
84 case PUBLISH_MODE_PROACTIVE:
85 return MAKE_STR(PUBLISH_MODE_PROACTIVE);
86 default:
87 return NULL;
88 }
89 }
90
RemoveCoapReqJsonData(cJSON * data)91 static void RemoveCoapReqJsonData(cJSON *data)
92 {
93 // remove: service data, extend service data, business data, coapUri, device hash
94 cJSON_DeleteItemFromObjectCaseSensitive(data, JSON_SERVICE_DATA);
95 cJSON_DeleteItemFromObjectCaseSensitive(data, JSON_EXTEND_SERVICE_DATA);
96 cJSON_DeleteItemFromObjectCaseSensitive(data, JSON_BUSINESS_DATA);
97 cJSON_DeleteItemFromObjectCaseSensitive(data, JSON_COAP_URI);
98 cJSON_DeleteItemFromObjectCaseSensitive(data, JSON_DEVICE_HASH);
99 }
100
GetAnonymizedIp(char * dstIp,size_t dstLen,char * srcIp)101 static int32_t GetAnonymizedIp(char *dstIp, size_t dstLen, char *srcIp)
102 {
103 struct sockaddr_in addr;
104 (void)memset_s(&addr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in));
105 addr.sin_family = AF_INET;
106 addr.sin_addr.s_addr = inet_addr(srcIp);
107 return IpAddrAnonymousFormat(dstIp, dstLen, (struct sockaddr *)&addr, sizeof(addr));
108 }
109
CheckAnonymizeJsonData(cJSON * data,const char * const jsonKey)110 static cJSON *CheckAnonymizeJsonData(cJSON *data, const char * const jsonKey)
111 {
112 cJSON *item = cJSON_GetObjectItemCaseSensitive(data, jsonKey);
113 if (item == NULL) {
114 DFINDER_LOGE(TAG, "can not get json data with passed key");
115 return NULL;
116 }
117 if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
118 DFINDER_LOGE(TAG, "invalid json data with passed key");
119 return NULL;
120 }
121 return item;
122 }
123
GetAnonymizedDeviceId(char * srcStr,char * dstStr,size_t dstLen)124 static int32_t GetAnonymizedDeviceId(char *srcStr, char *dstStr, size_t dstLen)
125 {
126 size_t lenFlag = strlen(srcStr) / DFINDER_MGT_UUID_LEN;
127 size_t len = (lenFlag > 0) ? DFINDER_MGT_UUID_LEN : strlen(srcStr);
128 int ret = 0;
129 uint32_t wroteLen = 0;
130 DUMP_MSG_ADD_CHECK(ret, dstStr, wroteLen, dstLen, "%.*s******", len, srcStr);
131 return NSTACKX_EOK;
132 }
133
AnonymizeDeviceIdJsonData(cJSON * data)134 static int32_t AnonymizeDeviceIdJsonData(cJSON *data)
135 {
136 cJSON *item = CheckAnonymizeJsonData(data, JSON_DEVICE_ID);
137 if (item == NULL) {
138 return NSTACKX_EFAILED;
139 }
140 char anonyDevId[NSTACKX_MAX_DEVICE_ID_LEN] = {0};
141 if (GetAnonymizedDeviceId(item->valuestring, anonyDevId, sizeof(anonyDevId)) != NSTACKX_EOK) {
142 DFINDER_LOGE(TAG, "get anonymize device id failed");
143 return NSTACKX_EFAILED;
144 }
145 if (!cJSON_ReplaceItemInObjectCaseSensitive(data, JSON_DEVICE_ID, cJSON_CreateString(anonyDevId))) {
146 DFINDER_LOGE(TAG, "replace device id in json failed");
147 return NSTACKX_EFAILED;
148 }
149 return NSTACKX_EOK;
150 }
151
AnonymizeIpJsonData(cJSON * data)152 static int32_t AnonymizeIpJsonData(cJSON *data)
153 {
154 cJSON *item = CheckAnonymizeJsonData(data, JSON_DEVICE_WLAN_IP);
155 if (item == NULL) {
156 return NSTACKX_EFAILED;
157 }
158 char ipStr[NSTACKX_MAX_IP_STRING_LEN] = {0};
159 int ret = GetAnonymizedIp(ipStr, sizeof(ipStr), item->valuestring);
160 if (ret < 0) {
161 DFINDER_LOGE(TAG, "get anonymized ip failed");
162 return NSTACKX_EFAILED;
163 }
164 if (!cJSON_ReplaceItemInObjectCaseSensitive(data, JSON_DEVICE_WLAN_IP, cJSON_CreateString(ipStr))) {
165 DFINDER_LOGE(TAG, "replace device wlan ip in json failed");
166 return NSTACKX_EFAILED;
167 }
168 return NSTACKX_EOK;
169 }
170
CheckJsonTypeFiled(cJSON * data,const char * const typeFiled)171 static cJSON *CheckJsonTypeFiled(cJSON *data, const char * const typeFiled)
172 {
173 cJSON *item = cJSON_GetObjectItemCaseSensitive(data, typeFiled);
174 if (item == NULL) {
175 DFINDER_LOGE(TAG, "can not get json data with passed filed");
176 return NULL;
177 }
178 if (!cJSON_IsNumber(item) || (item->valuedouble) < 0) {
179 DFINDER_LOGE(TAG, "invalid json data with passed filed");
180 return NULL;
181 }
182 return item;
183 }
184
UpdateJsonTypeFiled(cJSON * data,const char * const typeFiled,const char * newTypeStr)185 static int32_t UpdateJsonTypeFiled(cJSON *data, const char * const typeFiled, const char *newTypeStr)
186 {
187 cJSON_DeleteItemFromObjectCaseSensitive(data, typeFiled);
188 cJSON *item = cJSON_CreateString(newTypeStr);
189 if (item == NULL || !cJSON_AddItemToObject(data, typeFiled, item)) {
190 cJSON_Delete(item);
191 DFINDER_LOGE(TAG, "cjson create new type item failed");
192 return NSTACKX_EFAILED;
193 }
194 return NSTACKX_EOK;
195 }
196
BusinessTypeToJsonStr(cJSON * data)197 static int32_t BusinessTypeToJsonStr(cJSON *data)
198 {
199 cJSON *item = CheckJsonTypeFiled(data, JSON_BUSINESS_TYPE);
200 if (item == NULL) {
201 return NSTACKX_EFAILED;
202 }
203 char *businessTypeStr = GetBusinessTypeStr((uint8_t)item->valuedouble);
204 if (businessTypeStr == NULL) {
205 DFINDER_LOGE(TAG, "get business type str failed");
206 return NSTACKX_EFAILED;
207 }
208 return UpdateJsonTypeFiled(data, JSON_BUSINESS_TYPE, businessTypeStr);
209 }
210
ModeTypeToJsonStr(cJSON * data)211 static int32_t ModeTypeToJsonStr(cJSON *data)
212 {
213 cJSON *item = CheckJsonTypeFiled(data, JSON_REQUEST_MODE);
214 if (item == NULL) {
215 return NSTACKX_EFAILED;
216 }
217 char *modeTypeStr = GetModeTypeStr((uint8_t)item->valuedouble);
218 if (modeTypeStr == NULL) {
219 DFINDER_LOGE(TAG, "get mode type str failed");
220 return NSTACKX_EFAILED;
221 }
222 return UpdateJsonTypeFiled(data, JSON_REQUEST_MODE, modeTypeStr);
223 }
224
ParseCoapRequestData(const char * reqData,size_t dataLen)225 static char *ParseCoapRequestData(const char *reqData, size_t dataLen)
226 {
227 if (reqData == NULL || dataLen == 0) {
228 DFINDER_LOGE(TAG, "illegal coap request data");
229 return NULL;
230 }
231 char *dupReqData = (char *)malloc(dataLen);
232 if (dupReqData == NULL) {
233 DFINDER_LOGE(TAG, "malloc for duplicate request data failed");
234 return NULL;
235 }
236 (void)memcpy_s(dupReqData, dataLen, reqData, dataLen);
237 char *formatString = NULL;
238 cJSON *data = cJSON_Parse(dupReqData);
239 if (data == NULL) {
240 DFINDER_LOGE(TAG, "cjson parse coap request data failed");
241 goto L_END_JSON;
242 }
243 RemoveCoapReqJsonData(data);
244 if (BusinessTypeToJsonStr(data) != NSTACKX_EOK) {
245 goto L_END_JSON;
246 }
247 if (ModeTypeToJsonStr(data) != NSTACKX_EOK) {
248 goto L_END_JSON;
249 }
250 if (AnonymizeDeviceIdJsonData(data) != NSTACKX_EOK) {
251 goto L_END_JSON;
252 }
253 if (AnonymizeIpJsonData(data) != NSTACKX_EOK) {
254 goto L_END_JSON;
255 }
256 formatString = cJSON_PrintUnformatted(data);
257 if (formatString == NULL) {
258 DFINDER_LOGE(TAG, "cjson print unformatted data failed");
259 goto L_END_JSON;
260 }
261 L_END_JSON:
262 cJSON_Delete(data);
263 free(dupReqData);
264 return formatString;
265 }
266
DFinderMgtReqLog(CoapRequest * coapRequest)267 void DFinderMgtReqLog(CoapRequest *coapRequest)
268 {
269 if (!g_mgtMsgLog) {
270 return;
271 }
272 char *coapReqData = ParseCoapRequestData(coapRequest->data, coapRequest->dataLength);
273 if (coapReqData == NULL) {
274 DFINDER_LOGE(TAG, "parse coap request data failed");
275 return;
276 }
277 DFINDER_LOGI(TAG, "coap msg type: %s, coap req data: %s", GetCoapReqTypeStr(coapRequest->type), coapReqData);
278 cJSON_free(coapReqData);
279 }
280
UnpackLogToStr(DeviceInfo * dev,char * msg,uint32_t size)281 static int32_t UnpackLogToStr(DeviceInfo *dev, char *msg, uint32_t size)
282 {
283 char ip[NSTACKX_MAX_IP_STRING_LEN] = {0};
284 if (inet_ntop(AF_INET, &(dev->netChannelInfo.wifiApInfo.ip), ip, sizeof(ip)) == NULL) {
285 DFINDER_LOGE(TAG, "convert ip struct failed");
286 return NSTACKX_EFAILED;
287 }
288 char ipStr[NSTACKX_MAX_IP_STRING_LEN] = {0};
289 if (GetAnonymizedIp(ipStr, sizeof(ipStr), ip) < 0) {
290 DFINDER_LOGE(TAG, "get anonymized ip failed");
291 return NSTACKX_EFAILED;
292 }
293 char anonyDevId[NSTACKX_MAX_DEVICE_ID_LEN] = {0};
294 if (GetAnonymizedDeviceId(dev->deviceId, anonyDevId, sizeof(anonyDevId)) != NSTACKX_EOK) {
295 DFINDER_LOGE(TAG, "get anonymize device id failed");
296 return NSTACKX_EFAILED;
297 }
298
299 uint32_t wroteLen = 0;
300 int ret = 0;
301 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "deviceId: %s ", anonyDevId);
302 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "devicename: %s, ", dev->deviceName);
303 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "type: %u, ", dev->deviceType);
304 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "hicomversion: %s, ", dev->version);
305 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "mode: %s, ", GetModeTypeStr(dev->mode));
306 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size,
307 "bType: %s, ", GetBusinessTypeStr(dev->businessType));
308 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "wlanIp: %s, ", ipStr);
309 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size,
310 "bcast: %hhu, ", dev->businessData.isBroadcast);
311 for (uint32_t i = 0; i < dev->capabilityBitmapNum; ++i) {
312 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size,
313 "cap[%u]:%u, ", i, dev->capabilityBitmap[i]);
314 }
315 DFINDER_LOGI(TAG, "%s", msg);
316 return NSTACKX_EOK;
317 }
318
DFinderMgtUnpackLog(DeviceInfo * dev)319 void DFinderMgtUnpackLog(DeviceInfo *dev)
320 {
321 if (!g_mgtMsgLog) {
322 return;
323 }
324
325 if (dev == NULL) {
326 DFINDER_LOGE(TAG, "invalid deviceInfo");
327 return;
328 }
329
330 char *msg = (char *)malloc(DFINDER_MGT_UNPACK_LOG_LEN);
331 if (msg == NULL) {
332 DFINDER_LOGE(TAG, "malloc failed");
333 return;
334 }
335 (void)memset_s(msg, DFINDER_MGT_UNPACK_LOG_LEN, 0, DFINDER_MGT_UNPACK_LOG_LEN);
336 if (UnpackLogToStr(dev, msg, DFINDER_MGT_UNPACK_LOG_LEN) != NSTACKX_EOK) {
337 DFINDER_LOGE(TAG, "unpack log to string failed");
338 }
339 free(msg);
340 }
341 #endif /* END OF DFINDER_MGT_MSG_LOG */
342