1/* 2 * Copyright (c) 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 "dm_softbus_cache.h" 17#include "dm_anonymous.h" 18#include "dm_crypto.h" 19#include "dm_constants.h" 20#include "dm_device_info.h" 21#include "dm_log.h" 22namespace OHOS { 23namespace DistributedHardware { 24DM_IMPLEMENT_SINGLE_INSTANCE(SoftbusCache); 25bool g_online = false; 26bool g_getLocalDevInfo = false; 27DmDeviceInfo localDeviceInfo_; 28std::mutex localDevInfoMutex_; 29void SoftbusCache::SaveLocalDeviceInfo() 30{ 31 LOGI("SoftbusCache::SaveLocalDeviceInfo"); 32 std::lock_guard<std::mutex> mutexLock(localDevInfoMutex_); 33 if (g_online) { 34 return; 35 } 36 NodeBasicInfo nodeBasicInfo; 37 int32_t ret = GetLocalNodeDeviceInfo(DM_PKG_NAME, &nodeBasicInfo); 38 if (ret != DM_OK) { 39 LOGE("[SOFTBUS]GetLocalNodeDeviceInfo failed, ret: %{public}d.", ret); 40 return; 41 } 42 ConvertNodeBasicInfoToDmDevice(nodeBasicInfo, localDeviceInfo_); 43 LOGI("SoftbusCache::SaveLocalDeviceInfo networkid %{public}s.", 44 GetAnonyString(std::string(localDeviceInfo_.networkId)).c_str()); 45 SaveDeviceInfo(localDeviceInfo_); 46 SaveDeviceSecurityLevel(localDeviceInfo_.networkId); 47 g_online = true; 48 g_getLocalDevInfo = true; 49} 50 51void SoftbusCache::DeleteLocalDeviceInfo() 52{ 53 LOGI("SoftbusCache::DeleteLocalDeviceInfo networkid %{public}s.", 54 GetAnonyString(std::string(localDeviceInfo_.networkId)).c_str()); 55 std::lock_guard<std::mutex> mutexLock(localDevInfoMutex_); 56 g_online = false; 57 g_getLocalDevInfo = false; 58} 59 60int32_t SoftbusCache::GetLocalDeviceInfo(DmDeviceInfo &nodeInfo) 61{ 62 std::lock_guard<std::mutex> mutexLock(localDevInfoMutex_); 63 if (g_getLocalDevInfo) { 64 nodeInfo = localDeviceInfo_; 65 LOGI("SoftbusCache::GetLocalDeviceInfo from dm cache."); 66 return DM_OK; 67 } 68 NodeBasicInfo nodeBasicInfo; 69 int32_t ret = GetLocalNodeDeviceInfo(DM_PKG_NAME, &nodeBasicInfo); 70 if (ret != DM_OK) { 71 LOGE("[SOFTBUS]GetLocalNodeDeviceInfo failed, ret: %{public}d.", ret); 72 return ret; 73 } 74 ConvertNodeBasicInfoToDmDevice(nodeBasicInfo, localDeviceInfo_); 75 nodeInfo = localDeviceInfo_; 76 SaveDeviceInfo(localDeviceInfo_); 77 SaveDeviceSecurityLevel(localDeviceInfo_.networkId); 78 g_getLocalDevInfo = true; 79 LOGI("SoftbusCache::GetLocalDeviceInfo from softbus."); 80 return DM_OK; 81} 82 83void SoftbusCache::UpDataLocalDevInfo() 84{ 85 LOGI("SoftbusCache::UpDataLocalDevInfo"); 86 NodeBasicInfo nodeBasicInfo; 87 int32_t ret = GetLocalNodeDeviceInfo(DM_PKG_NAME, &nodeBasicInfo); 88 if (ret != DM_OK) { 89 LOGE("[SOFTBUS]GetLocalNodeDeviceInfo failed, ret: %{public}d.", ret); 90 return; 91 } 92 std::lock_guard<std::mutex> mutexLock(localDevInfoMutex_); 93 ConvertNodeBasicInfoToDmDevice(nodeBasicInfo, localDeviceInfo_); 94 ChangeDeviceInfo(localDeviceInfo_); 95} 96 97int32_t SoftbusCache::GetUdidByNetworkId(const char *networkId, std::string &udid) 98{ 99 uint8_t mUdid[UDID_BUF_LEN] = {0}; 100 int32_t ret = GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_UDID, mUdid, sizeof(mUdid)); 101 if (ret != DM_OK) { 102 LOGE("[SOFTBUS]GetNodeKeyInfo failed, ret: %{public}d.", ret); 103 return ret; 104 } 105 udid = reinterpret_cast<char *>(mUdid); 106 return ret; 107} 108 109int32_t SoftbusCache::GetUuidByNetworkId(const char *networkId, std::string &uuid) 110{ 111 uint8_t mUuid[UUID_BUF_LEN] = {0}; 112 int32_t ret = GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_UUID, mUuid, sizeof(mUuid)); 113 if (ret != DM_OK) { 114 LOGE("[SOFTBUS]GetNodeKeyInfo failed, ret: %{public}d.", ret); 115 return ret; 116 } 117 uuid = reinterpret_cast<char *>(mUuid); 118 return ret; 119} 120 121void SoftbusCache::SaveDeviceInfo(DmDeviceInfo deviceInfo) 122{ 123 LOGI("SoftbusCache::SaveDeviceInfo"); 124 std::string udid = ""; 125 std::string uuid = ""; 126 GetUdidByNetworkId(deviceInfo.networkId, udid); 127 GetUuidByNetworkId(deviceInfo.networkId, uuid); 128 char udidHash[DM_MAX_DEVICE_ID_LEN] = {0}; 129 if (Crypto::GetUdidHash(udid, reinterpret_cast<uint8_t *>(udidHash)) != DM_OK) { 130 LOGE("get udidhash by udid: %{public}s failed.", GetAnonyString(udid).c_str()); 131 return; 132 } 133 if (memcpy_s(deviceInfo.deviceId, sizeof(deviceInfo.deviceId), udidHash, 134 std::min(sizeof(deviceInfo.deviceId), sizeof(udidHash))) != DM_OK) { 135 LOGE("SaveDeviceInfo copy deviceId failed."); 136 return; 137 } 138 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 139 deviceInfo_[udid] = std::pair<std::string, DmDeviceInfo>(uuid, deviceInfo); 140 LOGI("SaveDeviceInfo success udid %{public}s, networkId %{public}s", 141 GetAnonyString(udid).c_str(), GetAnonyString(std::string(deviceInfo.networkId)).c_str()); 142} 143 144void SoftbusCache::DeleteDeviceInfo(const DmDeviceInfo &nodeInfo) 145{ 146 LOGI("SoftbusCache::DeleteDeviceInfo networkId %{public}s", 147 GetAnonyString(std::string(nodeInfo.networkId)).c_str()); 148 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 149 for (const auto &item : deviceInfo_) { 150 if (std::string(item.second.second.networkId) == std::string(nodeInfo.networkId)) { 151 LOGI("DeleteDeviceInfo success udid %{public}s", GetAnonyString(item.first).c_str()); 152 deviceInfo_.erase(item.first); 153 break; 154 } 155 } 156} 157 158void SoftbusCache::ChangeDeviceInfo(const DmDeviceInfo deviceInfo) 159{ 160 LOGI("SoftbusCache::ChangeDeviceInfo"); 161 std::string udid = ""; 162 GetUdidByNetworkId(deviceInfo.networkId, udid); 163 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 164 if (deviceInfo_.find(udid) != deviceInfo_.end()) { 165 if (memcpy_s(deviceInfo_[udid].second.deviceName, sizeof(deviceInfo_[udid].second.deviceName), 166 deviceInfo.deviceName, sizeof(deviceInfo.deviceName)) != DM_OK) { 167 LOGE("ChangeDeviceInfo deviceInfo copy deviceName failed"); 168 } 169 if (memcpy_s(deviceInfo_[udid].second.networkId, sizeof(deviceInfo_[udid].second.networkId), 170 deviceInfo.networkId, sizeof(deviceInfo.networkId)) != DM_OK) { 171 LOGE("ChangeDeviceInfo deviceInfo copy networkId failed"); 172 } 173 deviceInfo_[udid].second.deviceTypeId = deviceInfo.deviceTypeId; 174 std::string uuid = ""; 175 GetUuidByNetworkId(deviceInfo.networkId, uuid); 176 deviceInfo_[udid].first = uuid; 177 } 178 LOGI("ChangeDeviceInfo sucess udid %{public}s, networkId %{public}s.", 179 GetAnonyString(udid).c_str(), GetAnonyString(std::string(deviceInfo.networkId)).c_str()); 180} 181 182int32_t SoftbusCache::GetDeviceInfoFromCache(std::vector<DmDeviceInfo> &deviceInfoList) 183{ 184 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 185 for (const auto &item : deviceInfo_) { 186 if (std::string(item.second.second.networkId) == std::string(localDeviceInfo_.networkId)) { 187 continue; 188 } 189 deviceInfoList.push_back(item.second.second); 190 } 191 return DM_OK; 192} 193 194void SoftbusCache::UpdateDeviceInfoCache() 195{ 196 LOGI("SoftbusCache::UpdateDeviceInfoCache"); 197 int32_t deviceCount = 0; 198 NodeBasicInfo *nodeInfo = nullptr; 199 int32_t ret = GetAllNodeDeviceInfo(DM_PKG_NAME, &nodeInfo, &deviceCount); 200 if (ret != DM_OK) { 201 LOGE("[SOFTBUS]GetAllNodeDeviceInfo failed, ret: %{public}d.", ret); 202 return; 203 } 204 SaveLocalDeviceInfo(); 205 for (int32_t i = 0; i < deviceCount; ++i) { 206 NodeBasicInfo *nodeBasicInfo = nodeInfo + i; 207 DmDeviceInfo deviceInfo; 208 ConvertNodeBasicInfoToDmDevice(*nodeBasicInfo, deviceInfo); 209 SaveDeviceInfo(deviceInfo); 210 } 211 FreeNodeInfo(nodeInfo); 212 LOGI("UpdateDeviceInfoCache success, deviceCount: %{public}d.", deviceCount); 213 return; 214} 215 216int32_t SoftbusCache::GetUdidFromCache(const char *networkId, std::string &udid) 217{ 218 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 219 for (const auto &item : deviceInfo_) { 220 if (std::string(item.second.second.networkId) == std::string(networkId)) { 221 udid = item.first; 222 LOGI("Get udid from cache success, networkId %{public}s, udid %{public}s.", 223 GetAnonyString(std::string(networkId)).c_str(), GetAnonyString(udid).c_str()); 224 return DM_OK; 225 } 226 } 227 int32_t ret = GetUdidByNetworkId(networkId, udid); 228 if (ret == DM_OK) { 229 LOGI("Get udid from bus success, networkId %{public}s, udid %{public}s.", 230 GetAnonyString(std::string(networkId)).c_str(), GetAnonyString(udid).c_str()); 231 return DM_OK; 232 } 233 return ret; 234} 235 236int32_t SoftbusCache::GetUuidFromCache(const char *networkId, std::string &uuid) 237{ 238 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 239 for (const auto &item : deviceInfo_) { 240 if (std::string(item.second.second.networkId) == std::string(networkId)) { 241 uuid = item.second.first; 242 LOGI("Get uuid from cache success, networkId %{public}s, uuid %{public}s.", 243 GetAnonyString(std::string(networkId)).c_str(), GetAnonyString(uuid).c_str()); 244 return DM_OK; 245 } 246 } 247 int32_t ret = GetUuidByNetworkId(networkId, uuid); 248 if (ret == DM_OK) { 249 LOGI("Get uuid from bus success, networkId %{public}s, uuid %{public}s.", 250 GetAnonyString(std::string(networkId)).c_str(), GetAnonyString(uuid).c_str()); 251 return DM_OK; 252 } 253 return ret; 254} 255 256int32_t SoftbusCache::ConvertNodeBasicInfoToDmDevice(const NodeBasicInfo &nodeInfo, DmDeviceInfo &devInfo) 257{ 258 if (memset_s(&devInfo, sizeof(DmDeviceInfo), 0, sizeof(DmDeviceInfo)) != DM_OK) { 259 LOGE("ConvertNodeBasicInfoToDmDevice memset_s failed."); 260 return ERR_DM_FAILED; 261 } 262 263 if (memcpy_s(devInfo.networkId, sizeof(devInfo.networkId), nodeInfo.networkId, 264 std::min(sizeof(devInfo.networkId), sizeof(nodeInfo.networkId))) != DM_OK) { 265 LOGE("ConvertNodeBasicInfoToDmDevice copy networkId data failed."); 266 return ERR_DM_FAILED; 267 } 268 269 if (memcpy_s(devInfo.deviceName, sizeof(devInfo.deviceName), nodeInfo.deviceName, 270 std::min(sizeof(devInfo.deviceName), sizeof(nodeInfo.deviceName))) != DM_OK) { 271 LOGE("ConvertNodeBasicInfoToDmDevice copy deviceName data failed."); 272 return ERR_DM_FAILED; 273 } 274 275 devInfo.deviceTypeId = nodeInfo.deviceTypeId; 276 nlohmann::json extraJson; 277 extraJson[PARAM_KEY_OS_TYPE] = nodeInfo.osType; 278 extraJson[PARAM_KEY_OS_VERSION] = ConvertCharArray2String(nodeInfo.osVersion, OS_VERSION_BUF_LEN); 279 devInfo.extraData = to_string(extraJson); 280 return DM_OK; 281} 282 283void SoftbusCache::SaveDeviceSecurityLevel(const char *networkId) 284{ 285 LOGI("SoftbusCache::SaveDeviceSecurityLevel networkId %{public}s.", GetAnonyString(std::string(networkId)).c_str()); 286 std::lock_guard<std::mutex> mutexLock(deviceSecurityLevelMutex_); 287 if (deviceSecurityLevel_.find(std::string(networkId)) != deviceSecurityLevel_.end()) { 288 return; 289 } 290 int32_t tempSecurityLevel = -1; 291 if (GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_DEVICE_SECURITY_LEVEL, 292 reinterpret_cast<uint8_t *>(&tempSecurityLevel), LNN_COMMON_LEN) != DM_OK) { 293 LOGE("[SOFTBUS]GetNodeKeyInfo networkType failed."); 294 return; 295 } 296 deviceSecurityLevel_[std::string(networkId)] = tempSecurityLevel; 297} 298 299void SoftbusCache::DeleteDeviceSecurityLevel(const char *networkId) 300{ 301 LOGI("SoftbusCache::DeleteDeviceSecurityLevel networkId %{public}s.", 302 GetAnonyString(std::string(networkId)).c_str()); 303 std::lock_guard<std::mutex> mutexLock(deviceSecurityLevelMutex_); 304 if (deviceSecurityLevel_.find(std::string(networkId)) != deviceSecurityLevel_.end()) { 305 deviceSecurityLevel_.erase(std::string(networkId)); 306 } 307} 308 309int32_t SoftbusCache::GetSecurityDeviceLevel(const char *networkId, int32_t &securityLevel) 310{ 311 std::lock_guard<std::mutex> mutexLock(deviceSecurityLevelMutex_); 312 for (const auto &item : deviceSecurityLevel_) { 313 if (item.first == std::string(networkId)) { 314 securityLevel = item.second; 315 LOGI("Get dev level from cache success, networkId is %{public}s.", 316 GetAnonyString(std::string(networkId)).c_str()); 317 return DM_OK; 318 } 319 } 320 return GetDevLevelFromBus(networkId, securityLevel); 321} 322 323int32_t SoftbusCache::GetDevLevelFromBus(const char *networkId, int32_t &securityLevel) 324{ 325 int32_t tempSecurityLevel = -1; 326 if (GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_DEVICE_SECURITY_LEVEL, 327 reinterpret_cast<uint8_t *>(&tempSecurityLevel), LNN_COMMON_LEN) != DM_OK) { 328 LOGE("[SOFTBUS]GetNodeKeyInfo networkType failed."); 329 return ERR_DM_FAILED; 330 } 331 securityLevel = tempSecurityLevel; 332 deviceSecurityLevel_[std::string(networkId)] = tempSecurityLevel; 333 LOGI("Get dev level from softbus success, networkId is %{public}s.", 334 GetAnonyString(std::string(networkId)).c_str()); 335 return DM_OK; 336} 337 338int32_t SoftbusCache::GetDevInfoByNetworkId(const std::string &networkId, DmDeviceInfo &nodeInfo) 339{ 340 { 341 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 342 for (const auto &item : deviceInfo_) { 343 if (std::string(item.second.second.networkId) == networkId) { 344 nodeInfo = item.second.second; 345 LOGI("GetDevInfoByNetworkId success networkId %{public}s, udid %{public}s.", 346 GetAnonyString(networkId).c_str(), GetAnonyString(item.first).c_str()); 347 return DM_OK; 348 } 349 } 350 } 351 int32_t ret = GetDevInfoFromBus(networkId, nodeInfo); 352 if (ret != DM_OK) { 353 LOGE("GetDevInfoFromBus failed."); 354 return ret; 355 } 356 SaveDeviceInfo(nodeInfo); 357 return DM_OK; 358} 359 360int32_t SoftbusCache::GetDevInfoFromBus(const std::string &networkId, DmDeviceInfo &devInfo) 361{ 362 int32_t nodeInfoCount = 0; 363 NodeBasicInfo *nodeInfo = nullptr; 364 int32_t ret = GetAllNodeDeviceInfo(DM_PKG_NAME, &nodeInfo, &nodeInfoCount); 365 if (ret != DM_OK) { 366 LOGE("[SOFTBUS]GetAllNodeDeviceInfo failed, ret: %{public}d.", ret); 367 return ret; 368 } 369 for (int32_t i = 0; i < nodeInfoCount; ++i) { 370 NodeBasicInfo *nodeBasicInfo = nodeInfo + i; 371 if (networkId == std::string(nodeBasicInfo->networkId)) { 372 ConvertNodeBasicInfoToDmDevice(*nodeBasicInfo, devInfo); 373 break; 374 } 375 } 376 FreeNodeInfo(nodeInfo); 377 LOGI("GetDeviceInfo complete, deviceName : %{public}s, deviceTypeId : %{public}d.", 378 GetAnonyString(devInfo.deviceName).c_str(), devInfo.deviceTypeId); 379 return ret; 380} 381 382int32_t SoftbusCache::GetUdidByUdidHash(const std::string &udidHash, std::string &udid) 383{ 384 LOGI("udidHash %{public}s.", GetAnonyString(udidHash).c_str()); 385 { 386 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 387 for (const auto &item : deviceInfo_) { 388 if (std::string(item.second.second.deviceId) == udidHash) { 389 udid = item.first; 390 LOGI("GetUdidByUdidHash success udid %{public}s.", GetAnonyString(udid).c_str()); 391 return DM_OK; 392 } 393 } 394 } 395 return ERR_DM_FAILED; 396} 397 398int32_t SoftbusCache::GetUuidByUdid(const std::string &udid, std::string &uuid) 399{ 400 LOGI("udid %{public}s.", GetAnonyString(udid).c_str()); 401 { 402 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 403 if (deviceInfo_.find(udid) != deviceInfo_.end()) { 404 uuid = deviceInfo_[udid].first; 405 LOGI("success uuid %{public}s.", GetAnonyString(uuid).c_str()); 406 return DM_OK; 407 } 408 } 409 return ERR_DM_FAILED; 410} 411 412int32_t SoftbusCache::GetNetworkIdFromCache(const std::string &udid, std::string &networkId) 413{ 414 LOGI("udid %{public}s.", GetAnonyString(udid).c_str()); 415 { 416 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 417 if (deviceInfo_.find(udid) != deviceInfo_.end()) { 418 networkId = deviceInfo_[udid].second.networkId; 419 LOGI("GetNetworkIdFromCache success networkId %{public}s, udid %{public}s.", 420 GetAnonyString(networkId).c_str(), GetAnonyString(udid).c_str()); 421 return DM_OK; 422 } 423 } 424 return ERR_DM_FAILED; 425} 426 427bool SoftbusCache::CheckIsOnline(const std::string &deviceId) 428{ 429 LOGI("deviceId %{public}s.", GetAnonyString(deviceId).c_str()); 430 { 431 std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_); 432 for (const auto &item : deviceInfo_) { 433 if (std::string(item.second.second.deviceId) == deviceId) { 434 LOGI("CheckIsOnline is true."); 435 return true; 436 } 437 } 438 } 439 return false; 440} 441} // namespace DistributedHardware 442} // namespace OHOS 443