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