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 "messenger_device_status_manager.h"
17
18 #include <cstdlib>
19 #include <memory>
20 #include <mutex>
21 #include <string>
22
23 #include "device_manager.h"
24 #include "securec.h"
25 #include "singleton.h"
26
27 #include "messenger_utils.h"
28 #include "utils_log.h"
29 #include "utils_mem.h"
30 #include "utils_json.h"
31
32 #define PKG_NAME_LEN 128
33 #define TYPE_PLACE 8
34 #define DEFAULT_TYPE 10
35 #define LAPTOP_TYPE 12
36 #define SMART_DISPLAY_TYPE 2562
37
38 static void GetDeviceSecurityLevelByNetworkId(const OHOS::DistributedHardware::DmDeviceInfo &info, int32_t &level);
39
40 namespace OHOS {
41 namespace Security {
42 namespace DeviceSecurityLevel {
43 using namespace OHOS::DistributedHardware;
44
45 class DeviceStatusControlBlock final : public Singleton<DeviceStatusControlBlock> {
46 public:
47 using StateReceiver = std::function<int32_t(const DeviceIdentify *devId, uint32_t status, int32_t level)>;
Reset(const std::string & pkgName,WorkQueue * queue,StateReceiver deviceStatusReceiver)48 void Reset(const std::string &pkgName, WorkQueue *queue, StateReceiver deviceStatusReceiver)
49 {
50 std::lock_guard<std::mutex> lock(mutex_);
51 pkgName_ = pkgName;
52 queue_ = queue;
53 receiver_ = deviceStatusReceiver;
54 }
GetPackageName() const55 const std::string &GetPackageName() const
56 {
57 return pkgName_;
58 }
59
GetStateReceiver() const60 const StateReceiver &GetStateReceiver() const
61 {
62 return receiver_;
63 }
64
GetQueue() const65 WorkQueue *GetQueue() const
66 {
67 return queue_;
68 }
69
70 private:
71 std::mutex mutex_;
72 WorkQueue *queue_ {nullptr};
73 std::string pkgName_ {};
74 StateReceiver receiver_ {nullptr};
75 };
76
77 class DslmStateReceiver final {
78 public:
79 DslmStateReceiver() = default;
80 ~DslmStateReceiver() = default;
81 };
82
83 class DslmDeviceState final : public DeviceStateCallback,
84 public DmInitCallback,
85 public std::enable_shared_from_this<DslmDeviceState> {
86 public:
87 enum State : uint32_t {
88 EVENT_NODE_STATE_OFFLINE = 0,
89 EVENT_NODE_STATE_ONLINE = 1,
90 };
91
92 struct QueueStatusData {
93 DeviceIdentify srcIdentity {0, {0}};
94 uint32_t status {0};
95 uint32_t level {0};
96 };
97
98 DslmDeviceState() = default;
99 ~DslmDeviceState() override = default;
100
OnDeviceOnline(const DmDeviceInfo & deviceInfo)101 void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override
102 {
103 }
104
OnDeviceOffline(const DmDeviceInfo & deviceInfo)105 void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override
106 {
107 MessengerOnNodeStateChange(deviceInfo, EVENT_NODE_STATE_OFFLINE);
108 }
109
OnDeviceChanged(const DmDeviceInfo & deviceInfo)110 void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override
111 {
112 }
113
OnDeviceReady(const DmDeviceInfo & deviceInfo)114 void OnDeviceReady(const DmDeviceInfo &deviceInfo) override
115 {
116 MessengerOnNodeStateChange(deviceInfo, EVENT_NODE_STATE_ONLINE);
117 }
118
OnRemoteDied()119 void OnRemoteDied() override
120 {
121 }
122
MessengerOnNodeStateChange(const DmDeviceInfo & info,State state)123 static void MessengerOnNodeStateChange(const DmDeviceInfo &info, State state)
124 {
125 DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}};
126 int32_t level = 0;
127 if (!MessengerGetDeviceIdentifyByNetworkId(info.networkId, &identity)) {
128 SECURITY_LOG_ERROR("MessengerOnNodeStateChange copy device error");
129 return;
130 }
131 if (state == EVENT_NODE_STATE_ONLINE) {
132 GetDeviceSecurityLevelByNetworkId(info, level);
133 }
134 ProcessDeviceStatusReceiver(&identity, state, level);
135 }
136
ProcessDeviceStatusReceiver(const DeviceIdentify * devId,uint32_t status,int32_t level)137 static void ProcessDeviceStatusReceiver(const DeviceIdentify *devId, uint32_t status, int32_t level)
138 {
139 if (devId == nullptr || devId->length == 0) {
140 SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, invalid input");
141 return;
142 }
143
144 auto queue = DeviceStatusControlBlock::GetInstance().GetQueue();
145 if (queue == nullptr) {
146 SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, invalid queue");
147 return;
148 }
149
150 QueueStatusData *data = new (std::nothrow) QueueStatusData;
151 if (data == nullptr) {
152 SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, malloc result null");
153 return;
154 }
155 data->srcIdentity = *devId;
156 if (level > 0) {
157 data->level = static_cast<uint32_t>(level);
158 }
159 data->status = status;
160
161 uint32_t maskId = MaskDeviceIdentity((const char *)&devId->identity[0], DEVICE_ID_MAX_LEN);
162 SECURITY_LOG_INFO("OnlineStateChange device %{public}x*** change to %{public}s, level is %{public}d", maskId,
163 (status == EVENT_NODE_STATE_ONLINE) ? " online " : " offline ", level);
164
165 auto process = [](const uint8_t *data, uint32_t len) {
166 if (data == nullptr || len == 0) {
167 return;
168 }
169 auto *queueData = static_cast<const QueueStatusData *>(static_cast<const void *>(data));
170 if (len != sizeof(QueueStatusData)) {
171 SECURITY_LOG_ERROR("ProcessDeviceStatusReceived, invalid input");
172 return;
173 }
174 auto processor = DeviceStatusControlBlock::GetInstance().GetStateReceiver();
175 if (processor == nullptr) {
176 SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, invalid queue");
177 return;
178 }
179 processor(&queueData->srcIdentity, queueData->status, queueData->level);
180 delete queueData;
181 };
182 auto input = static_cast<uint8_t *>(static_cast<void *>(data));
183 auto ret = QueueWork(queue, process, input, sizeof(QueueStatusData));
184 if (ret != WORK_QUEUE_OK) {
185 SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, QueueWork failed, ret is %{public}u", ret);
186 delete data;
187 return;
188 }
189 }
190 };
191
MessengerConvertNodeToIdentity(const std::string & networkId,DeviceIdentify & devId)192 static bool MessengerConvertNodeToIdentity(const std::string &networkId, DeviceIdentify &devId)
193 {
194 const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
195
196 std::string udid;
197 int32_t ret = DeviceManager::GetInstance().GetUdidByNetworkId(name, networkId, udid);
198 if (ret != 0) {
199 SECURITY_LOG_ERROR("MessengerConvertNodeToIdentity GetUdidByNetworkId failed = %{public}d", ret);
200 return false;
201 }
202 auto size = (udid.size() < DEVICE_ID_MAX_LEN) ? udid.size() : DEVICE_ID_MAX_LEN;
203
204 static_cast<void>(memset_s(&devId, sizeof(DeviceIdentify), 0, sizeof(DeviceIdentify)));
205 if (memcpy_s(devId.identity, DEVICE_ID_MAX_LEN, udid.c_str(), size) != EOK) {
206 SECURITY_LOG_ERROR("MessengerConvertNodeToIdentity memcpy error");
207 return false;
208 }
209 if (devId.identity[0] == 0) {
210 SECURITY_LOG_ERROR("MessengerConvertNodeToIdentity content error");
211 return false;
212 }
213 devId.length = DEVICE_ID_MAX_LEN;
214 return true;
215 }
216
MessengerGetDeviceNodeBasicInfo(const DeviceIdentify & devId,DmDeviceInfo & info)217 static bool MessengerGetDeviceNodeBasicInfo(const DeviceIdentify &devId, DmDeviceInfo &info)
218 {
219 const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
220
221 std::vector<DmDeviceInfo> deviceList;
222 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(name, "", deviceList);
223 if (ret != 0) {
224 SECURITY_LOG_ERROR("MessengerGetDeviceOnlineStatus GetTrustedDeviceList failed = %{public}d", ret);
225 return false;
226 }
227
228 bool find = false;
229 for (auto const &device : deviceList) {
230 DeviceIdentify curr = {DEVICE_ID_MAX_LEN, {0}};
231 bool convert = MessengerConvertNodeToIdentity(device.networkId, curr);
232 if (convert != true) {
233 continue;
234 }
235
236 if (IsSameDevice(&devId, &curr)) {
237 find = true;
238 info = device;
239 break;
240 }
241 }
242 return find;
243 }
244 } // namespace DeviceSecurityLevel
245 } // namespace Security
246 } // namespace OHOS
247
248 #ifdef __cplusplus
249 extern "C" {
250 #endif
251 using namespace OHOS::Security::DeviceSecurityLevel;
252
GetDeviceSecurityLevelByNetworkId(const OHOS::DistributedHardware::DmDeviceInfo & info,int32_t & level)253 static void GetDeviceSecurityLevelByNetworkId(const OHOS::DistributedHardware::DmDeviceInfo &info, int32_t &level)
254 {
255 const char pkgName[PKG_NAME_LEN + 1] = "ohos.dslm";
256 int32_t ret = DeviceManager::GetInstance().GetDeviceSecurityLevel(pkgName, info.networkId, level);
257 SECURITY_LOG_INFO("GetDeviceSecurityLevelByNetworkId ret = %{public}d, level = %{public}d", ret, level);
258
259 const char *jsonString = static_cast<const char *>(info.extraData.c_str());
260 DslmJsonHandle handle = DslmCreateJson(jsonString);
261 if (handle == nullptr) {
262 return;
263 }
264 uint32_t osType = static_cast<uint32_t>(DslmGetJsonFieldInt(handle, "OS_TYPE"));
265 SECURITY_LOG_INFO("device type is %{public}d", osType);
266 if (info.deviceTypeId == LAPTOP_TYPE || info.deviceTypeId == SMART_DISPLAY_TYPE) {
267 osType = DEFAULT_TYPE;
268 SECURITY_LOG_INFO("deviceTypeId is %{public}d", info.deviceTypeId);
269 }
270 level = static_cast<int32_t>(static_cast<uint32_t>(level) | (osType << TYPE_PLACE));
271 DslmDestroyJson(handle);
272 return;
273 }
274
InitDeviceStatusManager(WorkQueue * queue,const char * pkgName,DeviceStatusReceiver deviceStatusReceiver)275 bool InitDeviceStatusManager(WorkQueue *queue, const char *pkgName, DeviceStatusReceiver deviceStatusReceiver)
276 {
277 if (queue == nullptr || pkgName == nullptr || deviceStatusReceiver == nullptr) {
278 return false;
279 }
280 const std::string name(pkgName);
281 DeviceStatusControlBlock::GetInstance().Reset(name, queue, deviceStatusReceiver);
282
283 auto callback = std::make_shared<DslmDeviceState>();
284 if (callback == nullptr) {
285 SECURITY_LOG_ERROR("DslmDeviceState alloc failed");
286 return false;
287 }
288
289 int tryTimes = 0;
290 int32_t ret = 0;
291 do {
292 tryTimes++;
293 ret = DeviceManager::GetInstance().InitDeviceManager(name, callback);
294 if (ret != 0) {
295 SECURITY_LOG_ERROR("InitDeviceManager failed = %{public}d", ret);
296 MessengerSleep(1); // sleep 1 second and try again
297 continue;
298 }
299 } while (ret != 0 && tryTimes < MAX_TRY_TIMES);
300
301 if (ret != 0) {
302 SECURITY_LOG_ERROR("InitDeviceManager RegNodeDeviceStateCb failed = %{public}d", ret);
303 return false;
304 }
305
306 auto process = [](const DeviceIdentify *devId, int32_t level, void *para) -> int32_t {
307 static_cast<void>(para);
308 DslmDeviceState::ProcessDeviceStatusReceiver(devId, DslmDeviceState::State::EVENT_NODE_STATE_ONLINE, level);
309 return 0;
310 };
311
312 MessengerForEachDeviceProcess(process, nullptr);
313 SECURITY_LOG_INFO("InitDeviceManager RegNodeDeviceStateCb success");
314 return true;
315 }
316
DeInitDeviceStatusManager(void)317 bool DeInitDeviceStatusManager(void)
318 {
319 const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
320 static_cast<void>(DeviceManager::GetInstance().UnInitDeviceManager(name));
321
322 SECURITY_LOG_INFO("DeInitDeviceManager UnregNodeDeviceStateCb success");
323 return true;
324 }
325
MessengerGetDeviceOnlineStatus(const DeviceIdentify * devId,int32_t * level)326 bool MessengerGetDeviceOnlineStatus(const DeviceIdentify *devId, int32_t *level)
327 {
328 if (devId == nullptr) {
329 return false;
330 }
331
332 DmDeviceInfo info;
333 bool result = MessengerGetDeviceNodeBasicInfo(*devId, info);
334 if (result == true && level != nullptr) {
335 GetDeviceSecurityLevelByNetworkId(info, *level);
336 }
337 return result;
338 }
339
MessengerGetSelfDeviceIdentify(DeviceIdentify * devId,int32_t * level)340 bool MessengerGetSelfDeviceIdentify(DeviceIdentify *devId, int32_t *level)
341 {
342 if (devId == nullptr || level == NULL) {
343 return false;
344 }
345
346 const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
347
348 DmDeviceInfo info;
349 int32_t ret = DeviceManager::GetInstance().GetLocalDeviceInfo(name, info);
350 if (ret != 0) {
351 SECURITY_LOG_ERROR("MessengerGetSelfDeviceIdentify GetLocalNodeDeviceInfo failed = %{public}d", ret);
352 return false;
353 }
354
355 bool convert = MessengerConvertNodeToIdentity(info.networkId, *devId);
356 if (convert == false) {
357 return false;
358 }
359
360 GetDeviceSecurityLevelByNetworkId(info, *level);
361 *level = static_cast<int32_t>(static_cast<uint32_t>(*level) & 0xFF);
362
363 uint32_t maskId = MaskDeviceIdentity((const char *)&devId->identity[0], DEVICE_ID_MAX_LEN);
364 SECURITY_LOG_DEBUG("MessengerGetSelfDeviceIdentify device %{public}x***, level is %{public}d", maskId, *level);
365 return true;
366 }
367
MessengerForEachDeviceProcess(const DeviceProcessor processor,void * para)368 void MessengerForEachDeviceProcess(const DeviceProcessor processor, void *para)
369 {
370 if (processor == nullptr) {
371 return;
372 }
373
374 const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
375
376 std::vector<DmDeviceInfo> deviceList;
377 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(name, "", deviceList);
378 if (ret != 0) {
379 SECURITY_LOG_ERROR("MessengerForEachDeviceProcess GetTrustedDeviceList failed = %{public}d", ret);
380 return;
381 }
382
383 for (auto const &device : deviceList) {
384 DeviceIdentify curr = {DEVICE_ID_MAX_LEN, {0}};
385 bool convert = MessengerConvertNodeToIdentity(device.networkId, curr);
386 int32_t level = 0;
387 GetDeviceSecurityLevelByNetworkId(device, level);
388
389 if (convert == true) {
390 processor(&curr, level, para);
391 }
392 }
393 }
394
MessengerGetNetworkIdByDeviceIdentify(const DeviceIdentify * devId,char * networkId,uint32_t len)395 bool MessengerGetNetworkIdByDeviceIdentify(const DeviceIdentify *devId, char *networkId, uint32_t len)
396 {
397 if (devId == nullptr || networkId == nullptr || len == 0) {
398 return false;
399 }
400 DmDeviceInfo info;
401 bool result = MessengerGetDeviceNodeBasicInfo(*devId, info);
402 if (result != true) {
403 return false;
404 }
405
406 int32_t ret = strcpy_s(networkId, len, info.networkId);
407 if (ret != EOK) {
408 SECURITY_LOG_ERROR("MessengerGetNetworkIdByDeviceIdentify strcpy_s error");
409 return false;
410 }
411 return true;
412 }
413
MessengerGetDeviceIdentifyByNetworkId(const char * networkId,DeviceIdentify * devId)414 bool MessengerGetDeviceIdentifyByNetworkId(const char *networkId, DeviceIdentify *devId)
415 {
416 if (networkId == nullptr || devId == nullptr) {
417 SECURITY_LOG_ERROR("MessengerGetDeviceIdentifyByNetworkId input error");
418 return false;
419 }
420 return MessengerConvertNodeToIdentity(networkId, *devId);
421 }
422 #ifdef __cplusplus
423 }
424 #endif
425