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 "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 int lenFlag = strlen(srcStr) / DFINDER_MGT_UUID_LEN;
127 int len = (lenFlag > 0) ? DFINDER_MGT_UUID_LEN : strlen(srcStr);
128 int ret = 0;
129 int 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 cJSON_ReplaceItemInObjectCaseSensitive(data, JSON_DEVICE_ID, cJSON_CreateString(anonyDevId));
146 return NSTACKX_EOK;
147 }
148
AnonymizeIpJsonData(cJSON * data)149 static int32_t AnonymizeIpJsonData(cJSON *data)
150 {
151 cJSON *item = CheckAnonymizeJsonData(data, JSON_DEVICE_WLAN_IP);
152 if (item == NULL) {
153 return NSTACKX_EFAILED;
154 }
155 char ipStr[NSTACKX_MAX_IP_STRING_LEN] = {0};
156 int ret = GetAnonymizedIp(ipStr, sizeof(ipStr), item->valuestring);
157 if (ret < 0) {
158 DFINDER_LOGE(TAG, "get anonymized ip failed");
159 return NSTACKX_EFAILED;
160 }
161 cJSON_ReplaceItemInObjectCaseSensitive(data, JSON_DEVICE_WLAN_IP, cJSON_CreateString(ipStr));
162 return NSTACKX_EOK;
163 }
164
CheckJsonTypeFiled(cJSON * data,const char * const typeFiled)165 static cJSON* CheckJsonTypeFiled(cJSON *data, const char * const typeFiled)
166 {
167 cJSON *item = cJSON_GetObjectItemCaseSensitive(data, typeFiled);
168 if (item == NULL) {
169 DFINDER_LOGE(TAG, "can not get json data with passed filed");
170 return NULL;
171 }
172 if (!cJSON_IsNumber(item) || (item->valuedouble) < 0) {
173 DFINDER_LOGE(TAG, "invalid json data with passed filed");
174 return NULL;
175 }
176 return item;
177 }
178
UpdateJsonTypeFiled(cJSON * data,const char * const typeFiled,const char * newTypeStr)179 static int32_t UpdateJsonTypeFiled(cJSON *data, const char * const typeFiled, const char *newTypeStr)
180 {
181 cJSON_DeleteItemFromObjectCaseSensitive(data, typeFiled);
182 cJSON *item = cJSON_CreateString(newTypeStr);
183 if (item == NULL || !cJSON_AddItemToObject(data, typeFiled, item)) {
184 cJSON_Delete(item);
185 DFINDER_LOGE(TAG, "cjson create new type item failed");
186 return NSTACKX_EFAILED;
187 }
188 return NSTACKX_EOK;
189 }
190
BusinessTypeToJsonStr(cJSON * data)191 static int32_t BusinessTypeToJsonStr(cJSON *data)
192 {
193 cJSON *item = CheckJsonTypeFiled(data, JSON_BUSINESS_TYPE);
194 if (item == NULL) {
195 return NSTACKX_EFAILED;
196 }
197 char *businessTypeStr = GetBusinessTypeStr((uint8_t)item->valuedouble);
198 if (businessTypeStr == NULL) {
199 DFINDER_LOGE(TAG, "get business type str failed");
200 return NSTACKX_EFAILED;
201 }
202 return UpdateJsonTypeFiled(data, JSON_BUSINESS_TYPE, businessTypeStr);
203 }
204
ModeTypeToJsonStr(cJSON * data)205 static int32_t ModeTypeToJsonStr(cJSON *data)
206 {
207 cJSON *item = CheckJsonTypeFiled(data, JSON_REQUEST_MODE);
208 if (item == NULL) {
209 return NSTACKX_EFAILED;
210 }
211 char *modeTypeStr = GetModeTypeStr((uint8_t)item->valuedouble);
212 if (modeTypeStr == NULL) {
213 DFINDER_LOGE(TAG, "get mode type str failed");
214 return NSTACKX_EFAILED;
215 }
216 return UpdateJsonTypeFiled(data, JSON_REQUEST_MODE, modeTypeStr);
217 }
218
ParseCoapRequestData(const char * reqData,size_t dataLen)219 static char *ParseCoapRequestData(const char *reqData, size_t dataLen)
220 {
221 if (reqData == NULL || dataLen == 0) {
222 DFINDER_LOGE(TAG, "illegal coap request data");
223 return NULL;
224 }
225 char *dupReqData = (char *)calloc(dataLen + 1, sizeof(char));
226 if (dupReqData == NULL) {
227 DFINDER_LOGE(TAG, "malloc for duplicate request data failed");
228 return NULL;
229 }
230 if (memcpy_s(dupReqData, dataLen + 1, reqData, dataLen) != EOK) {
231 DFINDER_LOGE(TAG, "memcpy for duplicate request data failed");
232 free(dupReqData);
233 return NULL;
234 }
235 char *formatString = NULL;
236 cJSON *data = cJSON_Parse(dupReqData);
237 if (data == NULL) {
238 DFINDER_LOGE(TAG, "cjson parse coap request data failed");
239 goto L_END_JSON;
240 }
241 RemoveCoapReqJsonData(data);
242 if (BusinessTypeToJsonStr(data) != NSTACKX_EOK) {
243 goto L_END_JSON;
244 }
245 if (ModeTypeToJsonStr(data) != NSTACKX_EOK) {
246 goto L_END_JSON;
247 }
248 if (AnonymizeDeviceIdJsonData(data) != NSTACKX_EOK) {
249 goto L_END_JSON;
250 }
251 if (AnonymizeIpJsonData(data) != NSTACKX_EOK) {
252 goto L_END_JSON;
253 }
254 formatString = cJSON_PrintUnformatted(data);
255 if (formatString == NULL) {
256 DFINDER_LOGE(TAG, "cjson print unformatted data failed");
257 goto L_END_JSON;
258 }
259 L_END_JSON:
260 cJSON_Delete(data);
261 free(dupReqData);
262 return formatString;
263 }
264
DFinderMgtReqLog(CoapRequest * coapRequest)265 void DFinderMgtReqLog(CoapRequest *coapRequest)
266 {
267 if (!g_mgtMsgLog) {
268 return;
269 }
270 char *coapReqData = ParseCoapRequestData(coapRequest->data, coapRequest->dataLength);
271 if (coapReqData == NULL) {
272 DFINDER_LOGE(TAG, "parse coap request data failed");
273 return;
274 }
275 DFINDER_LOGI(TAG, "coap msg type: %s, coap req data: %s", GetCoapReqTypeStr(coapRequest->type), coapReqData);
276 }
277
UnpackLogToStr(DeviceInfo * dev,char * msg,uint32_t size)278 static int32_t UnpackLogToStr(DeviceInfo *dev, char *msg, uint32_t size)
279 {
280 char ip[NSTACKX_MAX_IP_STRING_LEN] = {0};
281 if (inet_ntop(AF_INET, &(dev->netChannelInfo.wifiApInfo.ip), ip, sizeof(ip)) == NULL) {
282 DFINDER_LOGE(TAG, "convert ip struct failed");
283 return NSTACKX_EFAILED;
284 }
285 char ipStr[NSTACKX_MAX_IP_STRING_LEN] = {0};
286 if (GetAnonymizedIp(ipStr, sizeof(ipStr), ip) < 0) {
287 DFINDER_LOGE(TAG, "get anonymized ip failed");
288 return NSTACKX_EFAILED;
289 }
290 char anonyDevId[NSTACKX_MAX_DEVICE_ID_LEN] = {0};
291 if (GetAnonymizedDeviceId(dev->deviceId, anonyDevId, sizeof(anonyDevId)) != NSTACKX_EOK) {
292 DFINDER_LOGE(TAG, "get anonymize device id failed");
293 return NSTACKX_EFAILED;
294 }
295
296 int wroteLen = 0;
297 int ret = 0;
298 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "deviceId: %s ", anonyDevId);
299 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "devicename: %s, ", dev->deviceName);
300 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "type: %hhu, ", dev->deviceType);
301 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "hicomversion: %s, ", dev->version);
302 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "mode: %s, ", GetModeTypeStr(dev->mode));
303 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size,
304 "bType: %s, ", GetBusinessTypeStr(dev->businessType));
305 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size, "wlanIp: %s, ", ipStr);
306 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size,
307 "bcast: %hhu, ", dev->businessData.isBroadcast);
308 for (uint32_t i = 0; i < dev->capabilityBitmapNum; ++i) {
309 DUMP_MSG_ADD_CHECK(ret, msg, wroteLen, size,
310 "cap[%u]:%u, ", i, dev->capabilityBitmap[i]);
311 }
312 DFINDER_LOGI(TAG, "%s", msg);
313 return NSTACKX_EOK;
314 }
315
DFinderMgtUnpackLog(DeviceInfo * dev)316 void DFinderMgtUnpackLog(DeviceInfo *dev)
317 {
318 if (!g_mgtMsgLog) {
319 return;
320 }
321
322 char *msg = (char *)malloc(DFINDER_MGT_UNPACK_LOG_LEN);
323 if (msg == NULL) {
324 DFINDER_LOGE(TAG, "malloc failed");
325 return;
326 }
327 (void)memset_s(msg, DFINDER_MGT_UNPACK_LOG_LEN, 0, DFINDER_MGT_UNPACK_LOG_LEN);
328 if (UnpackLogToStr(dev, msg, DFINDER_MGT_UNPACK_LOG_LEN) != NSTACKX_EOK) {
329 DFINDER_LOGE(TAG, "unpack log to string failed");
330 }
331 free(msg);
332 }
333 #endif /* END OF DFINDER_MGT_MSG_LOG */
334