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