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