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