• 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: 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