• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "json_payload.h"
17 #include <securec.h>
18 
19 #include "cJSON.h"
20 #ifndef DFINDER_USE_MINI_NSTACKX
21 #include "coap_client.h"
22 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
23 #include "nstackx_dfinder_log.h"
24 #include "nstackx_dfinder_mgt_msg_log.h"
25 #include "nstackx_error.h"
26 #include "nstackx_device.h"
27 #include "nstackx_statistics.h"
28 #include "nstackx_device_local.h"
29 #include "nstackx_inet.h"
30 
31 #define TAG "nStackXCoAP"
32 
33 static const int DEVICE_TYPE_DEFAULT = 0;
34 
AddDeviceType(cJSON * data,const DeviceInfo * deviceInfo)35 static int32_t AddDeviceType(cJSON *data, const DeviceInfo *deviceInfo)
36 {
37     cJSON *item = NULL;
38 
39     if (deviceInfo->deviceType <= UINT8_MAX) {
40         item = cJSON_CreateNumber(deviceInfo->deviceType);
41         if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_TYPE, item)) {
42             cJSON_Delete(item);
43             return NSTACKX_EFAILED;
44         }
45     } else {
46         item = cJSON_CreateNumber(DEVICE_TYPE_DEFAULT);
47         if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_TYPE, item)) {
48             cJSON_Delete(item);
49             return NSTACKX_EFAILED;
50         }
51         item = cJSON_CreateNumber(deviceInfo->deviceType);
52         if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_TYPE_EXTERN, item)) {
53             cJSON_Delete(item);
54             return NSTACKX_EFAILED;
55         }
56     }
57 
58     return NSTACKX_EOK;
59 }
60 
AddServiceData(cJSON * data,const char * str,const char * realStr)61 static int32_t AddServiceData(cJSON *data, const char *str, const char *realStr)
62 {
63     const char *ptr = (realStr == NULL || strlen(realStr) == 0) ? str : realStr;
64     cJSON *item = cJSON_CreateString(ptr);
65     if (item == NULL || !cJSON_AddItemToObject(data, JSON_SERVICE_DATA, item)) {
66         cJSON_Delete(item);
67         DFINDER_LOGE(TAG, "cJSON_CreateString for serviceData failed");
68         return NSTACKX_EFAILED;
69     }
70 
71     return NSTACKX_EOK;
72 }
73 
AddDeviceJsonData(cJSON * data,const DeviceInfo * deviceInfo,const char * serviceData)74 static int32_t AddDeviceJsonData(cJSON *data, const DeviceInfo *deviceInfo, const char *serviceData)
75 {
76     cJSON *item = cJSON_CreateString(deviceInfo->deviceId);
77     if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_ID, item)) {
78         cJSON_Delete(item);
79         return NSTACKX_EFAILED;
80     }
81 
82     item = cJSON_CreateString(deviceInfo->deviceName);
83     if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_NAME, item)) {
84         cJSON_Delete(item);
85         return NSTACKX_EFAILED;
86     }
87 
88     if (AddDeviceType(data, deviceInfo) != NSTACKX_EOK) {
89         return NSTACKX_EFAILED;
90     }
91 
92     item = cJSON_CreateNumber(deviceInfo->mode);
93     if (item == NULL || !cJSON_AddItemToObject(data, JSON_REQUEST_MODE, item)) {
94         cJSON_Delete(item);
95         return NSTACKX_EFAILED;
96     }
97 
98     item = cJSON_CreateString(deviceInfo->deviceHash);
99     if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_HASH, item)) {
100         cJSON_Delete(item);
101         return NSTACKX_EFAILED;
102     }
103 
104     if (AddServiceData(data, deviceInfo->serviceData, serviceData) != NSTACKX_EOK) {
105         cJSON_Delete(item);
106         return NSTACKX_EFAILED;
107     }
108 
109 #ifndef DFINDER_USE_MINI_NSTACKX
110     item = cJSON_CreateString(deviceInfo->extendServiceData);
111     if (item == NULL || !cJSON_AddItemToObject(data, JSON_EXTEND_SERVICE_DATA, item)) {
112         cJSON_Delete(item);
113         DFINDER_LOGE(TAG, "cJSON_CreateString for extendServiceData failed");
114         return NSTACKX_EFAILED;
115     }
116 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
117 
118     return NSTACKX_EOK;
119 }
120 
AddCapabilityBitmap(cJSON * data,const DeviceInfo * deviceInfo)121 static int32_t AddCapabilityBitmap(cJSON *data, const DeviceInfo *deviceInfo)
122 {
123     cJSON *capabilityArray = NULL;
124     cJSON *capability = NULL;
125     uint32_t i;
126 
127     if (deviceInfo->capabilityBitmapNum == 0) {
128         return NSTACKX_EOK;
129     }
130 
131     capabilityArray = cJSON_CreateArray();
132     if (capabilityArray == NULL) {
133         goto L_END_JSON;
134     }
135 
136     for (i = 0; i < deviceInfo->capabilityBitmapNum; i++) {
137         capability = cJSON_CreateNumber(deviceInfo->capabilityBitmap[i]);
138         if (capability == NULL || !cJSON_AddItemToArray(capabilityArray, capability)) {
139             cJSON_Delete(capability);
140             goto L_END_JSON;
141         }
142     }
143     if (!cJSON_AddItemToObject(data, JSON_CAPABILITY_BITMAP, capabilityArray)) {
144         goto L_END_JSON;
145     }
146 
147     return NSTACKX_EOK;
148 
149 L_END_JSON:
150     cJSON_Delete(capabilityArray);
151     return NSTACKX_EFAILED;
152 }
153 
AddBusinessJsonData(cJSON * data,const DeviceInfo * deviceInfo,uint8_t isBroadcast,uint8_t businessType)154 static int32_t AddBusinessJsonData(cJSON *data, const DeviceInfo *deviceInfo, uint8_t isBroadcast, uint8_t businessType)
155 {
156     uint8_t tmpType = (isBroadcast) ? deviceInfo->businessType : businessType;
157     cJSON *item = cJSON_CreateNumber(tmpType);
158     if (item == NULL || !cJSON_AddItemToObject(data, JSON_BUSINESS_TYPE, item)) {
159         cJSON_Delete(item);
160         DFINDER_LOGE(TAG, "cJSON_CreateString for businessType failed");
161         return NSTACKX_EFAILED;
162     }
163     if (isBroadcast) {
164         item = cJSON_CreateString(deviceInfo->businessData.businessDataBroadcast);
165     } else {
166         item = cJSON_CreateString(deviceInfo->businessData.businessDataUnicast);
167     }
168     if (item == NULL || !cJSON_AddItemToObject(data, JSON_BUSINESS_DATA, item)) {
169         cJSON_Delete(item);
170         DFINDER_LOGE(TAG, "cJSON_CreateString for businessData failed");
171         return NSTACKX_EFAILED;
172     }
173 
174     return NSTACKX_EOK;
175 }
176 
AddSequenceNumber(cJSON * data,uint8_t af,uint8_t sendBcast)177 static int32_t AddSequenceNumber(cJSON *data, uint8_t af, uint8_t sendBcast)
178 {
179     cJSON *item = cJSON_CreateNumber(GetSequenceNumber(af, sendBcast));
180     if (item == NULL || !cJSON_AddItemToObject(data, JSON_SEQUENCE_NUMBER, item)) {
181         cJSON_Delete(item);
182         DFINDER_LOGE(TAG, "cJSON_CreateNumber for sequence number failed");
183         return NSTACKX_EFAILED;
184     }
185     return NSTACKX_EOK;
186 }
187 
ParseDeviceJsonData(const cJSON * data,DeviceInfo * dev)188 static int32_t ParseDeviceJsonData(const cJSON *data, DeviceInfo *dev)
189 {
190     cJSON *item = NULL;
191 
192     item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_ID);
193     if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
194         DFINDER_LOGE(TAG, "Cannot find device ID or invalid device ID");
195         return NSTACKX_EINVAL;
196     }
197     if (strcpy_s(dev->deviceId, sizeof(dev->deviceId), item->valuestring) != EOK) {
198         return NSTACKX_EFAILED;
199     }
200 
201     item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_NAME);
202     if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
203         DFINDER_LOGE(TAG, "Cannot find device name or invalid device name");
204         return NSTACKX_EINVAL;
205     }
206     if (strcpy_s(dev->deviceName, sizeof(dev->deviceName), item->valuestring) != EOK) {
207         return NSTACKX_EFAILED;
208     }
209 
210     item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_TYPE);
211     if (!cJSON_IsNumber(item) || (item->valuedouble < 0) || (item->valuedouble > 0xFF)) {
212         DFINDER_LOGE(TAG, "Cannot find device type or invalid device type");
213         return NSTACKX_EINVAL;
214     }
215     dev->deviceType = (uint32_t)item->valuedouble;
216     if (dev->deviceType == DEVICE_TYPE_DEFAULT) {
217         item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_TYPE_EXTERN);
218         if (!cJSON_IsNumber(item) || (item->valuedouble < 0) || (item->valuedouble > UINT32_MAX)) {
219             DFINDER_LOGI(TAG, "Cannot find device type or invalid device type extern");
220         } else {
221             dev->deviceType = (uint32_t)item->valuedouble;
222         }
223     }
224 
225     return NSTACKX_EOK;
226 }
227 
ParseWifiApJsonData(const cJSON * data,DeviceInfo * dev)228 static void ParseWifiApJsonData(const cJSON *data, DeviceInfo *dev)
229 {
230     cJSON *item = NULL;
231 
232     item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_WLAN_IP);
233     if (item != NULL && cJSON_IsString(item)) {
234         uint8_t af = InetGetAfType(item->valuestring, &(dev->netChannelInfo.wifiApInfo.addr));
235         if (af == AF_ERROR) {
236             DFINDER_LOGW(TAG, "Invalid ip address");
237         } else {
238             dev->netChannelInfo.wifiApInfo.af = af;
239             dev->netChannelInfo.wifiApInfo.state = NET_CHANNEL_STATE_CONNETED;
240         }
241     }
242 }
243 
ParseModeJsonData(const cJSON * data,DeviceInfo * dev)244 static void ParseModeJsonData(const cJSON *data, DeviceInfo *dev)
245 {
246     cJSON *item = NULL;
247     item = cJSON_GetObjectItemCaseSensitive(data, JSON_REQUEST_MODE);
248     if (item == NULL) {
249         DFINDER_LOGE(TAG, "Cannot get mode json");
250         return;
251     }
252     if (!cJSON_IsNumber(item) || (item->valuedouble < 0)) {
253         DFINDER_LOGE(TAG, "Cannot find mode or invalid mode");
254     } else {
255         if (dev == NULL) {
256             DFINDER_LOGE(TAG, "device info is null");
257             return;
258         }
259         dev->mode = (uint8_t)item->valuedouble;
260     }
261 }
262 
ParseDeviceHashData(const cJSON * data,DeviceInfo * dev)263 static void ParseDeviceHashData(const cJSON *data, DeviceInfo *dev)
264 {
265     cJSON *item = NULL;
266     item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_HASH);
267     if (item == NULL) {
268         DFINDER_LOGD(TAG, "Cannot get hash json");
269         return;
270     }
271     if (item->valuestring == NULL) {
272         DFINDER_LOGD(TAG, "Cannot get valuestring");
273         return;
274     }
275     if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
276         DFINDER_LOGD(TAG, "Cannot find device hash or invalid hash");
277         return;
278     }
279     if (strcpy_s(dev->deviceHash, sizeof(dev->deviceHash), item->valuestring) != EOK) {
280         DFINDER_LOGE(TAG, "parse device hash data error");
281         return;
282     }
283 }
284 
ParseServiceDataJsonData(const cJSON * data,DeviceInfo * dev)285 static void ParseServiceDataJsonData(const cJSON *data, DeviceInfo *dev)
286 {
287     cJSON *item = NULL;
288     item = cJSON_GetObjectItemCaseSensitive(data, JSON_SERVICE_DATA);
289     if (item == NULL) {
290         DFINDER_LOGE(TAG, "Cannot get service data");
291         return;
292     }
293     if (!cJSON_IsString(item)) {
294         DFINDER_LOGE(TAG, "Cannot find serviceData");
295         return;
296     }
297     if (item->valuestring == NULL) {
298         DFINDER_LOGE(TAG, "item->valuestring is null");
299         return;
300     }
301     if (strcpy_s(dev->serviceData, sizeof(dev->serviceData), item->valuestring)) {
302         DFINDER_LOGE(TAG, "parse device serviceData error");
303         return;
304     }
305 }
306 
307 #ifndef DFINDER_USE_MINI_NSTACKX
ParseExtendServiceDataJsonData(const cJSON * data,DeviceInfo * dev)308 static void ParseExtendServiceDataJsonData(const cJSON *data, DeviceInfo *dev)
309 {
310     cJSON *item = NULL;
311     item = cJSON_GetObjectItemCaseSensitive(data, JSON_EXTEND_SERVICE_DATA);
312     if (item == NULL) {
313         DFINDER_LOGD(TAG, "Cannot get service data");
314         return;
315     }
316     if (!cJSON_IsString(item)) {
317         DFINDER_LOGD(TAG, "Cannot find extendServiceData");
318         return;
319     }
320     if (item->valuestring == NULL) {
321         DFINDER_LOGD(TAG, "item->valuestring is null");
322         return;
323     }
324     if (strcpy_s(dev->extendServiceData, sizeof(dev->extendServiceData), item->valuestring)) {
325         DFINDER_LOGD(TAG, "parse device extendServiceData error");
326         return;
327     }
328 }
329 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
330 
ParseCapabilityBitmap(const cJSON * data,DeviceInfo * deviceInfo)331 static void ParseCapabilityBitmap(const cJSON *data, DeviceInfo *deviceInfo)
332 {
333     cJSON *capability = NULL;
334     cJSON *item = NULL;
335     uint32_t capabilityBitmapNum = 0;
336 
337     item = cJSON_GetObjectItemCaseSensitive(data, JSON_CAPABILITY_BITMAP);
338     if (cJSON_IsArray(item)) {
339         cJSON_ArrayForEach(capability, item) {
340             if (capabilityBitmapNum >= NSTACKX_MAX_CAPABILITY_NUM) {
341                 break;
342             }
343 
344             if (!cJSON_IsNumber(capability) ||
345                 capability->valuedouble < 0 ||
346                 capability->valuedouble > 0xFFFFFFFF) {
347                 /* skip invalid capability */
348                 continue;
349             }
350             deviceInfo->capabilityBitmap[capabilityBitmapNum++] = (uint32_t)capability->valuedouble;
351         }
352     }
353     deviceInfo->capabilityBitmapNum = capabilityBitmapNum;
354 }
355 
ParseBusinessType(const cJSON * data,DeviceInfo * dev)356 static void ParseBusinessType(const cJSON *data, DeviceInfo *dev)
357 {
358     cJSON *item = NULL;
359     item = cJSON_GetObjectItemCaseSensitive(data, JSON_BUSINESS_TYPE);
360     if (item == NULL) {
361         dev->businessType = NSTACKX_BUSINESS_TYPE_NULL;
362         DFINDER_LOGD(TAG, "Cannot get businessType json");
363         return;
364     }
365     if (!cJSON_IsNumber(item) || (item->valuedouble < 0)) {
366         dev->businessType = NSTACKX_BUSINESS_TYPE_NULL;
367         DFINDER_LOGE(TAG, "Cannot find businessType or invalid Type");
368     } else {
369         dev->businessType = (uint8_t)item->valuedouble;
370     }
371 }
372 
ParseBusinessDataJsonData(const cJSON * data,DeviceInfo * dev,uint8_t isBroadcast)373 static void ParseBusinessDataJsonData(const cJSON *data, DeviceInfo *dev, uint8_t isBroadcast)
374 {
375     cJSON *item = NULL;
376     item = cJSON_GetObjectItemCaseSensitive(data, JSON_BUSINESS_DATA);
377     if (item == NULL) {
378         DFINDER_LOGD(TAG, "Cannot get businessData json");
379         return;
380     }
381     if (!cJSON_IsString(item)) {
382         DFINDER_LOGE(TAG, "Cannot find businessData");
383         return;
384     }
385     if (isBroadcast == NSTACKX_TRUE) {
386         if (strcpy_s(dev->businessData.businessDataBroadcast,
387             sizeof(dev->businessData.businessDataBroadcast), item->valuestring)) {
388             DFINDER_LOGE(TAG, "parse device businessData error");
389             return;
390         }
391     } else {
392         if (strcpy_s(dev->businessData.businessDataUnicast,
393             sizeof(dev->businessData.businessDataUnicast), item->valuestring)) {
394             DFINDER_LOGE(TAG, "parse device businessData error");
395             return;
396         }
397     }
398 }
399 
ParseSequenceNumber(const cJSON * data,DeviceInfo * dev,uint8_t isBroadcast)400 static void ParseSequenceNumber(const cJSON *data, DeviceInfo *dev, uint8_t isBroadcast)
401 {
402     cJSON *item = cJSON_GetObjectItemCaseSensitive(data, JSON_SEQUENCE_NUMBER);
403     if (item == NULL) {
404         dev->seq.seqType = DFINDER_SEQ_TYPE_NONE;
405         return;
406     }
407     if (!cJSON_IsNumber(item) || (item->valueint < 0) || (item->valueint > UINT16_MAX)) {
408         DFINDER_LOGE(TAG, "invalid sequence number");
409         return;
410     }
411     dev->seq.seqType = isBroadcast == NSTACKX_TRUE ? DFINDER_SEQ_TYPE_BCAST : DFINDER_SEQ_TYPE_UNICAST;
412     if (isBroadcast == NSTACKX_TRUE) {
413         dev->seq.seqBcast = (uint16_t)item->valueint;
414     } else {
415         dev->seq.seqUcast = (uint16_t)item->valueint;
416     }
417 }
418 
JsonAddStr(cJSON * data,const char * key,const char * value)419 static int JsonAddStr(cJSON *data, const char *key, const char *value)
420 {
421     cJSON *item = cJSON_CreateString(value);
422     if (item == NULL || !cJSON_AddItemToObject(data, key, item)) {
423         cJSON_Delete(item);
424         return NSTACKX_EFAILED;
425     }
426 
427     return NSTACKX_EOK;
428 }
429 
PrepareServiceDiscoverEx(uint8_t af,const char * locaIpStr,uint8_t isBroadcast,uint8_t businessType,const char * serviceData)430 static char *PrepareServiceDiscoverEx(uint8_t af, const char *locaIpStr, uint8_t isBroadcast, uint8_t businessType,
431     const char *serviceData)
432 {
433     cJSON *data = cJSON_CreateObject();
434     if (data == NULL) {
435         DFINDER_LOGE(TAG, "cJSON_CreateObject failed");
436         return NULL;
437     }
438 
439     char *formatString = NULL;
440     const DeviceInfo *deviceInfo = GetLocalDeviceInfo();
441     if ((AddDeviceJsonData(data, deviceInfo, serviceData) != NSTACKX_EOK) ||
442         (JsonAddStr(data, JSON_DEVICE_WLAN_IP, locaIpStr) != NSTACKX_EOK) ||
443         (AddCapabilityBitmap(data, deviceInfo) != NSTACKX_EOK) ||
444         (AddBusinessJsonData(data, deviceInfo, isBroadcast, businessType) != NSTACKX_EOK) ||
445         (AddSequenceNumber(data, af, isBroadcast) != NSTACKX_EOK)) {
446         DFINDER_LOGE(TAG, "Add json data failed");
447         goto L_END_JSON;
448     }
449 
450     if (isBroadcast) {
451         char coapUriBuffer[NSTACKX_MAX_URI_BUFFER_LENGTH] = {0};
452         if (af == AF_INET &&
453             sprintf_s(coapUriBuffer, sizeof(coapUriBuffer), "coap://%s/" COAP_DEVICE_DISCOVER_URI, locaIpStr) < 0) {
454             DFINDER_LOGE(TAG, "format coap device discover uri failed");
455             goto L_END_JSON;
456         }
457         if (af == AF_INET6 && sprintf_s(coapUriBuffer, sizeof(coapUriBuffer),
458             "coap://[%s]/" COAP_DEVICE_DISCOVER_URI, locaIpStr) < 0) {
459             DFINDER_LOGE(TAG, "format coap device discover uri failed");
460             goto L_END_JSON;
461         }
462 
463         cJSON *localCoapString = cJSON_CreateString(coapUriBuffer);
464         if (localCoapString == NULL || !cJSON_AddItemToObject(data, JSON_COAP_URI, localCoapString)) {
465             cJSON_Delete(localCoapString);
466             DFINDER_LOGE(TAG, "cJSON_CreateString return null or cJSON_AddItemToObject failed");
467             goto L_END_JSON;
468         }
469     }
470 
471     formatString = cJSON_PrintUnformatted(data);
472     if (formatString == NULL) {
473         DFINDER_LOGE(TAG, "cJSON_PrintUnformatted return null");
474     }
475 
476 L_END_JSON:
477     cJSON_Delete(data);
478     return formatString;
479 }
480 
PrepareServiceDiscover(uint8_t af,const char * localIpStr,uint8_t isBroadcast,uint8_t businessType,const char * serviceData)481 char *PrepareServiceDiscover(uint8_t af, const char *localIpStr, uint8_t isBroadcast, uint8_t businessType,
482     const char *serviceData)
483 {
484     char *str = PrepareServiceDiscoverEx(af, localIpStr, isBroadcast, businessType, serviceData);
485     if (str == NULL) {
486         DFINDER_LOGE(TAG, "prepare service discover ex failed");
487         IncStatistics(STATS_PREPARE_SD_MSG_FAILED);
488     }
489     return str;
490 }
491 
ParseServiceDiscoverEx(const uint8_t * buf,DeviceInfo * deviceInfo,char ** remoteUrlPtr)492 static int32_t ParseServiceDiscoverEx(const uint8_t *buf, DeviceInfo *deviceInfo, char **remoteUrlPtr)
493 {
494     char *remoteUrl = NULL;
495     cJSON *data = NULL;
496     cJSON *item = NULL;
497     uint8_t isBroadcast = NSTACKX_FALSE;
498 
499     if (buf == NULL || deviceInfo == NULL || remoteUrlPtr == NULL) {
500         DFINDER_LOGE(TAG, "invalid params passed in");
501         return NSTACKX_EINVAL;
502     }
503 
504     data = cJSON_Parse((char *)buf);
505     if (data == NULL) {
506         DFINDER_LOGE(TAG, "cJSON_Parse buf return null");
507         return NSTACKX_EINVAL;
508     }
509 
510     if (ParseDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) {
511         cJSON_Delete(data);
512         return NSTACKX_EINVAL;
513     }
514 
515     ParseWifiApJsonData(data, deviceInfo);
516     ParseCapabilityBitmap(data, deviceInfo);
517     ParseModeJsonData(data, deviceInfo);
518     ParseDeviceHashData(data, deviceInfo);
519     ParseServiceDataJsonData(data, deviceInfo);
520 #ifndef DFINDER_USE_MINI_NSTACKX
521     ParseExtendServiceDataJsonData(data, deviceInfo);
522 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
523     ParseBusinessType(data, deviceInfo);
524 
525     item = cJSON_GetObjectItemCaseSensitive(data, JSON_COAP_URI);
526     if (item != NULL) {
527         isBroadcast = NSTACKX_TRUE;
528         if (cJSON_IsString(item)) {
529             DFINDER_LOGD(TAG, "new device join");
530             remoteUrl = strdup(item->valuestring);
531             if (remoteUrl == NULL) {
532                 DFINDER_LOGE(TAG, "remoteUrl strdup fail");
533                 cJSON_Delete(data);
534                 return NSTACKX_ENOMEM;
535             }
536         }
537     }
538     ParseBusinessDataJsonData(data, deviceInfo, isBroadcast);
539     deviceInfo->businessData.isBroadcast = isBroadcast;
540     ParseSequenceNumber(data, deviceInfo, isBroadcast);
541     *remoteUrlPtr = remoteUrl;
542     cJSON_Delete(data);
543     DFINDER_MGT_UNPACK_LOG(deviceInfo);
544     return NSTACKX_EOK;
545 }
546 
ParseServiceDiscover(const uint8_t * buf,struct DeviceInfo * deviceInfo,char ** remoteUrlPtr)547 int32_t ParseServiceDiscover(const uint8_t *buf, struct DeviceInfo *deviceInfo, char **remoteUrlPtr)
548 {
549     int32_t ret = ParseServiceDiscoverEx(buf, deviceInfo, remoteUrlPtr);
550     if (ret != NSTACKX_EOK) {
551         IncStatistics(STATS_PARSE_SD_MSG_FAILED);
552     }
553     return ret;
554 }
555 
PrepareServiceNotificationEx(void)556 static char *PrepareServiceNotificationEx(void)
557 {
558     cJSON *data = cJSON_CreateObject();
559     if (data == NULL) {
560         DFINDER_LOGE(TAG, "cJSON_CreateObject failed");
561         return NULL;
562     }
563     const DeviceInfo *deviceInfo = GetLocalDeviceInfo();
564     if (JsonAddStr(data, JSON_NOTIFICATION, deviceInfo->notification) != NSTACKX_EOK) {
565         DFINDER_LOGE(TAG, "add json data: %s fail", JSON_NOTIFICATION);
566         cJSON_Delete(data);
567         return NULL;
568     }
569     char *formatString = cJSON_PrintUnformatted(data);
570     if (formatString == NULL) {
571         DFINDER_LOGE(TAG, "cJSON_PrintUnformatted return null");
572     }
573     cJSON_Delete(data);
574     return formatString;
575 }
576 
PrepareServiceNotification(void)577 char *PrepareServiceNotification(void)
578 {
579     char *str = PrepareServiceNotificationEx();
580     if (str == NULL) {
581         IncStatistics(STATS_PREPARE_SN_MSG_FAILED);
582     }
583     return str;
584 }
585 
ParseServiceNotification(const uint8_t * buf,NSTACKX_NotificationConfig * config)586 int32_t ParseServiceNotification(const uint8_t *buf, NSTACKX_NotificationConfig *config)
587 {
588     if (buf == NULL || config == NULL) {
589         DFINDER_LOGE(TAG, "buf or notification config is null");
590         return NSTACKX_EINVAL;
591     }
592     cJSON *data = cJSON_Parse((char *)buf);
593     if (data == NULL) {
594         DFINDER_LOGE(TAG, "cJSON_Parse buf fail");
595         return NSTACKX_EINVAL;
596     }
597     cJSON *item = cJSON_GetObjectItemCaseSensitive(data, JSON_NOTIFICATION);
598     if (item == NULL) {
599         DFINDER_LOGE(TAG, "can not get service notification");
600         goto LERR;
601     }
602     if (!cJSON_IsString(item)) {
603         DFINDER_LOGE(TAG, "json notification data not in string format");
604         goto LERR;
605     }
606     if (item->valuestring == NULL || strlen(item->valuestring) > NSTACKX_MAX_NOTIFICATION_DATA_LEN - 1) {
607         DFINDER_LOGE(TAG, "parsed out illegal notification data len");
608         goto LERR;
609     }
610     config->msgLen = strlen(item->valuestring);
611     if (strcpy_s(config->msg, NSTACKX_MAX_NOTIFICATION_DATA_LEN, item->valuestring) != EOK) {
612         DFINDER_LOGE(TAG, "copy notification fail");
613         goto LERR;
614     }
615     cJSON_Delete(data);
616     return NSTACKX_EOK;
617 LERR:
618     cJSON_Delete(data);
619     return NSTACKX_EFAILED;
620 }
621