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