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