1 /*
2 * Copyright (C) 2023-2023 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 * Description: cast device data management
15 * Author: zhangge
16 * Create: 2022-10-15
17 */
18
19 #include "cast_device_data_manager.h"
20
21 #include "cast_engine_log.h"
22 #include "cast_service_common.h"
23 #include "utils.h"
24 #include "dm_constants.h"
25 #include "securec.h"
26 #include "json.hpp"
27
28 using nlohmann::json;
29
30 namespace OHOS {
31 namespace CastEngine {
32 namespace CastEngineService {
33 DEFINE_CAST_ENGINE_LABEL("Cast-DeviceDataManager");
34 namespace {
35 using namespace OHOS::DistributedHardware;
36 constexpr int CAST_SESSION_KEY_LENGTH = 16;
37 }
GetInstance()38 CastDeviceDataManager &CastDeviceDataManager::GetInstance()
39 {
40 static CastDeviceDataManager manager{};
41 return manager;
42 }
43
AddDevice(const CastInnerRemoteDevice & device,const DmDeviceInfo & dmDeviceInfo)44 bool CastDeviceDataManager::AddDevice(const CastInnerRemoteDevice &device, const DmDeviceInfo &dmDeviceInfo)
45 {
46 if (device.deviceId.empty() || device.deviceId != dmDeviceInfo.deviceId) {
47 CLOGE("Invalid device id<%s-%s>", device.deviceId.c_str(), dmDeviceInfo.deviceId);
48 return false;
49 }
50 std::lock_guard<std::mutex> lock(mutex_);
51 DeviceInfoCollection data{};
52 for (auto it : devices_) {
53 if (device.deviceId == it.device.deviceId) {
54 data = it;
55 break;
56 }
57 }
58 if (data.device.deviceId.empty()) {
59 data.state = RemoteDeviceState::FOUND;
60 }
61
62 json extraJson = json::parse(dmDeviceInfo.extraData, nullptr, false);
63 if (extraJson.is_discarded()) {
64 CLOGI("extrajson is discarded");
65 data.wifiDeviceInfo = data.wifiDeviceInfo.extraData.size() > 0 ? data.wifiDeviceInfo : dmDeviceInfo;
66 } else if (extraJson.contains(PARAM_KEY_BLE_MAC) && extraJson[PARAM_KEY_BLE_MAC].is_string()) {
67 data.bleDeviceInfo = dmDeviceInfo;
68 } else {
69 data.wifiDeviceInfo = dmDeviceInfo;
70 }
71
72 data.device = device;
73 data.networkId = strlen(dmDeviceInfo.networkId) > 0 ? dmDeviceInfo.networkId : data.networkId;
74 RemoveDeviceLocked(device.deviceId);
75
76 devices_.push_back(data);
77 return true;
78 }
79
HasDevice(const std::string & deviceId)80 bool CastDeviceDataManager::HasDevice(const std::string &deviceId)
81 {
82 std::lock_guard<std::mutex> lock(mutex_);
83 return HasDeviceLocked(deviceId);
84 }
85
UpdateDevice(const CastInnerRemoteDevice & device)86 bool CastDeviceDataManager::UpdateDevice(const CastInnerRemoteDevice &device)
87 {
88 std::lock_guard<std::mutex> lock(mutex_);
89 auto it = GetDeviceLocked(device.deviceId);
90 if (it == devices_.end()) {
91 return false;
92 }
93 if (it->device.deviceName != device.deviceName) {
94 CLOGW("Different devices name: old:%s, new:%s", it->device.deviceName.c_str(), device.deviceName.c_str());
95 }
96
97 it->device = device;
98
99 return true;
100 }
101
RemoveDevice(const std::string & deviceId)102 void CastDeviceDataManager::RemoveDevice(const std::string &deviceId)
103 {
104 std::lock_guard<std::mutex> lock(mutex_);
105 RemoveDeviceLocked(deviceId);
106 }
107
GetDeviceByDeviceId(const std::string & deviceId)108 std::optional<CastInnerRemoteDevice> CastDeviceDataManager::GetDeviceByDeviceId(const std::string &deviceId)
109 {
110 std::lock_guard<std::mutex> lock(mutex_);
111 auto it = GetDeviceLocked(deviceId);
112 if (it == devices_.end()) {
113 return std::nullopt;
114 }
115 return it->device;
116 }
117
GetDeviceByTransId(int transportId)118 std::optional<CastInnerRemoteDevice> CastDeviceDataManager::GetDeviceByTransId(int transportId)
119 {
120 CLOGD("GetDeviceByTransId in.");
121
122 if (transportId <= INVALID_ID) {
123 CLOGE("Invalid session id, %d", transportId);
124 return std::nullopt;
125 }
126
127 std::lock_guard<std::mutex> lock(mutex_);
128 for (auto it = devices_.begin(); it != devices_.end(); it++) {
129 if (it->transportId == transportId) {
130 return it->device;
131 }
132 }
133 return std::nullopt;
134 }
135
GetDmDevice(const std::string & deviceId)136 std::optional<DmDeviceInfo> CastDeviceDataManager::GetDmDevice(const std::string &deviceId)
137 {
138 std::lock_guard<std::mutex> lock(mutex_);
139 auto it = GetDeviceLocked(deviceId);
140 if (it == devices_.end()) {
141 return std::nullopt;
142 }
143 return strlen(it->wifiDeviceInfo.deviceId) > 0 ? it->wifiDeviceInfo : it->bleDeviceInfo;
144 }
145
SetDeviceTransId(const std::string & deviceId,int transportId)146 bool CastDeviceDataManager::SetDeviceTransId(const std::string &deviceId, int transportId)
147 {
148 if (transportId <= INVALID_ID) {
149 CLOGE("Invalid params: id(%d)", transportId);
150 return false;
151 }
152
153 std::lock_guard<std::mutex> lock(mutex_);
154 CLOGD("SetDeviceTransId in.");
155
156 auto it = GetDeviceLocked(deviceId);
157 if (it == devices_.end()) {
158 CLOGE("Device %{public}s has not been added yet.", Utils::Mask(deviceId).c_str());
159 return false;
160 }
161
162 if (it->transportId != INVALID_ID) {
163 CLOGE("Device(%{public}s) has matched a session id(%d) in the DB", Utils::Mask(deviceId).c_str(),
164 it->transportId);
165 return false;
166 }
167 it->transportId = transportId;
168 return true;
169 }
170
GetDeviceTransId(const std::string & deviceId)171 int CastDeviceDataManager::GetDeviceTransId(const std::string &deviceId)
172 {
173 std::lock_guard<std::mutex> lock(mutex_);
174 auto it = GetDeviceLocked(deviceId);
175 if (it == devices_.end()) {
176 return INVALID_ID;
177 }
178 return it->transportId;
179 }
180
ResetDeviceTransId(const std::string & deviceId)181 int CastDeviceDataManager::ResetDeviceTransId(const std::string &deviceId)
182 {
183 CLOGD("ResetDeviceTransId in.");
184
185 std::lock_guard<std::mutex> lock(mutex_);
186 auto it = GetDeviceLocked(deviceId);
187 if (it == devices_.end()) {
188 return INVALID_ID;
189 }
190
191 int tmp = it->transportId;
192 it->transportId = INVALID_ID;
193 return tmp;
194 }
195
SetDeviceRole(const std::string & deviceId,bool isSink)196 bool CastDeviceDataManager::SetDeviceRole(const std::string &deviceId, bool isSink)
197 {
198 std::lock_guard<std::mutex> lock(mutex_);
199 auto it = GetDeviceLocked(deviceId);
200 if (it == devices_.end()) {
201 return false;
202 }
203
204 it->isSink = isSink;
205 return true;
206 }
207
GetDeviceRole(const std::string & deviceId)208 std::optional<bool> CastDeviceDataManager::GetDeviceRole(const std::string &deviceId)
209 {
210 std::lock_guard<std::mutex> lock(mutex_);
211 auto it = GetDeviceLocked(deviceId);
212 if (it == devices_.end()) {
213 return std::nullopt;
214 }
215
216 return it->isSink;
217 }
218
SetDeviceNetworkId(const std::string & deviceId,const std::string & networkId)219 bool CastDeviceDataManager::SetDeviceNetworkId(const std::string &deviceId, const std::string &networkId)
220 {
221 std::lock_guard<std::mutex> lock(mutex_);
222 auto it = GetDeviceLocked(deviceId);
223 if (it == devices_.end()) {
224 return false;
225 }
226
227 it->networkId = networkId;
228 return true;
229 }
230
GetDeviceNetworkId(const std::string & deviceId)231 std::optional<std::string> CastDeviceDataManager::GetDeviceNetworkId(const std::string &deviceId)
232 {
233 std::lock_guard<std::mutex> lock(mutex_);
234 auto it = GetDeviceLocked(deviceId);
235 if (it == devices_.end()) {
236 return std::nullopt;
237 }
238
239 return it->networkId;
240 }
241
SetDeviceIsActiveAuth(const std::string & deviceId,bool isActiveAuth)242 bool CastDeviceDataManager::SetDeviceIsActiveAuth(const std::string &deviceId, bool isActiveAuth)
243 {
244 std::lock_guard<std::mutex> lock(mutex_);
245 auto it = GetDeviceLocked(deviceId);
246 if (it == devices_.end()) {
247 return false;
248 }
249 it->isActiveAuth = isActiveAuth;
250 return true;
251 }
252
GetDeviceIsActiveAuth(const std::string & deviceId)253 std::optional<bool> CastDeviceDataManager::GetDeviceIsActiveAuth(const std::string &deviceId)
254 {
255 std::lock_guard<std::mutex> lock(mutex_);
256 auto it = GetDeviceLocked(deviceId);
257 if (it == devices_.end()) {
258 return std::nullopt;
259 }
260 return it->isActiveAuth;
261 }
262
SetDeviceSessionKey(const std::string & deviceId,const uint8_t * sessionKey)263 bool CastDeviceDataManager::SetDeviceSessionKey(const std::string &deviceId, const uint8_t *sessionKey)
264 {
265 std::lock_guard<std::mutex> lock(mutex_);
266 auto it = GetDeviceLocked(deviceId);
267 if (it == devices_.end()) {
268 return false;
269 }
270
271 if (memcpy_s(it->device.sessionKey, CAST_SESSION_KEY_LENGTH, sessionKey, CAST_SESSION_KEY_LENGTH) != 0) {
272 return false;
273 }
274 it->device.sessionKeyLength = CAST_SESSION_KEY_LENGTH;
275
276 return true;
277 }
278
SetDeviceIp(const std::string & deviceId,const std::string & localIp,const std::string & remoteIp)279 bool CastDeviceDataManager::SetDeviceIp(const std::string &deviceId, const std::string &localIp,
280 const std::string &remoteIp)
281 {
282 std::lock_guard<std::mutex> lock(mutex_);
283 auto it = GetDeviceLocked(deviceId);
284 if (it == devices_.end()) {
285 return false;
286 }
287
288 it->device.localIp = localIp;
289 it->device.remoteIp = remoteIp;
290 return true;
291 }
292
SetDeviceChannleType(const std::string & deviceId,const ChannelType & channelType)293 bool CastDeviceDataManager::SetDeviceChannleType(const std::string &deviceId, const ChannelType &channelType)
294 {
295 std::lock_guard<std::mutex> lock(mutex_);
296 auto it = GetDeviceLocked(deviceId);
297 if (it == devices_.end()) {
298 return false;
299 }
300
301 it->device.channelType = channelType;
302 return true;
303 }
304
SetDeviceState(const std::string & deviceId,RemoteDeviceState state)305 bool CastDeviceDataManager::SetDeviceState(const std::string &deviceId, RemoteDeviceState state)
306 {
307 std::lock_guard<std::mutex> lock(mutex_);
308 auto it = GetDeviceLocked(deviceId);
309 if (it == devices_.end()) {
310 return false;
311 }
312 it->state = state;
313 return true;
314 }
315
GetDeviceState(const std::string & deviceId)316 RemoteDeviceState CastDeviceDataManager::GetDeviceState(const std::string &deviceId)
317 {
318 std::lock_guard<std::mutex> lock(mutex_);
319 return GetDeviceStateLocked(deviceId);
320 }
321
IsDeviceConnected(const std::string & deviceId)322 bool CastDeviceDataManager::IsDeviceConnected(const std::string &deviceId)
323 {
324 return GetDeviceState(deviceId) == RemoteDeviceState::CONNECTED;
325 }
326
IsDeviceConnecting(const std::string & deviceId)327 bool CastDeviceDataManager::IsDeviceConnecting(const std::string &deviceId)
328 {
329 return GetDeviceState(deviceId) == RemoteDeviceState::CONNECTING;
330 }
331
IsDeviceUsed(const std::string & deviceId)332 bool CastDeviceDataManager::IsDeviceUsed(const std::string &deviceId)
333 {
334 auto state = GetDeviceState(deviceId);
335 return state == RemoteDeviceState::CONNECTING || state == RemoteDeviceState::CONNECTED;
336 }
337
GetDeviceStateLocked(const std::string & deviceId)338 RemoteDeviceState CastDeviceDataManager::GetDeviceStateLocked(const std::string &deviceId)
339 {
340 auto it = GetDeviceLocked(deviceId);
341 return (it != devices_.end()) ? it->state : RemoteDeviceState::UNKNOWN;
342 }
343
RemoveDeviceLocked(const std::string & deviceId)344 bool CastDeviceDataManager::RemoveDeviceLocked(const std::string &deviceId)
345 {
346 CLOGI("RemoveDeviceLocked in %{public}s", Utils::Mask(deviceId).c_str());
347 if (deviceId.empty()) {
348 CLOGE("Empty device id!");
349 return false;
350 }
351
352 for (auto it = devices_.begin(); it != devices_.end(); it++) {
353 if (it->device.deviceId == deviceId) {
354 devices_.erase(it);
355 return true;
356 }
357 }
358
359 return false;
360 }
361
GetDeviceLocked(const std::string & deviceId)362 std::vector<CastDeviceDataManager::DeviceInfoCollection>::iterator CastDeviceDataManager::GetDeviceLocked(
363 const std::string &deviceId)
364 {
365 if (deviceId.empty()) {
366 CLOGE("Empty device id!");
367 return devices_.end();
368 }
369
370 for (auto it = devices_.begin(); it != devices_.end(); it++) {
371 if (it->device.deviceId == deviceId) {
372 return it;
373 }
374 }
375 CLOGW("Can't find the device(%s)!", deviceId.c_str());
376 return devices_.end();
377 }
378
HasDeviceLocked(const std::string & deviceId)379 bool CastDeviceDataManager::HasDeviceLocked(const std::string &deviceId)
380 {
381 if (deviceId.empty()) {
382 CLOGE("Empty device id!");
383 return false;
384 }
385
386 for (const auto &device : devices_) {
387 if (device.device.deviceId == deviceId) {
388 return true;
389 }
390 }
391
392 return false;
393 }
394
GetSessionIdByDeviceId(const std::string & deviceId)395 int CastDeviceDataManager::GetSessionIdByDeviceId(const std::string &deviceId)
396 {
397 if (deviceId.empty()) {
398 CLOGE("Empty device id!");
399 return INVALID_ID;
400 }
401
402 std::lock_guard<std::mutex> lock(mutex_);
403 for (auto it = devices_.begin(); it != devices_.end(); it++) {
404 if (it->device.deviceId == deviceId) {
405 return it->device.sessionId;
406 }
407 }
408 return INVALID_ID;
409 }
410
GetCastSessionIdByDeviceId(const std::string & deviceId)411 int CastDeviceDataManager::GetCastSessionIdByDeviceId(const std::string &deviceId)
412 {
413 if (deviceId.empty()) {
414 CLOGE("Empty device id!");
415 return INVALID_ID;
416 }
417
418 std::lock_guard<std::mutex> lock(mutex_);
419 for (auto it = devices_.begin(); it != devices_.end(); it++) {
420 if (it->device.deviceId == deviceId) {
421 return it->device.localCastSessionId;
422 }
423 }
424
425 return INVALID_ID;
426 }
427
UpdateDeviceByDeviceId(const std::string & deviceId)428 bool CastDeviceDataManager::UpdateDeviceByDeviceId(const std::string &deviceId)
429 {
430 CLOGI("UpdateDeviceByDeviceId in %{public}s", Utils::Mask(deviceId).c_str());
431 if (deviceId.empty()) {
432 CLOGE("Empty device id!");
433 return false;
434 }
435 std::lock_guard<std::mutex> lock(mutex_);
436
437 for (auto it = devices_.begin(); it != devices_.end(); it++) {
438 if (it->device.deviceId == deviceId) {
439 it->state = RemoteDeviceState::UNKNOWN;
440 it->localSessionId = INVALID_ID;
441 it->transportId = INVALID_ID;
442 it->isActiveAuth = false;
443 it->device.sessionId = INVALID_ID;
444 it->device.localCastSessionId = INVALID_ID;
445 return true;
446 }
447 }
448 return false;
449 }
450
GetDeviceNameByDeviceId(const std::string & deviceId)451 std::pair<std::string, std::string> CastDeviceDataManager::GetDeviceNameByDeviceId(const std::string &deviceId)
452 {
453 std::lock_guard<std::mutex> lock(mutex_);
454 auto it = GetDeviceLocked(deviceId);
455 std::pair<std::string, std::string> deviceName ("", "");
456 if (it == devices_.end()) {
457 CLOGE("No device found");
458 return deviceName;
459 }
460
461 if (strlen(it->wifiDeviceInfo.deviceName) > 0) {
462 deviceName.first = it->wifiDeviceInfo.deviceName;
463 deviceName.second = "WIFI";
464 return deviceName;
465 } else if (strlen(it->bleDeviceInfo.deviceName) > 0) {
466 deviceName.first = it->bleDeviceInfo.deviceName;
467 deviceName.second = "BLE";
468 return deviceName;
469 }
470
471 CLOGW("Device name is empty");
472 return deviceName;
473 }
474
IsDoubleFrameDevice(const std::string & deviceId)475 bool CastDeviceDataManager::IsDoubleFrameDevice(const std::string &deviceId)
476 {
477 CLOGI("IsDoubleFrameDevice in");
478 if (deviceId.empty()) {
479 CLOGE("Empty device id!");
480 return false;
481 }
482 std::lock_guard<std::mutex> lock(mutex_);
483 for (auto it = devices_.begin(); it != devices_.end(); it++) {
484 if (it->device.deviceId == deviceId) {
485 return !it->device.customData.empty() ? true : false;
486 }
487 }
488 return false;
489 }
490
RemoveDeviceInfo(std::string deviceId,bool isWifi)491 bool CastDeviceDataManager::RemoveDeviceInfo(std::string deviceId, bool isWifi)
492 {
493 CLOGI("RemoveDeviceInfo in %{public}s", Utils::Mask(deviceId).c_str());
494 std::lock_guard<std::mutex> lock(mutex_);
495 auto it = GetDeviceLocked(deviceId);
496 if (it == devices_.end()) {
497 CLOGE("No device found");
498 return false;
499 }
500 if (isWifi) {
501 it->wifiDeviceInfo = {};
502 it->device.wifiIp = "";
503 it->device.wifiPort = 0;
504 it->device.isWifiFresh = false;
505 uint32_t coap = static_cast<uint32_t>(NotifyMediumType::COAP);
506 it->device.mediumTypes = (it->device.mediumTypes | coap) ^ coap;
507 } else {
508 it->bleDeviceInfo = {};
509 it->device.bleMac = "";
510 it->device.isBleFresh = false;
511 uint32_t ble = static_cast<uint32_t>(NotifyMediumType::BLE);
512 it->device.mediumTypes = (it->device.mediumTypes | ble) ^ ble;
513 }
514 return true;
515 }
516
SetDeviceNotFresh(const std::string & deviceId)517 bool CastDeviceDataManager::SetDeviceNotFresh(const std::string &deviceId)
518 {
519 CLOGI("in %{public}s", Utils::Mask(deviceId).c_str());
520 std::lock_guard<std::mutex> lock(mutex_);
521 auto it = GetDeviceLocked(deviceId);
522 if (it == devices_.end()) {
523 CLOGE("No device found %s", deviceId.c_str());
524 return false;
525 }
526
527 it->device.isWifiFresh = false;
528 it->device.isBleFresh = false;
529 it->device.mediumTypes = 0;
530 return true;
531 }
532
533 } // namespace CastEngineService
534 } // namespace CastEngine
535 } // namespace OHOS
536