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