1 /*
2 * Copyright (c) 2023-2024 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 "disc_coap_parser.h"
17
18 #include "anonymizer.h"
19 #include "disc_log.h"
20 #include "securec.h"
21
22 #include "softbus_adapter_crypto.h"
23 #include "softbus_error_code.h"
24 #include "softbus_utils.h"
25
26 #define JSON_WLAN_IP "wifiIpAddr"
27 #define JSON_HW_ACCOUNT "hwAccountHashVal"
28 #define JSON_KEY_CAST_PLUS "castPlus"
29 #define JSON_KEY_BDATA "bData"
30 #define JSON_KEY_NICKNAME "nickName"
31 #define MAX_BDATA_LEN 300
32 #define HEX_HASH_LEN 16
33
DiscCoapParseDeviceUdid(const char * raw,DeviceInfo * device)34 int32_t DiscCoapParseDeviceUdid(const char *raw, DeviceInfo *device)
35 {
36 DISC_CHECK_AND_RETURN_RET_LOGE(raw != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "raw string is NULL");
37 DISC_CHECK_AND_RETURN_RET_LOGE(device != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "device info is NULL");
38
39 cJSON *udidJson = cJSON_Parse(raw);
40 DISC_CHECK_AND_RETURN_RET_LOGE(udidJson != NULL, SOFTBUS_PARSE_JSON_ERR, DISC_COAP, "parse udid json failed");
41 char tmpUdid[DISC_MAX_DEVICE_ID_LEN] = { 0 };
42 if (!GetJsonObjectStringItem(udidJson, DEVICE_UDID, tmpUdid, DISC_MAX_DEVICE_ID_LEN)) {
43 cJSON_Delete(udidJson);
44 DISC_LOGE(DISC_COAP, "parse remote udid failed");
45 return SOFTBUS_PARSE_JSON_ERR;
46 }
47 char *anonymizedStr;
48 Anonymize(tmpUdid, &anonymizedStr);
49 DISC_LOGI(DISC_COAP, "devId=%{public}s", AnonymizeWrapper(anonymizedStr));
50 AnonymizeFree(anonymizedStr);
51 cJSON_Delete(udidJson);
52
53 int32_t ret = GenerateStrHashAndConvertToHexString((const unsigned char *)tmpUdid, HEX_HASH_LEN,
54 (unsigned char *)device->devId, HEX_HASH_LEN + 1);
55 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
56 "generate udid hex hash failed, ret=%{public}d", ret);
57 return SOFTBUS_OK;
58 }
59
DiscCoapParseWifiIpAddr(const cJSON * data,DeviceInfo * device)60 void DiscCoapParseWifiIpAddr(const cJSON *data, DeviceInfo *device)
61 {
62 DISC_CHECK_AND_RETURN_LOGE(data != NULL, DISC_COAP, "json data is NULL");
63 DISC_CHECK_AND_RETURN_LOGE(device != NULL, DISC_COAP, "device info is NULL");
64 if (!GetJsonObjectStringItem(data, JSON_WLAN_IP, device->addr[0].info.ip.ip, sizeof(device->addr[0].info.ip.ip))) {
65 DISC_LOGE(DISC_COAP, "parse wifi ip address failed.");
66 return;
67 }
68 device->addrNum = 1;
69 char *anonymizedStr;
70 Anonymize(device->addr[0].info.ip.ip, &anonymizedStr);
71 DISC_LOGD(DISC_COAP, "ip=%{public}s", AnonymizeWrapper(anonymizedStr));
72 AnonymizeFree(anonymizedStr);
73 }
74
DiscCoapParseKeyValueStr(const char * src,const char * key,char * outValue,uint32_t outLen)75 int32_t DiscCoapParseKeyValueStr(const char *src, const char *key, char *outValue, uint32_t outLen)
76 {
77 DISC_CHECK_AND_RETURN_RET_LOGE(src != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "src is NULL");
78 DISC_CHECK_AND_RETURN_RET_LOGE(key != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "key is NULL");
79 DISC_CHECK_AND_RETURN_RET_LOGE(outValue != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "outValue is NULL");
80 DISC_CHECK_AND_RETURN_RET_LOGE(strlen(src) < DISC_MAX_CUST_DATA_LEN, SOFTBUS_INVALID_PARAM, DISC_COAP,
81 "src len >= max len. srcLen=%{public}zu, maxLen=%{public}u", strlen(src), DISC_MAX_CUST_DATA_LEN);
82
83 char tmpSrc[DISC_MAX_CUST_DATA_LEN] = { 0 };
84 if (memcpy_s(tmpSrc, (DISC_MAX_CUST_DATA_LEN - 1), src, strlen(src)) != EOK) {
85 DISC_LOGE(DISC_COAP, "copy src failed");
86 return SOFTBUS_MEM_ERR;
87 }
88
89 const char *delimiter = ",";
90 char *curValue = NULL;
91 char *remainStr = NULL;
92 char *curStr = strtok_s(tmpSrc, delimiter, &remainStr);
93 while (curStr != NULL) {
94 curValue = strchr(curStr, ':');
95 if (curValue == NULL) {
96 DISC_LOGW(DISC_COAP, "invalid kvStr item: curStr=%{public}s", curStr);
97 curStr = strtok_s(NULL, delimiter, &remainStr);
98 continue;
99 }
100
101 *curValue = '\0';
102 curValue++;
103 if (strcmp((const char *)curStr, key) != 0) {
104 curStr = strtok_s(NULL, delimiter, &remainStr);
105 continue;
106 }
107 if (strcpy_s(outValue, outLen, curValue) != EOK) {
108 DISC_LOGE(DISC_COAP, "copy value failed");
109 return SOFTBUS_STRCPY_ERR;
110 }
111 return SOFTBUS_OK;
112 }
113 DISC_LOGE(DISC_COAP, "cannot find the key: key=%{public}s", key);
114 return SOFTBUS_DISCOVER_COAP_PARSE_DATA_FAIL;
115 }
116
DiscCoapParseServiceData(const cJSON * data,DeviceInfo * device)117 int32_t DiscCoapParseServiceData(const cJSON *data, DeviceInfo *device)
118 {
119 DISC_CHECK_AND_RETURN_RET_LOGE(data != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "json data is NULL");
120 DISC_CHECK_AND_RETURN_RET_LOGE(device != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "device info is NULL");
121 char serviceData[MAX_SERVICE_DATA_LEN] = { 0 };
122 if (!GetJsonObjectStringItem(data, JSON_SERVICE_DATA, serviceData, sizeof(serviceData))) {
123 DISC_LOGD(DISC_COAP, "parse service data failed.");
124 return SOFTBUS_PARSE_JSON_ERR;
125 }
126 char port[MAX_PORT_STR_LEN] = { 0 };
127 int32_t ret = DiscCoapParseKeyValueStr(serviceData, SERVICE_DATA_PORT, port, MAX_PORT_STR_LEN);
128 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "parse service data failed");
129 int32_t authPort = atoi(port);
130 if (authPort <= 0 || authPort > UINT16_MAX) {
131 DISC_LOGE(DISC_COAP, "the auth port is invalid. authPort=%{public}d", authPort);
132 return SOFTBUS_DISCOVER_COAP_PARSE_DATA_FAIL;
133 }
134 device->addr[0].info.ip.port = (uint16_t)authPort;
135 return SOFTBUS_OK;
136 }
137
DiscCoapParseHwAccountHash(const cJSON * data,DeviceInfo * device)138 void DiscCoapParseHwAccountHash(const cJSON *data, DeviceInfo *device)
139 {
140 DISC_CHECK_AND_RETURN_LOGE(data != NULL, DISC_COAP, "json data is NULL");
141 DISC_CHECK_AND_RETURN_LOGE(device != NULL, DISC_COAP, "device info is NULL");
142 char tmpAccount[MAX_ACCOUNT_HASH_LEN] = { 0 };
143 if (!GetJsonObjectStringItem(data, JSON_HW_ACCOUNT, tmpAccount, MAX_ACCOUNT_HASH_LEN)) {
144 DISC_LOGE(DISC_COAP, "parse accountId failed");
145 return;
146 }
147
148 int32_t ret = SoftBusGenerateStrHash((const unsigned char *)tmpAccount, strlen(tmpAccount),
149 (unsigned char *)device->accountHash);
150 DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "generate account hash failed, ret=%{public}d", ret);
151 }
152
DiscCoapParseNickname(const cJSON * data,char * nickName,int32_t length)153 void DiscCoapParseNickname(const cJSON *data, char *nickName, int32_t length)
154 {
155 DISC_CHECK_AND_RETURN_LOGE(data != NULL, DISC_COAP, "json data is NULL");
156 DISC_CHECK_AND_RETURN_LOGE(nickName != NULL, DISC_COAP, "nickName is NULL");
157 char bData[MAX_BDATA_LEN] = { 0 };
158 if (!GetJsonObjectStringItem(data, JSON_KEY_BDATA, bData, MAX_BDATA_LEN)) {
159 DISC_LOGE(DISC_COAP, "parse bData failed");
160 return;
161 }
162
163 cJSON *bDataInfo = cJSON_Parse(bData);
164 DISC_CHECK_AND_RETURN_LOGE(bDataInfo != NULL, DISC_COAP, "parse bData failed.");
165 if (!GetJsonObjectStringItem(bDataInfo, JSON_KEY_NICKNAME, nickName, length)) {
166 DISC_LOGE(DISC_COAP, "parse nickName failed");
167 cJSON_Delete(bDataInfo);
168 return;
169 }
170 cJSON_Delete(bDataInfo);
171 }