• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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