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