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"
22 namespace OHOS {
23 namespace DistributedHardware {
24 DM_IMPLEMENT_SINGLE_INSTANCE(SoftbusCache);
25 bool g_online = false;
26 bool g_getLocalDevInfo = false;
27 DmDeviceInfo localDeviceInfo_;
28 std::mutex localDevInfoMutex_;
SaveLocalDeviceInfo()29 void 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 
DeleteLocalDeviceInfo()51 void 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 
GetLocalDeviceInfo(DmDeviceInfo & nodeInfo)60 int32_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 
UpDataLocalDevInfo()83 void 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 
GetUdidByNetworkId(const char * networkId,std::string & udid)97 int32_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 
GetUuidByNetworkId(const char * networkId,std::string & uuid)109 int32_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 
SaveDeviceInfo(DmDeviceInfo deviceInfo)121 void 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 
DeleteDeviceInfo(const DmDeviceInfo & nodeInfo)144 void 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 
ChangeDeviceInfo(const DmDeviceInfo deviceInfo)158 void 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 
GetDeviceInfoFromCache(std::vector<DmDeviceInfo> & deviceInfoList)182 int32_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 
UpdateDeviceInfoCache()194 void 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 
GetUdidFromCache(const char * networkId,std::string & udid)216 int32_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 
GetUuidFromCache(const char * networkId,std::string & uuid)236 int32_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 
ConvertNodeBasicInfoToDmDevice(const NodeBasicInfo & nodeInfo,DmDeviceInfo & devInfo)256 int32_t SoftbusCache::ConvertNodeBasicInfoToDmDevice(const NodeBasicInfo &nodeInfo, DmDeviceInfo &devInfo)
257 {
258     (void)memset_s(&devInfo, sizeof(DmDeviceInfo), 0, sizeof(DmDeviceInfo));
259     if (memcpy_s(devInfo.networkId, sizeof(devInfo.networkId), nodeInfo.networkId,
260         std::min(sizeof(devInfo.networkId), sizeof(nodeInfo.networkId))) != DM_OK) {
261         LOGE("ConvertNodeBasicInfoToDmDevice copy networkId data failed.");
262     }
263 
264     if (memcpy_s(devInfo.deviceName, sizeof(devInfo.deviceName), nodeInfo.deviceName,
265         std::min(sizeof(devInfo.deviceName), sizeof(nodeInfo.deviceName))) != DM_OK) {
266         LOGE("ConvertNodeBasicInfoToDmDevice copy deviceName data failed.");
267     }
268     devInfo.deviceTypeId = nodeInfo.deviceTypeId;
269     nlohmann::json extraJson;
270     extraJson[PARAM_KEY_OS_TYPE] = nodeInfo.osType;
271     extraJson[PARAM_KEY_OS_VERSION] = ConvertCharArray2String(nodeInfo.osVersion, OS_VERSION_BUF_LEN);
272     devInfo.extraData = to_string(extraJson);
273     return DM_OK;
274 }
275 
SaveDeviceSecurityLevel(const char * networkId)276 void SoftbusCache::SaveDeviceSecurityLevel(const char *networkId)
277 {
278     LOGI("SoftbusCache::SaveDeviceSecurityLevel networkId %{public}s.", GetAnonyString(std::string(networkId)).c_str());
279     std::lock_guard<std::mutex> mutexLock(deviceSecurityLevelMutex_);
280     if (deviceSecurityLevel_.find(std::string(networkId)) != deviceSecurityLevel_.end()) {
281         return;
282     }
283     int32_t tempSecurityLevel = -1;
284     if (GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_DEVICE_SECURITY_LEVEL,
285         reinterpret_cast<uint8_t *>(&tempSecurityLevel), LNN_COMMON_LEN) != DM_OK) {
286         LOGE("[SOFTBUS]GetNodeKeyInfo networkType failed.");
287         return;
288     }
289     deviceSecurityLevel_[std::string(networkId)] = tempSecurityLevel;
290 }
291 
DeleteDeviceSecurityLevel(const char * networkId)292 void SoftbusCache::DeleteDeviceSecurityLevel(const char *networkId)
293 {
294     LOGI("SoftbusCache::DeleteDeviceSecurityLevel networkId %{public}s.",
295         GetAnonyString(std::string(networkId)).c_str());
296     std::lock_guard<std::mutex> mutexLock(deviceSecurityLevelMutex_);
297     if (deviceSecurityLevel_.find(std::string(networkId)) != deviceSecurityLevel_.end()) {
298         deviceSecurityLevel_.erase(std::string(networkId));
299     }
300 }
301 
GetSecurityDeviceLevel(const char * networkId,int32_t & securityLevel)302 int32_t SoftbusCache::GetSecurityDeviceLevel(const char *networkId, int32_t &securityLevel)
303 {
304     std::lock_guard<std::mutex> mutexLock(deviceSecurityLevelMutex_);
305     for (const auto &item : deviceSecurityLevel_) {
306         if (item.first == std::string(networkId)) {
307             securityLevel = item.second;
308             LOGI("Get dev level from cache success, networkId is %{public}s.",
309                 GetAnonyString(std::string(networkId)).c_str());
310             return DM_OK;
311         }
312     }
313     int32_t ret = GetDevLevelFromBus(networkId, securityLevel);
314     if (ret == DM_OK) {
315         LOGI("Get dev level from softbus success.");
316         return DM_OK;
317     }
318     return ret;
319 }
320 
GetDevLevelFromBus(const char * networkId,int32_t & securityLevel)321 int32_t SoftbusCache::GetDevLevelFromBus(const char *networkId, int32_t &securityLevel)
322 {
323     int32_t tempSecurityLevel = -1;
324     if (GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_DEVICE_SECURITY_LEVEL,
325         reinterpret_cast<uint8_t *>(&tempSecurityLevel), LNN_COMMON_LEN) != DM_OK) {
326         LOGE("[SOFTBUS]GetNodeKeyInfo networkType failed.");
327         return ERR_DM_FAILED;
328     }
329     securityLevel = tempSecurityLevel;
330     deviceSecurityLevel_[std::string(networkId)] = tempSecurityLevel;
331     LOGI("Get dev level from softbus success, networkId is %{public}s.",
332         GetAnonyString(std::string(networkId)).c_str());
333     return DM_OK;
334 }
335 
GetDevInfoByNetworkId(const std::string & networkId,DmDeviceInfo & nodeInfo)336 int32_t SoftbusCache::GetDevInfoByNetworkId(const std::string &networkId, DmDeviceInfo &nodeInfo)
337 {
338     {
339         std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_);
340         for (const auto &item : deviceInfo_) {
341             if (std::string(item.second.second.networkId) == networkId) {
342                 nodeInfo = item.second.second;
343                 LOGI("GetDevInfoByNetworkId success networkId %{public}s, udid %{public}s.",
344                     GetAnonyString(networkId).c_str(), GetAnonyString(item.first).c_str());
345                 return DM_OK;
346             }
347         }
348     }
349     int32_t ret = GetDevInfoFromBus(networkId, nodeInfo);
350     if (ret != DM_OK) {
351         LOGE("GetDevInfoFromBus failed.");
352         return ret;
353     }
354     SaveDeviceInfo(nodeInfo);
355     return DM_OK;
356 }
357 
GetDevInfoFromBus(const std::string & networkId,DmDeviceInfo & devInfo)358 int32_t SoftbusCache::GetDevInfoFromBus(const std::string &networkId, DmDeviceInfo &devInfo)
359 {
360     int32_t nodeInfoCount = 0;
361     NodeBasicInfo *nodeInfo = nullptr;
362     int32_t ret = GetAllNodeDeviceInfo(DM_PKG_NAME, &nodeInfo, &nodeInfoCount);
363     if (ret != DM_OK) {
364         LOGE("[SOFTBUS]GetAllNodeDeviceInfo failed, ret: %{public}d.", ret);
365         return ret;
366     }
367     for (int32_t i = 0; i < nodeInfoCount; ++i) {
368         NodeBasicInfo *nodeBasicInfo = nodeInfo + i;
369         if (networkId == std::string(nodeBasicInfo->networkId)) {
370             ConvertNodeBasicInfoToDmDevice(*nodeBasicInfo, devInfo);
371             break;
372         }
373     }
374     FreeNodeInfo(nodeInfo);
375     LOGI("GetDeviceInfo complete, deviceName : %{public}s, deviceTypeId : %{public}d.",
376         GetAnonyString(devInfo.deviceName).c_str(), devInfo.deviceTypeId);
377     return ret;
378 }
379 
GetNetworkIdFromCache(const std::string & udid,std::string & networkId)380 int32_t SoftbusCache::GetNetworkIdFromCache(const std::string &udid, std::string &networkId)
381 {
382     LOGI("udid %{public}s.", GetAnonyString(udid).c_str());
383     {
384         std::lock_guard<std::mutex> mutexLock(deviceInfosMutex_);
385         if (deviceInfo_.find(udid) != deviceInfo_.end()) {
386             networkId = deviceInfo_[udid].second.networkId;
387             LOGI("GetNetworkIdFromCache success networkId %{public}s, udid %{public}s.",
388                 GetAnonyString(networkId).c_str(), GetAnonyString(udid).c_str());
389             return DM_OK;
390         }
391     }
392     return ERR_DM_FAILED;
393 }
394 } // namespace DistributedHardware
395 } // namespace OHOS
396