1 /*
2 * Copyright (c) 2022 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 "lnn_heartbeat_utils.h"
17
18 #include <securec.h>
19 #include <string.h>
20
21 #include "bus_center_manager.h"
22 #include "lnn_heartbeat_medium_mgr.h"
23 #include "wifi_direct_manager.h"
24
25 #include "softbus_adapter_crypto.h"
26 #include "softbus_conn_interface.h"
27 #include "softbus_def.h"
28 #include "softbus_errcode.h"
29 #include "softbus_log.h"
30 #include "softbus_utils.h"
31
LnnConvertConnAddrTypeToHbType(ConnectionAddrType addrType)32 NO_SANITIZE("cfi") LnnHeartbeatType LnnConvertConnAddrTypeToHbType(ConnectionAddrType addrType)
33 {
34 switch (addrType) {
35 case CONNECTION_ADDR_WLAN:
36 case CONNECTION_ADDR_ETH:
37 return HEARTBEAT_TYPE_UDP;
38 case CONNECTION_ADDR_BR:
39 case CONNECTION_ADDR_BLE:
40 return HEARTBEAT_TYPE_BLE_V1;
41 default:
42 break;
43 }
44 return HEARTBEAT_TYPE_MAX;
45 }
46
LnnConvertHbTypeToConnAddrType(LnnHeartbeatType type)47 NO_SANITIZE("cfi") ConnectionAddrType LnnConvertHbTypeToConnAddrType(LnnHeartbeatType type)
48 {
49 switch (type) {
50 case HEARTBEAT_TYPE_UDP:
51 case HEARTBEAT_TYPE_TCP_FLUSH:
52 return CONNECTION_ADDR_WLAN;
53 case HEARTBEAT_TYPE_BLE_V1:
54 case HEARTBEAT_TYPE_BLE_V0:
55 return CONNECTION_ADDR_BLE;
56 default:
57 break;
58 }
59 return CONNECTION_ADDR_MAX;
60 }
61
LnnConvertHbTypeToId(LnnHeartbeatType type)62 NO_SANITIZE("cfi") int32_t LnnConvertHbTypeToId(LnnHeartbeatType type)
63 {
64 int32_t cnt = -1;
65
66 if (type < HEARTBEAT_TYPE_MIN || type >= HEARTBEAT_TYPE_MAX) {
67 return HB_INVALID_TYPE_ID;
68 }
69 do {
70 type >>= 1;
71 ++cnt;
72 } while (type >= HEARTBEAT_TYPE_MIN);
73 if (cnt < 0 || cnt > HB_MAX_TYPE_COUNT) {
74 return HB_INVALID_TYPE_ID;
75 }
76 return cnt;
77 }
78
HbHasActiveBrConnection(const char * networkId)79 static bool HbHasActiveBrConnection(const char *networkId)
80 {
81 bool ret = false;
82 ConnectOption option = {0};
83 char brMac[BT_MAC_LEN] = {0};
84
85 if (LnnGetRemoteStrInfo(networkId, STRING_KEY_BT_MAC, brMac, sizeof(brMac)) != SOFTBUS_OK) {
86 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB get bt mac err");
87 return false;
88 }
89 option.type = CONNECT_BR;
90 if (strcpy_s(option.brOption.brMac, BT_MAC_LEN, brMac) != EOK) {
91 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB strcpy_s bt mac err");
92 return false;
93 }
94 ret = CheckActiveConnection(&option);
95 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_DBG, "HB has active bt connection:%s", ret ? "true" : "false");
96 return ret;
97 }
98
HbHasActiveBleConnection(const char * networkId)99 static bool HbHasActiveBleConnection(const char *networkId)
100 {
101 bool ret = false;
102 ConnectOption option = {0};
103 char udid[UDID_BUF_LEN] = {0};
104 char udidHash[UDID_HASH_LEN] = {0};
105
106 if (LnnGetRemoteStrInfo(networkId, STRING_KEY_DEV_UDID, udid, sizeof(udid)) != SOFTBUS_OK) {
107 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB get udid err");
108 return false;
109 }
110 if (SoftBusGenerateStrHash((const unsigned char *)udid, strlen(udid),
111 (unsigned char *)udidHash) != SOFTBUS_OK) {
112 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB get udid hash err");
113 return false;
114 }
115 option.type = CONNECT_BLE;
116 if (memcpy_s(option.bleOption.deviceIdHash, UDID_HASH_LEN, udidHash, sizeof(udidHash)) != EOK) {
117 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB memcpy_s udid hash err");
118 return false;
119 }
120 ret = CheckActiveConnection(&option);
121 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_DBG, "HB has active ble connection:%s", ret ? "true" : "false");
122 return ret;
123 }
124
HbHasActiveP2pConnection(const char * networkId)125 static bool HbHasActiveP2pConnection(const char *networkId)
126 {
127 char peerMac[MAC_ADDR_STR_LEN] = {0};
128
129 if (LnnGetRemoteStrInfo(networkId, STRING_KEY_P2P_MAC, peerMac, sizeof(peerMac)) != SOFTBUS_OK) {
130 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB get peer p2p mac err");
131 return false;
132 }
133 bool isOnline = GetWifiDirectManager()->isDeviceOnline(peerMac);
134 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_DBG, "HB has active p2p connection: %s", isOnline ? "true" : "false");
135 return isOnline;
136 }
137
LnnHasActiveConnection(const char * networkId,ConnectionAddrType addrType)138 NO_SANITIZE("cfi") bool LnnHasActiveConnection(const char *networkId, ConnectionAddrType addrType)
139 {
140 bool ret = false;
141
142 if (networkId == NULL || addrType >= CONNECTION_ADDR_MAX) {
143 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB check active connection get invalid param");
144 return ret;
145 }
146 switch (addrType) {
147 case CONNECTION_ADDR_WLAN:
148 case CONNECTION_ADDR_ETH:
149 case CONNECTION_ADDR_BR:
150 break;
151 case CONNECTION_ADDR_BLE:
152 ret = HbHasActiveBrConnection(networkId) || HbHasActiveBleConnection(networkId) ||
153 HbHasActiveP2pConnection(networkId);
154 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "HB networkId:%s has active BT/BLE/P2P connection:%s",
155 AnonymizesNetworkID(networkId), ret ? "true" : "false");
156 return ret;
157 default:
158 break;
159 }
160 return false;
161 }
162
LnnVisitHbTypeSet(VisitHbTypeCb callback,LnnHeartbeatType * typeSet,void * data)163 NO_SANITIZE("cfi") bool LnnVisitHbTypeSet(VisitHbTypeCb callback, LnnHeartbeatType *typeSet, void *data)
164 {
165 bool isFinish = false;
166 LnnHeartbeatType i;
167
168 if (typeSet == NULL || *typeSet < HEARTBEAT_TYPE_MIN || *typeSet >= HEARTBEAT_TYPE_MAX) {
169 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB visit typeSet get invalid param");
170 return false;
171 }
172 for (i = HEARTBEAT_TYPE_MIN; i < HEARTBEAT_TYPE_MAX; i <<= 1) {
173 if ((i & *typeSet) == 0) {
174 continue;
175 }
176 isFinish = callback(typeSet, i, data);
177 if (!isFinish) {
178 return false;
179 }
180 }
181 return true;
182 }
183
VisitCheckSupportedHbType(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)184 static bool VisitCheckSupportedHbType(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
185 {
186 (void)typeSet;
187 LnnHeartbeatType *dstType = (LnnHeartbeatType *)data;
188
189 if ((eachType & *dstType) == 0) {
190 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB not support hbType(%d) completely", *dstType);
191 return false;
192 }
193 return true;
194 }
195
LnnCheckSupportedHbType(LnnHeartbeatType * srcType,LnnHeartbeatType * dstType)196 NO_SANITIZE("cfi") bool LnnCheckSupportedHbType(LnnHeartbeatType *srcType, LnnHeartbeatType *dstType)
197 {
198 if (srcType == NULL || dstType == NULL) {
199 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB check supported hbType get invalid param");
200 return false;
201 }
202 return LnnVisitHbTypeSet(VisitCheckSupportedHbType, srcType, dstType);
203 }
204
LnnGenerateHexStringHash(const unsigned char * str,char * hashStr,uint32_t len)205 NO_SANITIZE("cfi") int32_t LnnGenerateHexStringHash(const unsigned char *str, char *hashStr, uint32_t len)
206 {
207 int32_t ret;
208 uint8_t hashResult[SHA_256_HASH_LEN] = {0};
209
210 if (str == NULL) {
211 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB generate str hash invalid param");
212 return SOFTBUS_INVALID_PARAM;
213 }
214 ret = SoftBusGenerateStrHash(str, strlen((char *)str), hashResult);
215 if (ret != SOFTBUS_OK) {
216 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB generate str hash fail, ret=%d", ret);
217 return ret;
218 }
219 ret = ConvertBytesToHexString(hashStr, len + 1, hashResult, len / HEXIFY_UNIT_LEN);
220 if (ret != SOFTBUS_OK) {
221 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "HB convert bytes to str hash fail ret=%d", ret);
222 return ret;
223 }
224 return SOFTBUS_OK;
225 }
226
LnnGenerateBtMacHash(const char * btMac,int32_t brMacLen,char * brMacHash,int32_t hashLen)227 NO_SANITIZE("cfi") int32_t LnnGenerateBtMacHash(const char *btMac, int32_t brMacLen, char *brMacHash, int32_t hashLen)
228 {
229 if (btMac == NULL || brMacHash == NULL) {
230 LLOGE("null point");
231 return SOFTBUS_ERR;
232 }
233 if (brMacLen != BT_MAC_LEN || hashLen != BT_MAC_HASH_STR_LEN) {
234 LLOGE("invaild len");
235 return SOFTBUS_ERR;
236 }
237 uint8_t btMacBin[BT_ADDR_LEN] = {0};
238 char btMacStr[BT_MAC_NO_COLON_LEN] = {0};
239 char hashLower[BT_MAC_HASH_STR_LEN] = {0};
240 char hash[BT_MAC_HASH_LEN] = {0};
241 if (ConvertBtMacToBinary(btMac, BT_MAC_LEN, btMacBin, BT_ADDR_LEN) != SOFTBUS_OK) {
242 LLOGE("convert br mac to bin fail.");
243 return SOFTBUS_ERR;
244 }
245 if (ConvertBtMacToStrNoColon(btMacStr, BT_MAC_NO_COLON_LEN, btMacBin, BT_ADDR_LEN)) {
246 LLOGE("convert br mac to str fail.");
247 return SOFTBUS_ERR;
248 }
249 char brMacUpper[BT_MAC_NO_COLON_LEN] = {0};
250 if (StringToUpperCase(btMacStr, brMacUpper, BT_MAC_NO_COLON_LEN) != SOFTBUS_OK) {
251 LLOGE("bt mac to upperCase fail");
252 return SOFTBUS_ERR;
253 }
254 LLOGI("upper BrMac=**:**:**:**:%s", AnonymizesUDID(brMacUpper));
255 if (SoftBusGenerateStrHash((const unsigned char *)brMacUpper, strlen(brMacUpper), (unsigned char *)hash)) {
256 LLOGE("Generate brMac hash fail.");
257 return SOFTBUS_ERR;
258 }
259 if (ConvertBytesToHexString(hashLower, BT_MAC_HASH_STR_LEN, (const uint8_t *)hash,
260 BT_MAC_HASH_LEN) != SOFTBUS_OK) {
261 DLOGE("ConvertBytesToHexString failed");
262 return SOFTBUS_ERR;
263 }
264 if (StringToUpperCase(hashLower, brMacHash, BT_MAC_HASH_STR_LEN) != SOFTBUS_OK) {
265 LLOGE("bt mac to upperCase fail");
266 return SOFTBUS_ERR;
267 }
268 LLOGI("brmacHash :%s", AnonymizesUDID(brMacHash));
269 return SOFTBUS_OK;
270 }