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