• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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