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: implement the cast source connect
15 * Author: zhangge
16 * Create: 2022-08-23
17 */
18
19 #include "connection_manager.h"
20
21 #include <thread>
22
23 #include "dm_device_info.h"
24 #include "dm_constants.h"
25 #include "json.hpp"
26 #include "securec.h"
27
28 #include "cast_engine_dfx.h"
29 #include "cast_engine_errors.h"
30 #include "cast_engine_log.h"
31 #include "discovery_manager.h"
32 #include "session.h"
33 #include "softbus_common.h"
34 #include "utils.h"
35 #include "openssl/rand.h"
36 #include "encrypt_decrypt.h"
37 #include "utils.h"
38 #include <iconv.h>
39 #include "radar_constants.h"
40
41 using nlohmann::json;
42 using namespace OHOS::DistributedHardware;
43 using OHOS::DistributedHardware::DeviceManager;
44 using OHOS::DistributedHardware::PeerTargetId;
45
46 namespace OHOS {
47 namespace CastEngine {
48 namespace CastEngineService {
49 DEFINE_CAST_ENGINE_LABEL("Cast-Connection-Manager");
50 namespace {
51 using namespace OHOS::DistributedHardware;
52
53 constexpr int SOFTBUS_OK = 0;
54
55 const std::string AUTH_WITH_PIN = "1";
56
57 const std::string VERSION_KEY = "version";
58 const std::string OPERATION_TYPE_KEY = "operType";
59 const std::string SEQUENCE_NUMBER = "sequenceNumber";
60 const std::string DATA_KEY = "data";
61
62 const std::string DEVICE_ID_KEY = "deviceId";
63 const std::string DEVICE_NAME_KEY = "deviceName";
64 const std::string KEY_SESSION_ID = "sessionId";
65 const std::string PROTOCOL_TYPE_KEY = "protocolType";
66 const std::string KEY_TRANSFER_MODE = "transferMode";
67 const std::string DEVICE_CAST_SOURCE = "deviceCastSource";
68 const std::string PORT_KEY = "port";
69 const std::string SOURCE_IP_KEY = "sourceIp";
70 const std::string SINK_IP_KEY = "sinkIp";
71 const std::string TYPE_SESSION_KEY = "sessionKey";
72
73 constexpr int TRANSFER_MODE_SOFTBUS_SINGLE = 2;
74 constexpr int SESSION_KEY_LENGTH = 16;
75
76 const std::string VERSION = "OH1.0";
77 constexpr int OPERATION_CONSULT = 3;
78
79 const std::map<uint16_t, DeviceType> DEVICE_TYPE_CONVERT_MAP = {
80 { DEVICE_TYPE_TV, DeviceType::DEVICE_HW_TV },
81 { DEVICE_TYPE_CAR, DeviceType::DEVICE_HICAR },
82 { DEVICE_TYPE_PAD, DeviceType::DEVICE_MATEBOOK },
83 { DEVICE_TYPE_PC, DeviceType::DEVICE_MATEBOOK },
84 { DEVICE_TYPE_2IN1, DeviceType::DEVICE_MATEBOOK },
85 };
86
87 const std::map<uint16_t, SubDeviceType> SUB_DEVICE_TYPE_CONVERT_MAP = {
88 { DEVICE_TYPE_PAD, SubDeviceType::SUB_DEVICE_MATEBOOK_PAD },
89 };
90
ConvertDeviceType(uint16_t deviceTypeId)91 DeviceType ConvertDeviceType(uint16_t deviceTypeId)
92 {
93 return DEVICE_TYPE_CONVERT_MAP.count(deviceTypeId) ?
94 DEVICE_TYPE_CONVERT_MAP.at(deviceTypeId) : DeviceType::DEVICE_CAST_PLUS;
95 }
96
ConvertSubDeviceType(uint16_t deviceTypeId)97 SubDeviceType ConvertSubDeviceType(uint16_t deviceTypeId)
98 {
99 return SUB_DEVICE_TYPE_CONVERT_MAP.count(deviceTypeId) ?
100 SUB_DEVICE_TYPE_CONVERT_MAP.at(deviceTypeId) : SubDeviceType::SUB_DEVICE_DEFAULT;
101 }
102
103 /*
104 * send to json key auth version, hichain 1.0 or 2.0
105 */
106 const std::string AUTH_VERSION_KEY = "authVersion";
107 const std::string AUTH_VERSION_1 = "1.0";
108 const std::string AUTH_VERSION_2 = "2.0";
109 const std::string AUTH_VERSION_3 = "DM";
110
111 const std::string KEY_BIND_TARGET_ACTION = "action";
112 constexpr int ACTION_CONNECT_DEVICE = 0;
113 constexpr int ACTION_QUERY_P2P_IP = 1;
114 constexpr int ACTION_SEND_MESSAGE = 2;
115
116 const std::string KEY_LOCAL_P2P_IP = "localP2PIp";
117 const std::string KEY_REMOTE_P2P_IP = "remoteP2PIp";
118 const std::string NETWORK_ID = "networkId";
119
120 const std::string TIME_RECORD = "TimeRecord";
121 const std::string TOTAL_AUTH_TIME = "totalAuthTime";
122 const std::string TIME_RECORD_STRING = "timeRecordString";
123
DeviceDiscoveryWriteWrap(const std::string & funcName,const std::string & puid)124 void DeviceDiscoveryWriteWrap(const std::string& funcName, const std::string& puid)
125 {
126 HiSysEventWriteWrap(funcName, {
127 {"BIZ_SCENE", static_cast<int32_t>(BIZSceneType::DEVICE_DISCOVERY)},
128 {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_END)},
129 {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_DISCOVERY)},
130 {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
131 {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
132 {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
133 {"LOCAL_SESS_NAME", ""},
134 {"PEER_SESS_NAME", ""},
135 {"PEER_UDID", puid}});
136 }
137
EstablishConsultWriteWrap(const std::string & funcName,int sceneType,const std::string & puid)138 void EstablishConsultWriteWrap(const std::string& funcName, int sceneType, const std::string& puid)
139 {
140 HiSysEventWriteWrap(funcName, {
141 {"BIZ_SCENE", sceneType},
142 {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::ESTABLISH_CONSULT_SESSION)},
143 {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_IDLE)},
144 {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
145 {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
146 {"LOCAL_SESS_NAME", ""},
147 {"PEER_SESS_NAME", ""},
148 {"PEER_UDID", puid}});
149 }
150
151 } // namespace
152
153 namespace SoftBus {
154 constexpr char PEER_NAME[] = "CastPlusSessionName";
155 int32_t g_bindSocketId = INVALID_ID;
156
OnShutdown(int32_t socket,ShutdownReason reason)157 static void OnShutdown(int32_t socket, ShutdownReason reason)
158 {
159 CLOGI("OnShutdown, socket id = %{public}d", socket);
160 auto device = CastDeviceDataManager::GetInstance().GetDeviceByTransId(socket);
161 if (device == std::nullopt) {
162 CLOGE("Failed to get device by socketId.");
163 return;
164 }
165 CLOGI("notify disconnect %{public}d", socket);
166 }
167
OnBytes(int32_t socket,const void * data,uint32_t dataLen)168 static void OnBytes(int32_t socket, const void *data, uint32_t dataLen)
169 {
170 CLOGI("OnBytes, socket id = %{public}d", socket);
171 ConnectionManager::GetInstance().OnConsultDataReceivedFromSink(socket, data, dataLen);
172 }
173
174 QosTV mirrorQos1st[] = {
175 { .qos = QOS_TYPE_MIN_BW, .value = 80 * 1024 * 1024 }, // 最小带宽80M
176 { .qos = QOS_TYPE_MAX_LATENCY, .value = 16000 }, // 最大建链时延16s
177 { .qos = QOS_TYPE_RTT_LEVEL, .value = QosRttLevel::RTT_LEVEL_LOW },
178 };
179
180 QosTV mirrorQos2nd[] = {
181 { .qos = QOS_TYPE_MIN_BW, .value = 80 * 1024 * 1024 }, // 最小带宽80M
182 { .qos = QOS_TYPE_MAX_LATENCY, .value = 6000 }, // 最大建链时延6s
183 { .qos = QOS_TYPE_RTT_LEVEL, .value = QosRttLevel::RTT_LEVEL_LOW },
184 };
185
186 QosTV singleMirrorQos[] = {
187 { .qos = QOS_TYPE_MIN_BW, .value = 80 * 1024 * 1024 }, // 最小带宽80M
188 { .qos = QOS_TYPE_MAX_LATENCY, .value = 5000 }, // 最大建链时延5s
189 { .qos = QOS_TYPE_RTT_LEVEL, .value = QosRttLevel::RTT_LEVEL_LOW },
190 };
191
192 QosTV streamQos1st[] = {
193 { .qos = QOS_TYPE_MIN_BW, .value = 4 * 1024 * 1024 }, // 最小带宽4M, Wifi优先
194 { .qos = QOS_TYPE_MAX_LATENCY, .value = 16000 }, // 最大建链时延16s
195 };
196
197 QosTV streamQos2nd[] = {
198 { .qos = QOS_TYPE_MIN_BW, .value = 4 * 1024 * 1024 }, // 最小带宽4M, Wifi优先
199 { .qos = QOS_TYPE_MAX_LATENCY, .value = 6000 }, // 最大建链时延6s
200 };
201
202 QosTV singleStreamQos[] = {
203 { .qos = QOS_TYPE_MIN_BW, .value = 80 * 1024 * 1024 }, // 最小带宽80M
204 { .qos = QOS_TYPE_MAX_LATENCY, .value = 5000 }, // 最大建链时延5s
205 };
206
207 ISocketListener listener = {
208 .OnShutdown = OnShutdown,
209 .OnBytes = OnBytes,
210 };
211
CreateSocket(const std::optional<std::string> & networkId,const ProtocolType & protocolType)212 int32_t CreateSocket(const std::optional<std::string> &networkId, const ProtocolType &protocolType)
213 {
214 CLOGI("CreateSocket in, protocol type is %{public}d", protocolType);
215 SocketInfo messageSessionInfo = {
216 .name = (char *)PEER_NAME,
217 .peerName = (char *)PEER_NAME,
218 .peerNetworkId = (char *)networkId->c_str(),
219 .pkgName = (char *)PKG_NAME,
220 .dataType = DATA_TYPE_BYTES,
221 };
222
223 int32_t socketId = Socket(messageSessionInfo);
224 if (socketId <= 0) {
225 CLOGE("Create fail socket = %{public}d", socketId);
226 return socketId;
227 }
228
229 CLOGI("Create socket successfully");
230 return socketId;
231 }
232
BindSocket(int32_t socketId,const ProtocolType & protocolType,bool isSingle,int32_t times)233 int BindSocket(int32_t socketId, const ProtocolType &protocolType, bool isSingle, int32_t times)
234 {
235 CLOGI("BindSocket in, protocol type is %{public}d isSingle:%{public}d", protocolType, isSingle);
236 Utils::SetFirstTokenID();
237
238 if (socketId <= INVALID_ID) {
239 CLOGE("bind socket = %{public}d error", socketId);
240 return socketId;
241 }
242
243 int32_t result = INVALID_ID;
244 // Synchronization method. A failure message is returned after timeout.
245 if (protocolType == ProtocolType::CAST_PLUS_STREAM) {
246 if (isSingle) {
247 result = Bind(socketId, singleStreamQos, sizeof(singleStreamQos) / sizeof(QosTV), &SoftBus::listener);
248 } else {
249 if (times == 1) {
250 result = Bind(socketId, streamQos1st, sizeof(streamQos1st) / sizeof(QosTV), &SoftBus::listener);
251 } else {
252 result = Bind(socketId, streamQos2nd, sizeof(streamQos2nd) / sizeof(QosTV), &SoftBus::listener);
253 }
254 }
255 } else {
256 if (isSingle) {
257 result = Bind(socketId, singleMirrorQos, sizeof(singleMirrorQos) / sizeof(QosTV), &SoftBus::listener);
258 } else {
259 if (times == 1) {
260 result = Bind(socketId, mirrorQos1st, sizeof(mirrorQos1st) / sizeof(QosTV), &SoftBus::listener);
261 } else {
262 result = Bind(socketId, mirrorQos2nd, sizeof(mirrorQos2nd) / sizeof(QosTV), &SoftBus::listener);
263 }
264 }
265 }
266 if (result != SOFTBUS_OK) {
267 CLOGE("Bind fail result = %{public}d", result);
268 return result;
269 }
270
271 CLOGI("Bind socket successfully");
272 return SOFTBUS_OK;
273 }
274 } // namespace SoftBus
275 constexpr static int SECOND_BYTE_OFFSET = 8;
276 constexpr static int THIRD_BYTE_OFFSET = 16;
277 constexpr static int FOURTH_BYTE_OFFSET = 24;
278
279 constexpr static int INT_FOUR = 4;
280
281 /*
282 * auth success
283 */
284 constexpr int AUTH_SUCCESS_FROM_SINK = 0;
285 /*
286 * connection failed
287 */
288 constexpr int CONNECTION_FAILED = 9;
289
290 /*
291 * send to json key consultResult
292 */
293 const std::string CONSULT_RESULT = "consultResult";
294
295 // consult key
296 const std::string ACCOUNT_ID_KEY = "accountId";
297 const std::string USER_ID_KEY = "userId";
298
299 /*
300 * User's unusual action or other event scenarios could cause changing of STATE or RESULT which delivered
301 * by DM.
302 */
303 const std::map<int, int32_t> CastBindTargetCallback::RESULT_REASON_MAP = {
304 // SINK peer click distrust button during 3-state authentication.
305 { ERR_DM_AUTH_PEER_REJECT, REASON_DISTRUST_BY_SINK },
306 // SINK peer click cancel button during pin code inputting.
307 { ERR_DM_BIND_USER_CANCEL_PIN_CODE_DISPLAY, REASON_CANCEL_BY_SINK },
308 // SOURCE peer input wrong pin code up to 3 times
309 { ERR_DM_BIND_PIN_CODE_ERROR, REASON_PIN_CODE_OVER_RETRY },
310 // SOURCE peer click cancel button during pin code inputting.
311 { ERR_DM_BIND_USER_CANCEL_ERROR, REASON_CANCEL_BY_SOURCE },
312 // User interupt binding.
313 { STOP_BIND, REASON_STOP_BIND_BY_SOURCE }
314 };
315
316 const std::map<int, int32_t> CastBindTargetCallback::STATUS_REASON_MAP = {
317 // DEFAULT event
318 { DmAuthStatus::STATUS_DM_AUTH_DEFAULT, REASON_DEFAULT },
319 // Sink peer click trust during 3-state authentication.
320 { DmAuthStatus::STATUS_DM_SHOW_PIN_INPUT_UI, REASON_TRUST_BY_SINK },
321 // input right pin code, so close input dialog and show connecting dialog
322 { DmAuthStatus::STATUS_DM_CLOSE_PIN_INPUT_UI, REASON_BIND_COMPLETED },
323 // Waiting for user to click confirm
324 { DmAuthStatus::STATUS_DM_SHOW_AUTHORIZE_UI, REASON_SHOW_TRUST_SELECT_UI }
325 };
326
GetInstance()327 ConnectionManager &ConnectionManager::GetInstance()
328 {
329 static ConnectionManager instance{};
330 return instance;
331 }
332
Init(std::shared_ptr<IConnectionManagerListener> listener)333 void ConnectionManager::Init(std::shared_ptr<IConnectionManagerListener> listener)
334 {
335 CLOGI("ConnectionManager init start");
336 if (listener == nullptr) {
337 CLOGE("The input listener is null!");
338 return;
339 }
340
341 if (HasListener()) {
342 CLOGE("Already inited");
343 return;
344 }
345
346 if (DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "",
347 std::make_shared<CastDeviceStateCallback>()) != DM_OK) {
348 CLOGE("Failed to register device state callback");
349 return;
350 }
351
352 SetListener(listener);
353 CLOGD("ConnectionManager init done");
354 }
355
Deinit()356 void ConnectionManager::Deinit()
357 {
358 CLOGI("Deinit start");
359 ResetListener();
360 DisableDiscoverable();
361 DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
362 }
363
IsDeviceTrusted(const std::string & deviceId,std::string & networkId)364 bool ConnectionManager::IsDeviceTrusted(const std::string &deviceId, std::string &networkId)
365 {
366 std::vector<DmDeviceInfo> trustedDevices;
367 if (DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", trustedDevices) != DM_OK) {
368 CLOGE("Fail to get TrustedDeviceList from DM.");
369 return false;
370 }
371
372 for (const auto &device : trustedDevices) {
373 if (device.deviceId == deviceId) {
374 networkId = device.networkId;
375 CLOGI("Device: %{public}s has been trusted.", Utils::Mask(deviceId).c_str());
376 return true;
377 }
378 }
379 CLOGI("Device: %{public}s has not been trusted yet.", Utils::Mask(deviceId).c_str());
380
381 return false;
382 }
383
GetDmDeviceInfo(const std::string & deviceId)384 DmDeviceInfo ConnectionManager::GetDmDeviceInfo(const std::string &deviceId)
385 {
386 std::vector<DmDeviceInfo> trustedDevices;
387 if (DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", trustedDevices) != DM_OK) {
388 CLOGE("GetTrustedDeviceList fail");
389 return {};
390 }
391
392 for (const auto &device : trustedDevices) {
393 if (device.deviceId == deviceId) {
394 return device;
395 }
396 }
397 CLOGW("Can't find device(%{public}s)", Utils::Mask(deviceId).c_str());
398
399 return {};
400 }
401
EnableDiscoverable()402 bool ConnectionManager::EnableDiscoverable()
403 {
404 std::lock_guard lock(mutex_);
405 if (isDiscoverable_) {
406 CLOGW("service has been set discoverable");
407 return true;
408 }
409
410 isDiscoverable_ = true;
411 return true;
412 }
413
DisableDiscoverable()414 bool ConnectionManager::DisableDiscoverable()
415 {
416 std::lock_guard lock(mutex_);
417 if (!isDiscoverable_) {
418 return true;
419 }
420
421 isDiscoverable_ = false;
422 return true;
423 }
424
GrabDevice()425 void ConnectionManager::GrabDevice()
426 {
427 CLOGI("GrabDevice in");
428 if (grabState_ == DeviceGrabState::NO_GRAB) {
429 CLOGE("DeviceGrabState: NO_GRAB");
430 return;
431 }
432 if (listener_ == nullptr) {
433 CLOGE("listener_ nullptr.");
434 return;
435 }
436 listener_->GrabDevice(sessionId_);
437 }
438
OpenConsultSession(const CastInnerRemoteDevice & device)439 bool ConnectionManager::OpenConsultSession(const CastInnerRemoteDevice &device)
440 {
441 CLOGI("start open consult session");
442 // The session can only be opened using a network ID instead of a UDID in OH system
443 auto networkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(device.deviceId);
444 if (networkId == std::nullopt) {
445 CLOGE("networkId is null");
446 return false;
447 }
448
449 EstablishConsultWriteWrap(__func__, GetBIZSceneType(GetProtocolType()), GetAnonymousDeviceID(device.deviceId));
450 int32_t errorCode = SUCCESS;
451 int socketId = OpenSoftBusSocket(networkId, device, errorCode);
452 if (socketId <= INVALID_ID) {
453 CLOGE("session id invalid");
454 NotifyConnectStage(device, ConnectStageResult::DISCONNECT_START, REASON_DEFAULT);
455 return false;
456 }
457
458 OnConsultSessionOpened(socketId, true);
459 HiSysEventWriteWrap(__func__, {
460 {"BIZ_SCENE", GetBIZSceneType(GetProtocolType())},
461 {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::ESTABLISH_CONSULT_SESSION)},
462 {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
463 {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
464 {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
465 {"LOCAL_SESS_NAME", ""},
466 {"PEER_SESS_NAME", ""},
467 {"PEER_UDID", GetAnonymousDeviceID(device.deviceId)}});
468
469 UpdateDeviceState(device.deviceId, RemoteDeviceState::CONNECTED);
470 CLOGI("Out, socketId = %{public}d", socketId);
471 return true;
472 }
473
OnConsultDataReceived(int transportId,const void * data,unsigned int dataLen)474 void ConnectionManager::OnConsultDataReceived(int transportId, const void *data, unsigned int dataLen)
475 {
476 std::string dataStr(static_cast<const char *>(data), dataLen);
477 CLOGD("Received data: len:%{public}u, data:%s", dataLen, dataStr.c_str());
478
479 auto device = GetRemoteFromJsonData(dataStr);
480 if (device == nullptr) {
481 return;
482 }
483 const std::string &deviceId = device->deviceId;
484 auto dmDevice = GetDmDeviceInfo(deviceId);
485 if (deviceId.compare(dmDevice.deviceId) != 0) {
486 CLOGE("Failed to get DmDeviceInfo");
487 return;
488 }
489
490 constexpr int32_t sleepTimeMs = 50;
491 constexpr int32_t retryTimes = 20;
492 int castSessionId = GetCastSessionId(transportId);
493 for (int32_t retryTime = 1; castSessionId == INVALID_ID && retryTime < retryTimes; retryTime++) {
494 CLOGD("Retry for the %d(th) time after sleeping %dms", retryTime, sleepTimeMs);
495 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
496 castSessionId = GetCastSessionId(transportId);
497 }
498
499 if (castSessionId == INVALID_ID) {
500 CLOGE("Invalid CastSessionId!");
501 return;
502 }
503 CLOGI("protocolType is %d", device->protocolType);
504 if (device->protocolType == ProtocolType::CAST_PLUS_STREAM) {
505 SetSessionProtocolType(castSessionId, device->protocolType);
506 }
507 if (!listener_) {
508 CLOGE("Detect absence of listener_.");
509 return;
510 }
511 listener_->ReportSessionCreate(castSessionId);
512 device->localCastSessionId = castSessionId;
513 if (!CastDeviceDataManager::GetInstance().AddDevice(*device, dmDevice)) {
514 return;
515 }
516 if (!CastDeviceDataManager::GetInstance().SetDeviceRole(deviceId, true) ||
517 !UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTED)) {
518 CastDeviceDataManager::GetInstance().RemoveDevice(deviceId);
519 return;
520 }
521 if (!listener_->NotifyRemoteDeviceIsReady(castSessionId, *device)) {
522 CastDeviceDataManager::GetInstance().RemoveDevice(deviceId);
523 }
524
525 DestroyConsulationSession(deviceId);
526 }
527
GetCastSessionId(int transportId)528 int ConnectionManager::GetCastSessionId(int transportId)
529 {
530 std::lock_guard<std::mutex> lock(mutex_);
531 if (transIdToCastSessionIdMap_.count(transportId) == 1) {
532 return transIdToCastSessionIdMap_[transportId];
533 } else {
534 CLOGE("Invalid transport id:%{public}d", transportId);
535 return INVALID_ID;
536 }
537 }
538
OnConsultSessionOpened(int transportId,bool isSource)539 bool ConnectionManager::OnConsultSessionOpened(int transportId, bool isSource)
540 {
541 auto time = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
542 auto openSessionCost = time.time_since_epoch().count() - openSessionTime_;
543 CLOGI("%{public}s, openSession:%{public}lld, total %{public}lld, unit:ms", authTimeString_.c_str(),
544 openSessionCost, totalAuthTime_ + openSessionCost);
545 std::thread([transportId, isSource]() {
546 Utils::SetThreadName("OnConsultSessionOpened");
547 if (isSource) {
548 auto device = CastDeviceDataManager::GetInstance().GetDeviceByTransId(transportId);
549 if (device == std::nullopt) {
550 CLOGE("Failed to get device by sessionId.");
551 return;
552 }
553
554 bool isWifiChannelFirst = ConnectionManager::GetInstance().IsWifiChannelFirst(device->deviceId);
555 if (isWifiChannelFirst) {
556 CLOGE("select wifi channel localip %s, remoteIp %s", (device->localWifiIp).c_str(),
557 (device->wifiIp).c_str());
558 CastDeviceDataManager::GetInstance().SetDeviceIp(device->deviceId, device->localWifiIp, device->wifiIp);
559 }
560 if (ConnectionManager::GetInstance().IsHuaweiDevice(*device) && !isWifiChannelFirst) {
561 ConnectionManager::GetInstance().QueryP2PIp(*device);
562 } else {
563 ConnectionManager::GetInstance().NotifyConnectStage(*device, ConnectStageResult::AUTH_SUCCESS);
564 }
565 return;
566 }
567 ConnectionManager::GetInstance().GrabDevice();
568 ConnectionManager::GetInstance().NotifySessionIsReady(transportId);
569 }).detach();
570
571 return true;
572 }
573
OnConsultDataReceivedFromSink(int transportId,const void * data,unsigned int dataLen)574 void ConnectionManager::OnConsultDataReceivedFromSink(int transportId, const void *data, unsigned int dataLen)
575 {
576 std::string dataString(reinterpret_cast<const char *>(data), dataLen);
577 CLOGI("Received data: %{public}s", dataString.c_str());
578
579 if (!json::accept(dataString)) {
580 CLOGE("received data string does not conform to JSON format");
581 return;
582 }
583 json jsonObject = json::parse(dataString, nullptr, false);
584 if (jsonObject.contains(OPERATION_TYPE_KEY)) {
585 if (!jsonObject[OPERATION_TYPE_KEY].is_number()) {
586 CLOGE("OPERATION_TYPE_KEY json data is not number");
587 return;
588 }
589 int operType = jsonObject[OPERATION_TYPE_KEY];
590 if (operType != OPERATION_CONSULT) {
591 CLOGE("cast operation type %d, return", operType);
592 return;
593 }
594 }
595
596 if (jsonObject.contains(DATA_KEY)) {
597 if (!jsonObject[DATA_KEY].is_string()) {
598 CLOGE("data key is empty, get body string fail");
599 return;
600 }
601
602 std::string bodyString = jsonObject[DATA_KEY];
603 if (!json::accept(bodyString)) {
604 CLOGE("received body string does not conform to JSON format");
605 return;
606 }
607 json body = json::parse(bodyString, nullptr, false);
608 handleConsultData(body, transportId);
609 }
610 }
611
handleConsultData(const json & body,int transportId)612 bool ConnectionManager::handleConsultData(const json &body, int transportId)
613 {
614 CLOGI("handleConsultData data from sink %{public}s", body.dump().c_str());
615 if (body.contains(CONSULT_RESULT) && !body[CONSULT_RESULT].is_number()) {
616 CLOGE("consult result data is not number");
617 return false;
618 }
619
620 auto device = CastDeviceDataManager::GetInstance().GetDeviceByTransId(transportId);
621 if (device == std::nullopt) {
622 CLOGE("handleConsultData device is null");
623 return false;
624 }
625
626 int consultResult = body[CONSULT_RESULT];
627 switch (consultResult) {
628 case AUTH_SUCCESS_FROM_SINK: {
629 CLOGI("handleConsultData auth success, consult result is %{public}d", consultResult);
630 break;
631 }
632 case CONNECTION_FAILED: {
633 CLOGI("handleConsultData connect fail, consult result is %{public}d", consultResult);
634 break;
635 }
636 default: {
637 CLOGE("unhandled message, consult result is %d", consultResult);
638 break;
639 }
640 }
641
642 return true;
643 }
644
ConnectDevice(const CastInnerRemoteDevice & dev,const ProtocolType & protocolType)645 bool ConnectionManager::ConnectDevice(const CastInnerRemoteDevice &dev, const ProtocolType &protocolType)
646 {
647 DeviceDiscoveryWriteWrap(__func__, GetAnonymousDeviceID(dev.deviceId));
648
649 auto &deviceId = dev.deviceId;
650 CLOGI("deviceId %{public}s, protocolType %{public}d, capabilityInfo %{public}d, wifiIp %{public}s, "
651 "bleMac %{public}s, isLeagacy %{public}d, isFresh wifi %{public}d, ble %{public}d",
652 Utils::Mask(deviceId).c_str(), protocolType, dev.capabilityInfo, Utils::Mask(dev.wifiIp).c_str(),
653 Utils::Mask(dev.bleMac).c_str(), dev.isLeagacy, dev.isWifiFresh, dev.isBleFresh);
654
655 if (!UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTING)) {
656 CLOGE("Device(%s) is missing", deviceId.c_str());
657 return false;
658 }
659
660 protocolType_ = protocolType;
661 SetConnectingDeviceId(deviceId);
662
663 if (IsNeedDiscoveryDevice(dev)) {
664 CLOGI("need discovery device");
665 DiscoveryManager::GetInstance().StartDiscovery(static_cast<int>(protocolType), {});
666 std::thread([this, dev]() {
667 Utils::SetThreadName("ConnectTargetDevice");
668 WaitAndConnectTargetDevice(dev);
669 }).detach();
670 return true;
671 }
672 isWifiFresh_ = dev.isWifiFresh;
673 DiscoveryManager::GetInstance().StopDiscovery();
674
675 std::string networkId;
676 if (IsDeviceTrusted(dev.deviceId, networkId) && IsSingle(dev) && SourceCheckConnectAccess(networkId)) {
677 NotifyListenerToLoadSinkSA(networkId);
678 if (!CastDeviceDataManager::GetInstance().SetDeviceNetworkId(deviceId, networkId) ||
679 !OpenConsultSession(dev)) {
680 (void)UpdateDeviceState(deviceId, RemoteDeviceState::FOUND);
681 return false;
682 }
683 (void)UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTED);
684 return true;
685 }
686 if (!BindTarget(dev)) {
687 (void)UpdateDeviceState(deviceId, RemoteDeviceState::FOUND);
688 return false;
689 }
690 std::unique_lock<std::mutex> lock(mutex_);
691 if (isBindTargetMap_.find(deviceId) != isBindTargetMap_.end()) {
692 isBindTargetMap_[deviceId] = true;
693 } else {
694 isBindTargetMap_.insert({ deviceId, true });
695 }
696 CLOGI("ConnectDevice out, %{public}s", Utils::Mask(deviceId).c_str());
697 return true;
698 }
699
DisconnectDevice(const std::string & deviceId)700 void ConnectionManager::DisconnectDevice(const std::string &deviceId)
701 {
702 CLOGI("DisconnectDevice in, deviceId %{public}s", Utils::Mask(deviceId).c_str());
703
704 std::unique_lock<std::mutex> lock(mutex_);
705 connectingDeviceId_ = "";
706 DiscoveryManager::GetInstance().StopDiscovery();
707 if (!CastDeviceDataManager::GetInstance().IsDeviceUsed(deviceId)) {
708 CLOGE("Device(%s) is not used, remove it", deviceId.c_str());
709 CastDeviceDataManager::GetInstance().UpdateDeviceByDeviceId(deviceId);
710 return;
711 }
712
713 protocolType_ = ProtocolType::CAST_PLUS_MIRROR;
714 lock.unlock();
715 UpdateDeviceState(deviceId, RemoteDeviceState::FOUND);
716 DestroyConsulationSession(deviceId);
717 CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
718 auto isActiveAuth = CastDeviceDataManager::GetInstance().GetDeviceIsActiveAuth(deviceId);
719 if (isActiveAuth == std::nullopt) {
720 return;
721 }
722 auto networkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(deviceId);
723 if (networkId == std::nullopt) {
724 return;
725 }
726
727 CastDeviceDataManager::GetInstance().UpdateDeviceByDeviceId(deviceId);
728 }
729
UpdateDeviceState(const std::string & deviceId,RemoteDeviceState state)730 bool ConnectionManager::UpdateDeviceState(const std::string &deviceId, RemoteDeviceState state)
731 {
732 CLOGI("UpdateDeviceState device: %{public}s state: %{public}s", Utils::Mask(deviceId).c_str(),
733 REMOTE_DEVICE_STATE_STRING[static_cast<size_t>(state)].c_str());
734 return CastDeviceDataManager::GetInstance().SetDeviceState(deviceId, state);
735 }
736
UpdateGrabState(bool changeState,int32_t sessionId)737 void ConnectionManager::UpdateGrabState(bool changeState, int32_t sessionId)
738 {
739 CLOGI("GrabDevice in");
740 std::lock_guard<std::mutex> lock(mutex_);
741 sessionId_ = sessionId;
742 if (changeState) {
743 grabState_ = DeviceGrabState::GRAB_ALLOWED;
744 return;
745 }
746 grabState_ = DeviceGrabState::NO_GRAB;
747 }
748
GetProtocolType() const749 int ConnectionManager::GetProtocolType() const
750 {
751 return static_cast<int>(protocolType_);
752 }
753
SetProtocolType(ProtocolType protocol)754 void ConnectionManager::SetProtocolType(ProtocolType protocol)
755 {
756 protocolType_ = protocol;
757 }
758
GetLocalDeviceInfo(CastLocalDevice & device)759 int32_t ConnectionManager::GetLocalDeviceInfo(CastLocalDevice &device)
760 {
761 CLOGI("GetLocalDeviceInfo in");
762 DmDeviceInfo local;
763 int32_t ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, local);
764 if (ret != DM_OK) {
765 CLOGE("Cannot get the local device info from DM");
766 return ret;
767 };
768 device.deviceId = local.deviceId;
769 device.deviceType = ConvertDeviceType(local.deviceTypeId);
770 device.subDeviceType = ConvertSubDeviceType(local.deviceTypeId);
771 device.deviceName = local.deviceName;
772 CLOGI("GetLocalDeviceInfo out, dmTypeId:%{public}d deviceType:%{public}d subDeviceType:%{public}d",
773 local.deviceTypeId, device.deviceType, device.subDeviceType);
774 return ret;
775 }
776
NotifySessionIsReady(int transportId)777 void ConnectionManager::NotifySessionIsReady(int transportId)
778 {
779 if (!listener_) {
780 CLOGE("Detect absence of listener_.");
781 return;
782 }
783 int castSessionId = listener_->NotifySessionIsReady();
784 if (castSessionId == INVALID_ID) {
785 CLOGE("sessionId is invalid");
786 return;
787 }
788
789 CLOGD("Update cast session id map: %d: %d", transportId, castSessionId);
790 std::lock_guard<std::mutex> lock(mutex_);
791 transIdToCastSessionIdMap_.insert({ transportId, castSessionId });
792 }
793
NotifyDeviceIsOffline(const std::string & deviceId)794 void ConnectionManager::NotifyDeviceIsOffline(const std::string &deviceId)
795 {
796 CLOGI("NotifyDeviceIsOffline in");
797 auto listener = GetListener();
798 if (!listener) {
799 return;
800 }
801 listener->NotifyDeviceIsOffline(deviceId);
802 }
803
NotifyConnectStage(const CastInnerRemoteDevice & device,int result,int32_t reasonCode)804 bool ConnectionManager::NotifyConnectStage(const CastInnerRemoteDevice &device, int result, int32_t reasonCode)
805 {
806 CLOGI("result %{public}d, reasonCode %{public}d", result, reasonCode);
807
808 auto sessionListener = GetSessionListener(device.localCastSessionId);
809 if (sessionListener == nullptr) {
810 CLOGE("sessionListener is NULL");
811 return false;
812 }
813
814 if (result == ConnectStageResult::AUTH_FAILED || result == ConnectStageResult::CONNECT_FAIL ||
815 result == ConnectStageResult::DISCONNECT_START) {
816 UpdateDeviceState(device.deviceId, RemoteDeviceState::FOUND);
817 }
818
819 sessionListener->NotifyConnectStage(device.deviceId, result, reasonCode);
820 return true;
821 }
822
NotifyListenerToLoadSinkSA(const std::string & networkId)823 bool ConnectionManager::NotifyListenerToLoadSinkSA(const std::string& networkId)
824 {
825 auto listener = GetListener();
826 if (!listener) {
827 return false;
828 }
829 return listener->LoadSinkSA(networkId);
830 }
831
SourceCheckConnectAccess(std::string & peerNetworkId)832 bool ConnectionManager::SourceCheckConnectAccess(std::string &peerNetworkId)
833 {
834 std::string localNetworkId = "";
835 if (DeviceManager::GetInstance().GetLocalDeviceNetWorkId(PKG_NAME, localNetworkId) != 0) {
836 CLOGI("GetLocalDeviceNetWorkId fail %s", localNetworkId.c_str());
837 return false;
838 }
839 DmAccessCaller dmSrcCaller = {
840 .accountId = Utils::GetOhosAccountId(),
841 .pkgName = PKG_NAME,
842 .networkId = localNetworkId,
843 .userId = Utils::GetCurrentActiveAccountUserId(),
844 .tokenId = 0,
845 };
846 DmAccessCallee dmDstCallee = {
847 .networkId = peerNetworkId,
848 .peerId = "",
849 };
850 bool ret = DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee);
851 CLOGI("peerNetworkId:%{public}s, has connect Access:%{public}d", Utils::Mask(peerNetworkId).c_str(), ret);
852 return ret;
853 }
854
SinkCheckConnectAccess(json & data,std::string & peerDeviceId)855 bool ConnectionManager::SinkCheckConnectAccess(json &data, std::string &peerDeviceId)
856 {
857 if (!data.contains(ACCOUNT_ID_KEY)) {
858 CLOGI("ACCOUNT_ID_KEY is not exit, no need to check access");
859 return true;
860 }
861 if (!data[ACCOUNT_ID_KEY].is_string()) {
862 CLOGE("ACCOUNT_ID_KEY json data is not string");
863 return false;
864 }
865 if (!data.contains(USER_ID_KEY) || !data[USER_ID_KEY].is_number()) {
866 CLOGE("ACCOUNT_ID_KEY json data is not exit or is not number");
867 return false;
868 }
869 std::string accountId = data[ACCOUNT_ID_KEY];
870 int userId = data[USER_ID_KEY];
871 auto dmDevice = GetDmDeviceInfo(peerDeviceId);
872 if (peerDeviceId.compare(dmDevice.deviceId) != 0) {
873 CLOGE("Failed to get DmDeviceInfo");
874 return false;
875 }
876 std::string localNetworkId = "";
877 if (DeviceManager::GetInstance().GetLocalDeviceNetWorkId(PKG_NAME, localNetworkId) != 0) {
878 CLOGI("GetLocalDeviceNetWorkId fail %s", localNetworkId.c_str());
879 return false;
880 }
881 DmAccessCaller dmSrcCaller = {
882 .accountId = accountId,
883 .pkgName = PKG_NAME,
884 .networkId = dmDevice.networkId,
885 .userId = userId,
886 .tokenId = 0,
887 };
888 DmAccessCallee dmDstCallee = {
889 .accountId = Utils::GetOhosAccountId(),
890 .networkId = localNetworkId,
891 .peerId = "",
892 .userId = Utils::GetCurrentActiveAccountUserId(),
893 };
894 bool ret = DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee);
895 CLOGI("peerDeviceId:%{public}s, has connect Access:%{public}d", Utils::Mask(peerDeviceId).c_str(), ret);
896 return ret;
897 }
898
IsWifiChannelFirst(const std::string & deviceId)899 bool ConnectionManager::IsWifiChannelFirst(const std::string &deviceId)
900 {
901 if (deviceId.empty()) {
902 return false;
903 }
904 if (protocolType_ != ProtocolType::CAST_PLUS_STREAM) {
905 CLOGI("protocal type is %{public}d, not stream", protocolType_);
906 return false;
907 }
908
909 if (!isWifiFresh_) {
910 CLOGI("deviceId %s, wifi is not fresh", deviceId.c_str());
911 return false;
912 }
913 auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
914 if (remote == std::nullopt) {
915 CLOGE("Get remote device is empty");
916 return false;
917 }
918 CastInnerRemoteDevice device = *remote;
919 CLOGI("deviceId %s, wifi ip local %s, remote %s, link ip local %s, remote %s", deviceId.c_str(),
920 device.localWifiIp.c_str(), device.wifiIp.c_str(), device.localIp.c_str(), device.remoteIp.c_str());
921 return !device.localWifiIp.empty() && !device.wifiIp.empty();
922 }
923
IsNeedDiscoveryDevice(const CastInnerRemoteDevice & dev)924 bool ConnectionManager::IsNeedDiscoveryDevice(const CastInnerRemoteDevice &dev)
925 {
926 return IsHuaweiDevice(dev) && !dev.isWifiFresh && !dev.isBleFresh;
927 }
928
WaitAndConnectTargetDevice(const CastInnerRemoteDevice & dev)929 void ConnectionManager::WaitAndConnectTargetDevice(const CastInnerRemoteDevice &dev)
930 {
931 CLOGI("In");
932 constexpr int maxCount = 100;
933 constexpr int sleepTime = 50;
934 bool result = false;
935 for (int index = 0; index <= maxCount; index++) {
936 if (GetConnectingDeviceId().empty()) {
937 CLOGI("connecting deviceId is empty, return");
938 result = true;
939 break;
940 }
941 auto temp = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(dev.deviceId);
942 if (temp == std::nullopt || IsNeedDiscoveryDevice(*temp)) {
943 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
944 continue;
945 } else {
946 CastInnerRemoteDevice device = *temp;
947 CLOGI("find target device %{public}s wifiFresh is %{public}d", Utils::Mask(dev.deviceId).c_str(),
948 device.isWifiFresh);
949 if (!device.isWifiFresh) {
950 device.wifiIp = "";
951 device.wifiPort = 0;
952 }
953 result = ConnectDevice(device, protocolType_);
954 break;
955 }
956 }
957 // auto end = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
958 CLOGI("wait target device time (endTime - startTime ms), result %{public}d", result);
959 if (!result) {
960 NotifyConnectStage(dev, ConnectStageResult::DISCONNECT_START, REASON_DEFAULT);
961 }
962 }
963
BindTarget(const CastInnerRemoteDevice & dev)964 bool ConnectionManager::BindTarget(const CastInnerRemoteDevice &dev)
965 {
966 CLOGD("device info is %s, device name %s, customData %s", dev.deviceId.c_str(), dev.deviceName.c_str(),
967 dev.customData.c_str());
968 PeerTargetId targetId = {
969 .deviceId = dev.deviceId,
970 .bleMac = dev.bleMac,
971 .wifiIp = dev.wifiIp,
972 .wifiPort = dev.wifiPort,
973 };
974 std::map<std::string, std::string> bindParam;
975 BuildBindParam(dev, bindParam);
976 int ret = DeviceManager::GetInstance().BindTarget(PKG_NAME, targetId, bindParam,
977 std::make_shared<CastBindTargetCallback>());
978 if (ret != DM_OK) {
979 CLOGE("ConnectDevice BindTarget fail, ret = %{public}d)", ret);
980 if (ret == ERR_DM_AUTH_BUSINESS_BUSY) {
981 DeviceManager::GetInstance().UnbindTarget(
982 PKG_NAME, targetId, bindParam, std::make_shared<CastUnBindTargetCallback>());
983 }
984 return false;
985 }
986
987 CastDeviceDataManager::GetInstance().SetDeviceIsActiveAuth(dev.deviceId, true);
988 CLOGI("Finish to BindTarget device!");
989 return true;
990 }
991
BuildBindParam(const CastInnerRemoteDevice & device,std::map<std::string,std::string> & bindParam)992 bool ConnectionManager::BuildBindParam(const CastInnerRemoteDevice &device,
993 std::map<std::string, std::string> &bindParam)
994 {
995 CLOGI("start BuildBindParam");
996 if (IsSingle(device)) { // bind target by dm
997 bindParam[PARAM_KEY_AUTH_TYPE] = AUTH_WITH_PIN;
998 } else { // bind target by meta node
999 CastLocalDevice local;
1000 int32_t ret = GetLocalDeviceInfo(local);
1001 if (ret != DM_OK) {
1002 CLOGE("CastLocalDevice get failed");
1003 return false;
1004 }
1005 bindParam[DistributedHardware::PARAM_KEY_META_TYPE] = "5";
1006 bindParam[KEY_TRANSFER_MODE] = std::to_string(TRANSFER_MODE_SOFTBUS_SINGLE);
1007 bindParam[DEVICE_NAME_KEY] = local.deviceName;
1008 bindParam[AUTH_VERSION_KEY] = GetAuthVersion(device);
1009 bindParam[KEY_SESSION_ID] = std::to_string(device.sessionId);
1010 bindParam["udid"] = device.udid;
1011 }
1012 return true;
1013 }
1014
GetAuthVersion(const CastInnerRemoteDevice & device)1015 std::string ConnectionManager::GetAuthVersion(const CastInnerRemoteDevice &device)
1016 {
1017 if (!device.bleMac.empty() && !device.customData.empty()) {
1018 return AUTH_VERSION_2;
1019 }
1020 return device.wifiPort == 0 ? AUTH_VERSION_1 : AUTH_VERSION_2;
1021 }
1022
QueryP2PIp(const CastInnerRemoteDevice & dev)1023 bool ConnectionManager::QueryP2PIp(const CastInnerRemoteDevice &dev)
1024 {
1025 CLOGI("query p2p ip method in ");
1026 auto temp = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(dev.deviceId);
1027 if (temp == std::nullopt) {
1028 CLOGE("GetDeviceByDeviceId the device(%s) is missing", dev.deviceId.c_str());
1029 return false;
1030 }
1031
1032 CastInnerRemoteDevice device = *temp;
1033
1034 PeerTargetId targetId;
1035 targetId.deviceId = device.deviceId;
1036 targetId.wifiIp = device.wifiIp;
1037 targetId.wifiPort = device.wifiPort;
1038 targetId.bleMac = device.bleMac;
1039
1040 std::string localNetworkId = "";
1041 if (DeviceManager::GetInstance().GetLocalDeviceNetWorkId(PKG_NAME, localNetworkId) != 0) {
1042 CLOGI("GetLocalDeviceNetWorkId fail %s", localNetworkId.c_str());
1043 return false;
1044 }
1045
1046 // The session can only be opened using a network ID instead of a UDID in OH system
1047 auto remoteNetworkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(dev.deviceId);
1048 if (remoteNetworkId == std::nullopt) {
1049 return false;
1050 }
1051 std::map<std::string, std::string> bindParam;
1052 bindParam[DistributedHardware::PARAM_KEY_META_TYPE] = "5";
1053 bindParam[KEY_BIND_TARGET_ACTION] = std::to_string(ACTION_QUERY_P2P_IP);
1054 bindParam["localNetworkId"] = localNetworkId;
1055 bindParam["remoteNetworkId"] = remoteNetworkId.value();
1056 CLOGI("QueryP2PIp localNetworkId=%s, remoteNetworkId=%s", localNetworkId.c_str(), remoteNetworkId.value().c_str());
1057 DeviceManager::GetInstance().BindTarget(PKG_NAME, targetId, bindParam,
1058 std::make_shared<CastBindTargetCallback>());
1059 return true;
1060 }
1061
SendConsultData(const CastInnerRemoteDevice & device,int port)1062 void ConnectionManager::SendConsultData(const CastInnerRemoteDevice &device, int port)
1063 {
1064 CLOGI("In");
1065 int transportId = CastDeviceDataManager::GetInstance().GetDeviceTransId(device.deviceId);
1066 if (transportId == INVALID_ID) {
1067 CLOGE("transport id is invalid");
1068 return;
1069 }
1070
1071 json data;
1072 data[VERSION_KEY] = VERSION;
1073 data[OPERATION_TYPE_KEY] = OPERATION_CONSULT;
1074 data[SEQUENCE_NUMBER] = rand();
1075 json body;
1076 GetConsultationData(device, port, body);
1077 data[DATA_KEY] = body;
1078
1079 std::string dataStr = data.dump();
1080 int ret = SendBytes(transportId, dataStr.c_str(), dataStr.size());
1081 if (ret != SOFTBUS_OK) {
1082 CLOGE("failed to send consultion data, return:%{public}d", ret);
1083 CastEngineDfx::WriteErrorEvent(SEND_CONSULTION_DATA_FAIL);
1084 return;
1085 }
1086 CLOGD("return:%{public}d, data:%s", ret, dataStr.c_str());
1087 }
1088
GetConsultationData(const CastInnerRemoteDevice & device,int port,json & body)1089 std::string ConnectionManager::GetConsultationData(const CastInnerRemoteDevice &device, int port, json &body)
1090 {
1091 CastLocalDevice local;
1092 auto ret = GetLocalDeviceInfo(local);
1093 if (ret != DM_OK) {
1094 CLOGE("local device info get failed");
1095 return "";
1096 }
1097
1098 body[DEVICE_ID_KEY] = local.deviceId;
1099 body[DEVICE_NAME_KEY] = local.deviceName;
1100 body[KEY_SESSION_ID] = device.sessionId;
1101 body[KEY_TRANSFER_MODE] = TRANSFER_MODE_SOFTBUS_SINGLE;
1102
1103 ProtocolType protocolType;
1104 GetSessionProtocolType(device.sessionId, protocolType);
1105 body[PROTOCOL_TYPE_KEY] = protocolType;
1106
1107 if (GetAuthVersion(device) == AUTH_VERSION_2) {
1108 body[TYPE_SESSION_KEY] = device.sessionKey;
1109 }
1110
1111 CLOGI("Encrypt data localIp %s, remoteIp %s, port %d", device.localIp.c_str(), device.remoteIp.c_str(), port);
1112 EncryptPort(port, device.sessionKey, body);
1113 EncryptIp(device.localIp, SOURCE_IP_KEY, device.sessionKey, body);
1114 EncryptIp(device.remoteIp, SINK_IP_KEY, device.sessionKey, body);
1115 return body.dump();
1116 }
1117
EncryptPort(int port,const uint8_t * sessionKey,json & body)1118 void ConnectionManager::EncryptPort(int port, const uint8_t *sessionKey, json &body)
1119 {
1120 std::unique_ptr<uint8_t[]> portArray = intToByteArray(port);
1121 int portArraySize = 4;
1122 ConstPacketData inputData = { portArray.get(), portArraySize };
1123
1124 int encryptedDataLen = 0;
1125 auto encryptedData = EncryptDecrypt::GetInstance().EncryptData(EncryptDecrypt::CTR_CODE, { sessionKey,
1126 SESSION_KEY_LENGTH }, inputData, encryptedDataLen);
1127 if (!encryptedData) {
1128 CLOGE("encrypt error");
1129 return;
1130 }
1131 CLOGD("encrypt result is %d ", encryptedDataLen);
1132 std::string encryptedPortLatin1(reinterpret_cast<const char *>(encryptedData.get()), encryptedDataLen);
1133 std::string encryptedPortUtf8 = convLatin1ToUTF8(encryptedPortLatin1);
1134 body[PORT_KEY] = encryptedPortUtf8;
1135 }
1136
EncryptIp(const std::string & ip,const std::string & key,const uint8_t * sessionKey,json & body)1137 void ConnectionManager::EncryptIp(const std::string &ip, const std::string &key, const uint8_t *sessionKey, json &body)
1138 {
1139 if (ip.empty()) {
1140 return;
1141 }
1142 ConstPacketData inputData = { reinterpret_cast<const uint8_t *>(ip.c_str()), ip.size() };
1143 int encryptedDataLen = 0;
1144 auto encryptedData = EncryptDecrypt::GetInstance().EncryptData(EncryptDecrypt::CTR_CODE, { sessionKey,
1145 SESSION_KEY_LENGTH }, inputData, encryptedDataLen);
1146 if (!encryptedData) {
1147 CLOGE("encrypt error");
1148 return;
1149 }
1150 uint8_t *encrypted = encryptedData.get();
1151 for (int i = 0; i < encryptedDataLen; i++) {
1152 body[key].push_back(encrypted[i]);
1153 }
1154 CLOGI("encrypt %s finish", key.c_str());
1155 }
1156
intToByteArray(int32_t num)1157 std::unique_ptr<uint8_t[]> ConnectionManager::intToByteArray(int32_t num)
1158 {
1159 unsigned int number = static_cast<unsigned int>(num);
1160 std::unique_ptr<uint8_t[]> result = std::make_unique<uint8_t[]>(INT_FOUR);
1161 unsigned int i = 0;
1162 result[i] = (number >> FOURTH_BYTE_OFFSET) & 0xFF;
1163 result[++i] = (number >> THIRD_BYTE_OFFSET) & 0xFF;
1164 result[++i] = (number >> SECOND_BYTE_OFFSET) & 0xFF;
1165 result[++i] = number & 0xFF;
1166 return result;
1167 }
1168
convLatin1ToUTF8(std::string & latin1)1169 std::string ConnectionManager::convLatin1ToUTF8(std::string &latin1)
1170 {
1171 iconv_t cd = iconv_open("utf8", "iso88591");
1172 if (cd == (iconv_t)-1) {
1173 CLOGD("andy Failed to open iconv conversion descriptor");
1174 return "";
1175 }
1176
1177 size_t inSize = latin1.size();
1178 size_t outSize = inSize * 2;
1179 std::string utf8(outSize, 0);
1180
1181 char *inbuf = &latin1[0];
1182 char *outbuf = &utf8[0];
1183 size_t result = iconv(cd, &inbuf, &inSize, &outbuf, &outSize);
1184 if (result == (size_t)-1) {
1185 CLOGD("Failed to convert encoding");
1186 iconv_close(cd);
1187 return "";
1188 }
1189
1190 iconv_close(cd);
1191 utf8.resize(outbuf - &utf8[0]);
1192 return utf8;
1193 }
1194
DestroyConsulationSession(const std::string & deviceId)1195 void ConnectionManager::DestroyConsulationSession(const std::string &deviceId)
1196 {
1197 int transportId = CastDeviceDataManager::GetInstance().ResetDeviceTransId(deviceId);
1198 CLOGI("DestroyConsulationSession in tranId = %{public}d", transportId);
1199 if (transportId != INVALID_ID) {
1200 CloseSession(transportId);
1201 }
1202
1203 auto isSink = CastDeviceDataManager::GetInstance().GetDeviceRole(deviceId);
1204 if (isSink == std::nullopt || (*isSink)) {
1205 // The sink's Server is only removed when DisableDiscoverable or Deinit is performed.
1206 return;
1207 }
1208 }
1209
ParseAndCheckJsonData(const std::string & data,json & jsonData)1210 bool ConnectionManager::ParseAndCheckJsonData(const std::string &data, json &jsonData)
1211 {
1212 if (!json::accept(data)) {
1213 CLOGE("something wrong for the json data!");
1214 return false;
1215 }
1216 json jsonObject = json::parse(data, nullptr, false);
1217 if (!jsonObject.contains(DATA_KEY)) {
1218 CLOGE("json object have no data!");
1219 return false;
1220 }
1221
1222 if (jsonObject[DATA_KEY].is_string()) {
1223 std::string dataString = jsonObject[DATA_KEY];
1224 jsonData = json::parse(dataString, nullptr, false);
1225 } else if (jsonObject[DATA_KEY].is_object()) {
1226 jsonData = jsonObject[DATA_KEY];
1227 } else {
1228 CLOGE("data key in json object is invalid!");
1229 return false;
1230 }
1231 if (jsonData.is_discarded()) {
1232 CLOGE("json object discarded!");
1233 return false;
1234 }
1235
1236 if (jsonData.contains(DEVICE_ID_KEY) && !jsonData[DEVICE_ID_KEY].is_string()) {
1237 CLOGE("DEVICE_ID_KEY json data is not string");
1238 return false;
1239 }
1240
1241 if (jsonData.contains(DEVICE_NAME_KEY) && !jsonData[DEVICE_NAME_KEY].is_string()) {
1242 CLOGE("DEVICE_NAME_KEY json data is not string");
1243 return false;
1244 }
1245
1246 if (jsonData.contains(KEY_SESSION_ID) && !jsonData[KEY_SESSION_ID].is_number()) {
1247 CLOGE("KEY_SESSION_ID json data is not number");
1248 return false;
1249 }
1250 return true;
1251 }
1252
GetRemoteFromJsonData(const std::string & data)1253 std::unique_ptr<CastInnerRemoteDevice> ConnectionManager::GetRemoteFromJsonData(const std::string &data)
1254 {
1255 json jsonData;
1256 if (!ParseAndCheckJsonData(data, jsonData)) {
1257 return nullptr;
1258 }
1259
1260 auto device = std::make_unique<CastInnerRemoteDevice>();
1261 if (!device) {
1262 CLOGE("make unique failed");
1263 return nullptr;
1264 }
1265 device->deviceId = jsonData.contains(DEVICE_ID_KEY) ? jsonData[DEVICE_ID_KEY] : "";
1266 device->deviceName = jsonData.contains(DEVICE_NAME_KEY) ? jsonData[DEVICE_NAME_KEY] : "";
1267 device->deviceType = DeviceType::DEVICE_CAST_PLUS;
1268 if (jsonData.contains(KEY_SESSION_ID)) {
1269 device->sessionId = jsonData[KEY_SESSION_ID];
1270 }
1271 if (jsonData.contains(PROTOCOL_TYPE_KEY) && jsonData[PROTOCOL_TYPE_KEY].is_number()) {
1272 device->protocolType = jsonData[PROTOCOL_TYPE_KEY];
1273 }
1274 if (!SinkCheckConnectAccess(jsonData, device->deviceId)) {
1275 return nullptr;
1276 }
1277
1278 return device;
1279 }
1280
OpenSoftBusSocket(const std::optional<std::string> & networkId,const CastInnerRemoteDevice & device,int32_t & errorCode)1281 int ConnectionManager::OpenSoftBusSocket(const std::optional<std::string> &networkId,
1282 const CastInnerRemoteDevice &device, int32_t &errorCode)
1283 {
1284 // Only transortId > INVALID_ID does NOT meaning openSession successfully,
1285 // result from OnOpenSession also count.
1286 CLOGI("OpenSoftBusSocket in");
1287 constexpr int32_t attemptCountMax = 2;
1288 int socketId = INVALID_ID;
1289 int bindResult = INVALID_ID;
1290 bool isSingle = IsSingle(device);
1291 auto time = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
1292 openSessionTime_ = time.time_since_epoch().count();
1293 std::lock_guard<std::mutex> lock(openConsultingSessionMutex_);
1294 for (int attemptCount = 1; attemptCount <= attemptCountMax; ++attemptCount) {
1295 CLOGI("Attemp to OpenSession in %{public}d times.", attemptCount);
1296 if (IsDeviceConnectStateChange(device)) {
1297 CLOGE("device state is not connecting, do nothting");
1298 socketId = INVALID_ID;
1299 errorCode = CONNECTION_DEVICE_IS_MISSING;
1300 break;
1301 }
1302 socketId = SoftBus::CreateSocket(networkId, protocolType_);
1303 if (socketId <= INVALID_ID) {
1304 CLOGE("Failed to open session, and try again, socketId: %{public}d", socketId);
1305 errorCode = socketId;
1306 continue;
1307 }
1308
1309 bindResult = SoftBus::BindSocket(socketId, protocolType_, isSingle, attemptCount);
1310 if (bindResult != SOFTBUS_OK) {
1311 CLOGE("Failed to bind socket, result %{public}d", bindResult);
1312 Shutdown(socketId);
1313 socketId = INVALID_ID;
1314 errorCode = bindResult;
1315 continue;
1316 }
1317 if (IsDeviceConnectStateChange(device) ||
1318 !CastDeviceDataManager::GetInstance().SetDeviceTransId(device.deviceId, socketId)) {
1319 CLOGE("deviceState is %{public}d",
1320 static_cast<int>(CastDeviceDataManager::GetInstance().GetDeviceState(device.deviceId)));
1321 Shutdown(socketId);
1322 socketId = INVALID_ID;
1323 errorCode = CONNECTION_DEVICE_IS_MISSING;
1324 break;
1325 }
1326 break;
1327 }
1328 return socketId;
1329 }
1330
IsDeviceConnectStateChange(const CastInnerRemoteDevice & device)1331 bool ConnectionManager::IsDeviceConnectStateChange(const CastInnerRemoteDevice &device)
1332 {
1333 auto newDevice = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(device.deviceId);
1334 if (!CastDeviceDataManager::GetInstance().IsDeviceConnecting(device.deviceId) ||
1335 (newDevice && newDevice->localCastSessionId != device.localCastSessionId)) {
1336 return true;
1337 }
1338
1339 return false;
1340 }
1341
AddSessionListener(int castSessionId,std::shared_ptr<IConnectManagerSessionListener> listener)1342 void ConnectionManager::AddSessionListener(int castSessionId, std::shared_ptr<IConnectManagerSessionListener> listener)
1343 {
1344 std::lock_guard<std::mutex> lock(mutex_);
1345 sessionListeners_[castSessionId] = listener;
1346 }
1347
RemoveSessionListener(int castSessionId)1348 void ConnectionManager::RemoveSessionListener(int castSessionId)
1349 {
1350 std::lock_guard<std::mutex> lock(mutex_);
1351 if (castSessionId == INVALID_ID) {
1352 sessionListeners_.clear();
1353 return;
1354 }
1355 auto it = sessionListeners_.find(castSessionId);
1356 if (it == sessionListeners_.end()) {
1357 CLOGE("Cast session listener(%{public}d) has gone.", castSessionId);
1358 return;
1359 }
1360 sessionListeners_.erase(it);
1361 }
1362
GetSessionListener(int castSessionId)1363 std::shared_ptr<IConnectManagerSessionListener> ConnectionManager::GetSessionListener(int castSessionId)
1364 {
1365 std::lock_guard<std::mutex> lock(mutex_);
1366 auto it = sessionListeners_.find(castSessionId);
1367 if (it == sessionListeners_.end()) {
1368 CLOGE("Cast session listener(%{public}d) has gone.", castSessionId);
1369 return nullptr;
1370 }
1371 return it->second;
1372 }
1373
SetListener(std::shared_ptr<IConnectionManagerListener> listener)1374 void ConnectionManager::SetListener(std::shared_ptr<IConnectionManagerListener> listener)
1375 {
1376 std::lock_guard<std::mutex> lock(mutex_);
1377 listener_ = listener;
1378 }
1379
GetListener()1380 std::shared_ptr<IConnectionManagerListener> ConnectionManager::GetListener()
1381 {
1382 std::lock_guard<std::mutex> lock(mutex_);
1383 return listener_;
1384 }
1385
HasListener()1386 bool ConnectionManager::HasListener()
1387 {
1388 std::lock_guard<std::mutex> lock(mutex_);
1389 return listener_ != nullptr;
1390 }
1391
ResetListener()1392 void ConnectionManager::ResetListener()
1393 {
1394 SetListener(nullptr);
1395 RemoveSessionListener(INVALID_ID);
1396 }
1397
GetSessionProtocolType(int sessionId,ProtocolType & protocolType)1398 int32_t ConnectionManager::GetSessionProtocolType(int sessionId, ProtocolType &protocolType)
1399 {
1400 auto listener = GetListener();
1401 if (!listener) {
1402 return CAST_ENGINE_ERROR;
1403 }
1404 return listener->GetSessionProtocolType(sessionId, protocolType);
1405 }
1406
SetSessionProtocolType(int sessionId,ProtocolType protocolType)1407 int32_t ConnectionManager::SetSessionProtocolType(int sessionId, ProtocolType protocolType)
1408 {
1409 auto listener = GetListener();
1410 if (!listener) {
1411 return CAST_ENGINE_ERROR;
1412 }
1413 return listener->SetSessionProtocolType(sessionId, protocolType);
1414 }
1415
SendConsultInfo(const std::string & deviceId,int port)1416 void ConnectionManager::SendConsultInfo(const std::string &deviceId, int port)
1417 {
1418 CLOGI("SendConsultInfo In");
1419 auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
1420 if (remote == std::nullopt) {
1421 CLOGE("Get remote device is empty");
1422 return;
1423 }
1424
1425 SendConsultData(*remote, port);
1426 }
1427
GetConnectingDeviceId()1428 std::string ConnectionManager::GetConnectingDeviceId()
1429 {
1430 std::lock_guard<std::mutex> lock(mutex_);
1431 return connectingDeviceId_;
1432 }
1433
SetConnectingDeviceId(std::string deviceId)1434 void ConnectionManager::SetConnectingDeviceId(std::string deviceId)
1435 {
1436 std::lock_guard<std::mutex> lock(mutex_);
1437 connectingDeviceId_ = deviceId;
1438 }
1439
OnBindResult(const PeerTargetId & targetId,int32_t result,int32_t status,std::string content)1440 void CastBindTargetCallback::OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status,
1441 std::string content)
1442 {
1443 CLOGI("device id: %{public}s, status: %{public}d, result: %{public}d", Utils::Mask(targetId.deviceId).c_str(),
1444 status, result);
1445 auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(targetId.deviceId);
1446 if (remote == std::nullopt) {
1447 CLOGE("Get remote device is empty");
1448 return;
1449 }
1450
1451 json jsonInfo{};
1452 if (json::accept(content)) {
1453 jsonInfo = json::parse(content, nullptr, false);
1454 }
1455
1456 int action = -1;
1457 switch (status) {
1458 case DmAuthStatus::STATUS_DM_AUTH_FINISH:
1459 if (jsonInfo.contains(KEY_BIND_TARGET_ACTION) && jsonInfo[KEY_BIND_TARGET_ACTION].is_number()) {
1460 action = jsonInfo[KEY_BIND_TARGET_ACTION];
1461 }
1462 return HandleBindAction(*remote, action, jsonInfo);
1463 case DmAuthStatus::STATUS_DM_SHOW_PIN_INPUT_UI:
1464 case DmAuthStatus::STATUS_DM_CLOSE_PIN_INPUT_UI:
1465 case DmAuthStatus::STATUS_DM_SHOW_AUTHORIZE_UI:
1466 return;
1467 case DmAuthStatus::STATUS_DM_AUTH_DEFAULT:
1468 return;
1469 default:
1470 CLOGW("unknow status %{public}d", status);
1471 return;
1472 }
1473 }
1474
HandleBindAction(const CastInnerRemoteDevice & device,int action,const json & authInfo)1475 void CastBindTargetCallback::HandleBindAction(const CastInnerRemoteDevice &device, int action, const json &authInfo)
1476 {
1477 CLOGI("action is %{public}d", action);
1478
1479 switch (action) {
1480 case ACTION_CONNECT_DEVICE: {
1481 HandleConnectDeviceAction(device, authInfo);
1482 return;
1483 }
1484 case ACTION_QUERY_P2P_IP: {
1485 HandleQueryIpAction(device, authInfo);
1486 return;
1487 }
1488 case ACTION_SEND_MESSAGE: {
1489 CLOGI("action operate 3 send message");
1490 return;
1491 }
1492 default: {
1493 CLOGW("unknow action %{public}d", action);
1494 return;
1495 }
1496 }
1497 }
1498
HandleConnectDeviceAction(const CastInnerRemoteDevice & device,const json & authInfo)1499 void CastBindTargetCallback::HandleConnectDeviceAction(const CastInnerRemoteDevice &device, const json &authInfo)
1500 {
1501 CLOGI("handle connect device action");
1502 if (!authInfo.contains(NETWORK_ID) || !authInfo[NETWORK_ID].is_string()) {
1503 CLOGE("networkId json data is not string");
1504 return;
1505 }
1506
1507 if (authInfo.contains(TIME_RECORD_STRING) && authInfo[TIME_RECORD_STRING].is_string()) {
1508 ConnectionManager::GetInstance().authTimeString_ = authInfo[TIME_RECORD_STRING];
1509 }
1510
1511 if (authInfo.contains(TOTAL_AUTH_TIME) && authInfo[TOTAL_AUTH_TIME].is_number()) {
1512 ConnectionManager::GetInstance().totalAuthTime_ = authInfo[TOTAL_AUTH_TIME];
1513 }
1514
1515 const std::string networkId = authInfo[NETWORK_ID];
1516 const std::string deviceId = device.deviceId;
1517 if (!CastDeviceDataManager::GetInstance().SetDeviceNetworkId(device.deviceId, networkId)) {
1518 return;
1519 }
1520
1521 if (authInfo.contains(KEY_TRANSFER_MODE) && authInfo[KEY_TRANSFER_MODE].is_number()) {
1522 int mode = authInfo[KEY_TRANSFER_MODE];
1523 ChannelType type = mode == TRANSFER_MODE_SOFTBUS_SINGLE ? ChannelType::SOFT_BUS : ChannelType::LEGACY_CHANNEL;
1524 CastDeviceDataManager::GetInstance().SetDeviceChannleType(deviceId, type);
1525 }
1526
1527 if (authInfo.contains(AUTH_VERSION_KEY) && authInfo[AUTH_VERSION_KEY].is_string()) {
1528 std::string authVersion = authInfo[AUTH_VERSION_KEY];
1529 uint8_t sessionKey[SESSION_KEY_LENGTH] = {0};
1530 if (authVersion == AUTH_VERSION_1) {
1531 // 获取sessionKey
1532 if (!GetSessionKey(authInfo, sessionKey)) {
1533 CLOGE("authVersion is 1.0, get sessionkey fail");
1534 return;
1535 }
1536 bool result = CastDeviceDataManager::GetInstance().SetDeviceSessionKey(deviceId, sessionKey);
1537 CLOGI("auth version 1.0, set sessionkey result is %{public}d", result);
1538 ConnectionManager::GetInstance().NotifyConnectStage(device, ConnectStageResult::AUTH_SUCCESS);
1539 } else {
1540 RAND_bytes(sessionKey, SESSION_KEY_LENGTH);
1541 bool result = CastDeviceDataManager::GetInstance().SetDeviceSessionKey(deviceId, sessionKey);
1542 CLOGI("authVersion is 2.0, set sessionkey result is %{public}d", result);
1543 std::thread([device]() {
1544 Utils::SetThreadName("HandleConnectDeviceAction");
1545 ConnectionManager::GetInstance().OpenConsultSession(device);
1546 }).detach();
1547 }
1548 }
1549 }
1550
GetSessionKey(const json & authInfo,uint8_t * sessionKey)1551 bool CastBindTargetCallback::GetSessionKey(const json &authInfo, uint8_t *sessionKey)
1552 {
1553 if (authInfo.contains(TYPE_SESSION_KEY) && authInfo[TYPE_SESSION_KEY].is_array()) {
1554 for (int i = 0; i < SESSION_KEY_LENGTH; i++) {
1555 sessionKey[i] = authInfo[TYPE_SESSION_KEY][i];
1556 CLOGD("get session key auth version 1 %d", static_cast<uint8_t>(authInfo[TYPE_SESSION_KEY][i]));
1557 }
1558 return true;
1559 } else {
1560 CLOGE("get sessionkey from json data fail");
1561 return false;
1562 }
1563 }
1564
HandleQueryIpAction(const CastInnerRemoteDevice & remoteDevice,const json & authInfo)1565 void CastBindTargetCallback::HandleQueryIpAction(const CastInnerRemoteDevice &remoteDevice, const json &authInfo)
1566 {
1567 CLOGI("query p2p finish, notify session auth success");
1568 std::string localIp;
1569 std::string remoteIp;
1570 if (authInfo.contains(KEY_LOCAL_P2P_IP) && authInfo[KEY_LOCAL_P2P_IP].is_string()) {
1571 localIp = authInfo[KEY_LOCAL_P2P_IP];
1572 }
1573
1574 if (authInfo.contains(KEY_REMOTE_P2P_IP) && authInfo[KEY_REMOTE_P2P_IP].is_string()) {
1575 remoteIp = authInfo[KEY_REMOTE_P2P_IP];
1576 }
1577
1578 if (localIp.empty() || remoteIp.empty()) {
1579 CLOGI("Get remote device p2p ip is empty");
1580 if (remoteDevice.localWifiIp.empty() || remoteDevice.wifiIp.empty()) {
1581 CLOGI("device p2p ip is empty start disconnect");
1582 return;
1583 } else {
1584 localIp = remoteDevice.localWifiIp;
1585 remoteIp = remoteDevice.wifiIp;
1586 }
1587 }
1588
1589 CastDeviceDataManager::GetInstance().SetDeviceIp(remoteDevice.deviceId, localIp, remoteIp);
1590 ConnectionManager::GetInstance().NotifyConnectStage(remoteDevice, ConnectStageResult::AUTH_SUCCESS);
1591 }
1592
OnUnbindResult(const PeerTargetId & targetId,int32_t result,std::string content)1593 void CastUnBindTargetCallback::OnUnbindResult(const PeerTargetId &targetId, int32_t result, std::string content)
1594 {
1595 CLOGI("OnUnbindResult,device id:%s, result: %d, content: %s", targetId.deviceId.c_str(), result, content.c_str());
1596 }
1597
OnDeviceOnline(const DmDeviceInfo & deviceInfo)1598 void CastDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
1599 {
1600 CLOGI("device(%{public}s) is online", Utils::Mask(deviceInfo.deviceId).c_str());
1601 std::string deviceId = std::string(deviceInfo.deviceId);
1602 if (!ConnectionManager::GetInstance().IsBindTarget(deviceId)) {
1603 return;
1604 }
1605
1606 CLOGD("Online for bind target, networkId:%s", deviceInfo.networkId);
1607 if (!CastDeviceDataManager::GetInstance().SetDeviceNetworkId(deviceId, deviceInfo.networkId)) {
1608 return;
1609 }
1610 auto isActiveAuth = CastDeviceDataManager::GetInstance().GetDeviceIsActiveAuth(deviceId);
1611 if (isActiveAuth == std::nullopt || !(*isActiveAuth)) {
1612 return;
1613 }
1614 auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
1615 if (remote == std::nullopt) {
1616 CLOGE("Get remote device is empty");
1617 return;
1618 }
1619 if (!ConnectionManager::GetInstance().IsSingle(*remote)) {
1620 CLOGI("current device is not single device %s ", deviceId.c_str());
1621 return;
1622 }
1623 ConnectionManager::GetInstance().NotifyListenerToLoadSinkSA(deviceInfo.networkId);
1624 ConnectionManager::GetInstance().OpenConsultSession(*remote);
1625 }
1626
OnDeviceOffline(const DmDeviceInfo & deviceInfo)1627 void CastDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
1628 {
1629 CLOGI("device(%{public}s) is offline", Utils::Mask(deviceInfo.deviceId).c_str());
1630 }
1631
OnDeviceChanged(const DmDeviceInfo & deviceInfo)1632 void CastDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
1633 {
1634 CLOGI("device(%{public}s) is changed", Utils::Mask(deviceInfo.deviceId).c_str());
1635 }
1636
OnDeviceReady(const DmDeviceInfo & deviceInfo)1637 void CastDeviceStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
1638 {
1639 CLOGI("device(%{public}s) is ready", Utils::Mask(deviceInfo.deviceId).c_str());
1640 }
1641
IsSingle(const CastInnerRemoteDevice & device)1642 bool ConnectionManager::IsSingle(const CastInnerRemoteDevice &device)
1643 {
1644 if (device.authVersion == AUTH_VERSION_3) {
1645 CLOGI("Is hw single device");
1646 return true;
1647 }
1648 return false;
1649 }
1650
IsHuaweiDevice(const CastInnerRemoteDevice & device)1651 bool ConnectionManager::IsHuaweiDevice(const CastInnerRemoteDevice &device)
1652 {
1653 if (device.authVersion == AUTH_VERSION_2) {
1654 CLOGI("Is hw device");
1655 return true;
1656 }
1657 return false;
1658 }
1659
IsThirdDevice(const CastInnerRemoteDevice & device)1660 bool ConnectionManager::IsThirdDevice(const CastInnerRemoteDevice &device)
1661 {
1662 if (device.authVersion == AUTH_VERSION_1) {
1663 CLOGI("Is third device");
1664 return true;
1665 }
1666
1667 return false;
1668 }
1669
IsBindTarget(std::string deviceId)1670 bool ConnectionManager::IsBindTarget(std::string deviceId)
1671 {
1672 std::unique_lock<std::mutex> lock(mutex_);
1673 if (isBindTargetMap_.find(deviceId) == isBindTargetMap_.end()) {
1674 return false;
1675 }
1676
1677 isBindTargetMap_.erase(deviceId);
1678 return true;
1679 }
1680
GetRTSPPort()1681 int ConnectionManager::GetRTSPPort()
1682 {
1683 std::lock_guard<std::mutex> lock(mutex_);
1684 return rtspPort_;
1685 }
1686
SetRTSPPort(int port)1687 void ConnectionManager::SetRTSPPort(int port)
1688 {
1689 std::lock_guard<std::mutex> lock(mutex_);
1690 rtspPort_ = port;
1691 }
1692
1693 } // namespace CastEngineService
1694 } // namespace CastEngine
1695 } // namespace OHOS
1696