• 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 
40 using nlohmann::json;
41 using namespace OHOS::DistributedHardware;
42 using OHOS::DistributedHardware::DeviceManager;
43 using OHOS::DistributedHardware::PeerTargetId;
44 
45 namespace OHOS {
46 namespace CastEngine {
47 namespace CastEngineService {
48 DEFINE_CAST_ENGINE_LABEL("Cast-Connection-Manager");
49 namespace {
50 using namespace OHOS::DistributedHardware;
51 constexpr char SESSION_NAME[] = "CastPlusSessionName";
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 constexpr int FIRST_PRIO_INDEX = 0;
80 constexpr int SECOND_PRIO_INDEX = 1;
81 constexpr int THIRD_PRIO_INDEX = 2;
82 constexpr int MAX_LINK_TYPE_NUM = 3;
83 
84 /*
85  * send to json key auth version, hichain 1.0 or 2.0
86  */
87 const std::string AUTH_VERSION_KEY = "authVersion";
88 const std::string AUTH_VERSION_1 = "1.0";
89 const std::string AUTH_VERSION_2 = "2.0";
90 
91 constexpr int THIRD_TV = 0x2E;
92 
93 const std::string KEY_BIND_TARGET_ACTION = "action";
94 constexpr int ACTION_CONNECT_DEVICE = 0;
95 constexpr int ACTION_QUERY_P2P_IP = 1;
96 constexpr int ACTION_SEND_MESSAGE = 2;
97 
98 const std::string KEY_LOCAL_P2P_IP = "localP2PIp";
99 const std::string KEY_REMOTE_P2P_IP = "remoteP2PIp";
100 const std::string NETWORK_ID = "networkId";
101 
102 constexpr static int SECOND_BYTE_OFFSET = 8;
103 constexpr static int THIRD_BYTE_OFFSET = 16;
104 constexpr static int FOURTH_BYTE_OFFSET = 24;
105 
106 constexpr static int INT_FOUR = 4;
107 
DeviceDiscoveryWriteWrap(const std::string & funcName,const std::string & puid)108 void DeviceDiscoveryWriteWrap(const std::string& funcName, const std::string& puid)
109 {
110     HiSysEventWriteWrap(funcName, {
111         {"BIZ_SCENE", static_cast<int32_t>(BIZSceneType::DEVICE_DISCOVERY)},
112         {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_END)},
113         {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_DISCOVERY)},
114         {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
115         {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
116         {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
117         {"LOCAL_SESS_NAME", ""},
118         {"PEER_SESS_NAME", ""},
119         {"PEER_UDID", puid}});
120 }
121 
EstablishConsultWriteWrap(const std::string & funcName,int sceneType,const std::string & puid)122 void EstablishConsultWriteWrap(const std::string& funcName, int sceneType, const std::string& puid)
123 {
124     HiSysEventWriteWrap(funcName, {
125             {"BIZ_SCENE", sceneType},
126             {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::ESTABLISH_CONSULT_SESSION)},
127             {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_IDLE)},
128             {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
129             {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
130             {"LOCAL_SESS_NAME", ""},
131             {"PEER_SESS_NAME", ""},
132             {"PEER_UDID", puid}});
133 }
134 
DeviceAuthWriteWrap(const std::string & funcName,int sceneType,const std::string & puid)135 void DeviceAuthWriteWrap(const std::string& funcName, int sceneType, const std::string& puid)
136 {
137     HiSysEventWriteWrap(funcName, {
138             {"BIZ_SCENE", sceneType},
139             {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_BEGIN)},
140             {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_AUTHENTICATION)},
141             {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
142             {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
143             {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
144             {"LOCAL_SESS_NAME", ""},
145             {"PEER_SESS_NAME", ""},
146             {"PEER_UDID", puid}});
147 }
148 
OnBindResultFailedWriteWrap(const std::string & funcName,int32_t result,const std::string & puid)149 void OnBindResultFailedWriteWrap(const std::string& funcName, int32_t result, const std::string& puid)
150 {
151     auto errorCode = GetErrorCode(CAST_ENGINE_SYSTEM_ID, CAST_ENGINE_CAST_PLUS_MODULE_ID,
152         static_cast<uint16_t>(result));
153     HiSysEventWriteWrap(funcName, {
154             {"BIZ_SCENE", static_cast<int32_t>(GetBIZSceneType(
155                 ConnectionManager::GetInstance().GetProtocolType()))},
156             {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_END)},
157             {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_AUTHENTICATION)},
158             {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_FAILED)},
159             {"ERROR_CODE", errorCode}}, {
160             {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
161             {"LOCAL_SESS_NAME", ""},
162             {"PEER_SESS_NAME", ""},
163             {"PEER_UDID", puid}});
164 }
165 } // namespace
166 
167 /*
168 * User's unusual action or other event scenarios could cause changing of STATE or RESULT which delivered
169 * by DM.
170 */
171 const std::map<int, EventCode> CastBindTargetCallback::EVENT_CODE_MAP = {
172     // ----- ON RESULT != 0 -----
173     // SINK peer click distrust button during 3-state authentication.
174     { ERR_DM_AUTH_PEER_REJECT, EventCode::ERR_DISTRUST_BY_SINK },
175     // SINK peer click cancel button during pin code inputting.
176     { ERR_DM_BIND_USER_CANCEL_PIN_CODE_DISPLAY, EventCode::ERR_CANCEL_BY_SINK },
177     // SOURCE peer input wrong pin code up to 3 times
178     { ERR_DM_BIND_PIN_CODE_ERROR, EventCode::ERR_PIN_CODE_RETRY_COUNT_EXCEEDED },
179     // SOURCE peer click cancel button during pin code inputting.
180     { ERR_DM_BIND_USER_CANCEL_ERROR, EventCode::EVT_CANCEL_BY_SOURCE },
181     // SINK peer PIN code window closed.
182     { ERR_DM_TIME_OUT, EventCode::ERR_SINK_TIMEOUT },
183     // ----- ON RESULT == 0 -----
184     // DEFAULT event
185     { DmAuthStatus::STATUS_DM_AUTH_DEFAULT, EventCode::DEFAULT_EVENT },
186     // Sink peer click trust during 3-state authentication.
187     { DmAuthStatus::STATUS_DM_SHOW_PIN_INPUT_UI, EventCode::EVT_TRUST_BY_SINK },
188     // Build connection successfully.
189     { DmAuthStatus::STATUS_DM_AUTH_FINISH, EventCode::EVT_AUTHENTICATION_COMPLETED },
190     // Waiting for user to click confirm
191     { DmAuthStatus::STATUS_DM_SHOW_AUTHORIZE_UI, EventCode::EVT_SHOW_AUTHORIZE_UI }
192 };
193 
GetInstance()194 ConnectionManager &ConnectionManager::GetInstance()
195 {
196     static ConnectionManager instance{};
197     return instance;
198 }
199 
Init(std::shared_ptr<IConnectionManagerListener> listener)200 void ConnectionManager::Init(std::shared_ptr<IConnectionManagerListener> listener)
201 {
202     CLOGD("ConnectionManager init start");
203     if (listener == nullptr) {
204         CLOGE("The input listener is null!");
205         return;
206     }
207 
208     if (HasListener()) {
209         CLOGE("Already inited");
210         return;
211     }
212 
213     if (DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "",
214         std::make_shared<CastDeviceStateCallback>()) != DM_OK) {
215         CLOGE("Failed to register device state callback");
216         return;
217     }
218 
219     SetListener(listener);
220     CLOGD("ConnectionManager init done");
221 }
222 
Deinit()223 void ConnectionManager::Deinit()
224 {
225     CLOGD("Deinit start");
226     ResetListener();
227     DisableDiscoverable();
228     DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
229 }
230 
GetDmDeviceInfo(const std::string & deviceId)231 DmDeviceInfo ConnectionManager::GetDmDeviceInfo(const std::string &deviceId)
232 {
233     std::vector<DmDeviceInfo> trustedDevices;
234     if (DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", trustedDevices) != DM_OK) {
235         CLOGE("GetTrustedDeviceList fail");
236         return {};
237     }
238 
239     for (const auto &device : trustedDevices) {
240         if (device.deviceId == deviceId) {
241             return device;
242         }
243     }
244     CLOGW("Can't find device");
245     return {};
246 }
247 
IsDeviceTrusted(const std::string & deviceId,std::string & networkId)248 bool ConnectionManager::IsDeviceTrusted(const std::string &deviceId, std::string &networkId)
249 {
250     std::vector<DmDeviceInfo> trustedDevices;
251     if (DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", trustedDevices) != DM_OK) {
252         CLOGE("GetTrustedDeviceList fail");
253         return false;
254     }
255 
256     for (const auto &device : trustedDevices) {
257         CLOGV("Trusted device id(%s)", device.deviceId);
258         if (device.deviceId == deviceId) {
259             networkId = device.networkId;
260             return true;
261         }
262     }
263 
264     return false;
265 }
266 
SetProtocolType(int protocols)267 void ConnectionManager::SetProtocolType(int protocols)
268 {
269     protocolType_ = protocols;
270 }
271 
GetProtocolType() const272 int ConnectionManager::GetProtocolType() const
273 {
274     return protocolType_;
275 }
276 
ConnectDevice(const CastInnerRemoteDevice & dev)277 bool ConnectionManager::ConnectDevice(const CastInnerRemoteDevice &dev)
278 {
279     DeviceDiscoveryWriteWrap(__func__, GetAnonymousDeviceID(dev.deviceId));
280 
281     auto &deviceId = dev.deviceId;
282     CLOGI("ConnectDevice in, %s", deviceId.c_str());
283 
284     if (CastDeviceDataManager::GetInstance().IsDeviceUsed(deviceId)) {
285         CLOGD("Device: %s is used.", deviceId.c_str());
286         return true;
287     }
288 
289     if (!UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTING)) {
290         CLOGE("Device(%s) is missing", deviceId.c_str());
291         return false;
292     }
293 
294     DiscoveryManager::GetInstance().StopDiscovery();
295 
296     std::string networkId;
297     if (IsDeviceTrusted(dev.deviceId, networkId) && IsSingle(dev)) {
298         DeviceAuthWriteWrap(__func__, GetBIZSceneType(GetProtocolType()), GetAnonymousDeviceID(dev.deviceId));
299         if (!CastDeviceDataManager::GetInstance().SetDeviceNetworkId(deviceId, networkId) ||
300             !OpenConsultSession(deviceId)) {
301             (void)UpdateDeviceState(deviceId, RemoteDeviceState::FOUND);
302             return false;
303         }
304         NotifySessionEvent(deviceId, ConnectEvent::AUTH_START);
305         (void)UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTED);
306         return true;
307     }
308     NotifySessionEvent(deviceId, ConnectEvent::AUTH_START);
309     HiSysEventWriteWrap(__func__, {
310             {"BIZ_SCENE", GetBIZSceneType(GetProtocolType())},
311             {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_BEGIN)},
312             {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_AUTHENTICATION)},
313             {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_IDLE)},
314             {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
315             {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
316             {"LOCAL_SESS_NAME", ""}, {"PEER_SESS_NAME", ""},
317             {"PEER_UDID", GetAnonymousDeviceID(dev.deviceId)}});
318 
319     if (!BindTarget(dev)) {
320         (void)UpdateDeviceState(deviceId, RemoteDeviceState::FOUND);
321         return false;
322     }
323     if (isBindTargetMap_.find(deviceId) != isBindTargetMap_.end()) {
324         isBindTargetMap_[deviceId] = true;
325     } else {
326         isBindTargetMap_.insert({ deviceId, true });
327     }
328     CLOGI("ConnectDevice out, %s", deviceId.c_str());
329     return true;
330 }
331 
BindTarget(const CastInnerRemoteDevice & dev)332 bool ConnectionManager::BindTarget(const CastInnerRemoteDevice &dev)
333 {
334     CLOGD("device info is %s, device name %s, customData %s", dev.deviceId.c_str(), dev.deviceName.c_str(),
335         dev.customData.c_str());
336     PeerTargetId targetId = {
337         .deviceId = dev.deviceId,
338         .bleMac = dev.bleMac,
339         .wifiIp = dev.wifiIp,
340         .wifiPort = dev.wifiPort,
341     };
342     std::map<std::string, std::string> bindParam;
343     BuildBindParam(dev, bindParam);
344     int ret = DeviceManager::GetInstance().BindTarget(PKG_NAME, targetId, bindParam,
345         std::make_shared<CastBindTargetCallback>());
346     if (ret == ERR_DM_AUTH_BUSINESS_BUSY) {
347         CLOGE("bind fail, target is binding %d", ret);
348         auto networkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(dev.deviceId);
349         PeerTargetId targetId = {
350             .deviceId = *networkId,
351         };
352         std::map<std::string, std::string> unbindParam{};
353         if (!CastDeviceDataManager::GetInstance().IsDoubleFrameDevice(dev.deviceId)) {
354             DeviceManager::GetInstance().UnbindTarget(PKG_NAME, targetId, unbindParam, nullptr);
355         } else {
356             unbindParam.insert(
357                 std::pair<std::string, std::string>(PARAM_KEY_META_TYPE, std::to_string(5)));
358             DeviceManager::GetInstance().UnbindTarget(PKG_NAME, targetId, unbindParam, nullptr);
359         }
360         return false;
361     }
362 
363     if (ret != DM_OK) {
364         CLOGE("ConnectDevice BindTarget fail, ret = %{public}d)", ret);
365         CastEngineDfx::WriteErrorEvent(AUTHENTICATE_DEVICE_FAIL);
366         return false;
367     }
368 
369     CastDeviceDataManager::GetInstance().SetDeviceIsActiveAuth(dev.deviceId, true);
370     CLOGI("Finish to BindTarget device!");
371     return true;
372 }
373 
BuildBindParam(const CastInnerRemoteDevice & device,std::map<std::string,std::string> & bindParam)374 bool ConnectionManager::BuildBindParam(const CastInnerRemoteDevice &device,
375     std::map<std::string, std::string> &bindParam)
376 {
377     CLOGI("start BuildBindParam");
378     if (IsSingle(device)) { // bind target by dm
379         bindParam[PARAM_KEY_AUTH_TYPE] = AUTH_WITH_PIN;
380     } else { // bind target by meta node
381         std::unique_ptr<CastLocalDevice> local = GetLocalDeviceInfo();
382         if (local == nullptr) {
383             CLOGE("CastLocalDevice is null");
384             return false;
385         }
386         bindParam[DistributedHardware::PARAM_KEY_META_TYPE] = "5";
387         bindParam[KEY_TRANSFER_MODE] = std::to_string(TRANSFER_MODE_SOFTBUS_SINGLE);
388         bindParam[DEVICE_NAME_KEY] = local->deviceName;
389         bindParam[AUTH_VERSION_KEY] = GetAuthVersion(device);
390         bindParam[KEY_SESSION_ID] = std::to_string(device.sessionId);
391         bindParam["udid"] = device.udid;
392     }
393     return true;
394 }
395 
GetAuthVersion(const CastInnerRemoteDevice & device)396 std::string ConnectionManager::GetAuthVersion(const CastInnerRemoteDevice &device)
397 {
398     if (!device.bleMac.empty() && !device.customData.empty()) {
399         return AUTH_VERSION_2;
400     }
401     return device.wifiPort == 0 ? AUTH_VERSION_1 : AUTH_VERSION_2;
402 }
403 
QueryP2PIp(const CastInnerRemoteDevice & dev)404 bool ConnectionManager::QueryP2PIp(const CastInnerRemoteDevice &dev)
405 {
406     CLOGI("query p2p ip method in ");
407     auto temp = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(dev.deviceId);
408     if (temp == std::nullopt) {
409         CLOGE("GetDeviceByDeviceId the device(%s) is missing", dev.deviceId.c_str());
410         return false;
411     }
412 
413     CastInnerRemoteDevice device = *temp;
414 
415     PeerTargetId targetId;
416     targetId.deviceId = device.deviceId;
417     targetId.wifiIp = device.wifiIp;
418     targetId.wifiPort = device.wifiPort;
419     targetId.bleMac = device.bleMac;
420 
421     std::string localNetworkId = "";
422     if (DeviceManager::GetInstance().GetLocalDeviceNetWorkId(PKG_NAME, localNetworkId) != 0) {
423         CLOGI("GetLocalDeviceNetWorkId fail %s", localNetworkId.c_str());
424         return false;
425     }
426 
427     // The session can only be opened using a network ID instead of a UDID in OH system
428     auto remoteNetworkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(dev.deviceId);
429     if (remoteNetworkId == std::nullopt) {
430         return false;
431     }
432     std::map<std::string, std::string> bindParam;
433     bindParam[DistributedHardware::PARAM_KEY_META_TYPE] = "5";
434     bindParam[KEY_BIND_TARGET_ACTION] = std::to_string(ACTION_QUERY_P2P_IP);
435     bindParam["localNetworkId"] = localNetworkId;
436     bindParam["remoteNetworkId"] = remoteNetworkId.value();
437     CLOGI("QueryP2PIp localNetworkId=%s, remoteNetworkId=%s", localNetworkId.c_str(), remoteNetworkId.value().c_str());
438     DeviceManager::GetInstance().BindTarget(PKG_NAME, targetId, bindParam,
439         std::make_shared<CastBindTargetCallback>());
440     return true;
441 }
442 
OpenConsultSession(const std::string & deviceId)443 bool ConnectionManager::OpenConsultSession(const std::string &deviceId)
444 {
445     CLOGI("start open consult session");
446     // The session can only be opened using a network ID instead of a UDID in OH system
447     auto networkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(deviceId);
448     if (networkId == std::nullopt) {
449         return false;
450     }
451 
452     EstablishConsultWriteWrap(__func__, GetBIZSceneType(GetProtocolType()), GetAnonymousDeviceID(deviceId));
453 
454     SessionAttribute attr{};
455     attr.dataType = TYPE_BYTES;
456     attr.linkTypeNum = MAX_LINK_TYPE_NUM;
457     attr.linkType[FIRST_PRIO_INDEX] = LINK_TYPE_WIFI_P2P;
458     attr.linkType[SECOND_PRIO_INDEX] = LINK_TYPE_WIFI_WLAN_5G;
459     attr.linkType[THIRD_PRIO_INDEX] = LINK_TYPE_WIFI_WLAN_2G;
460     auto transportId = OpenSession(SESSION_NAME, SESSION_NAME, networkId->c_str(), "", &attr);
461     if (transportId <= INVALID_ID) {
462         CLOGW("Failed to open session, and try again, id:%{public}d", transportId);
463         transportId = OpenSession(SESSION_NAME, SESSION_NAME, networkId->c_str(), "", &attr);
464         if (transportId <= INVALID_ID) {
465             CLOGE("Failed to open session finally, id:%{public}d", transportId);
466             CastEngineDfx::WriteErrorEvent(OPEN_SESSION_FAIL);
467             auto errorCode = GetErrorCode(CAST_ENGINE_SYSTEM_ID, CAST_ENGINE_CAST_PLUS_MODULE_ID, OPEN_SESSION_FAIL);
468             HiSysEventWriteWrap(__func__, {
469                     {"BIZ_SCENE", GetBIZSceneType(GetProtocolType())},
470                     {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::ESTABLISH_CONSULT_SESSION)},
471                     {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_IDLE)},
472                     {"ERROR_CODE", errorCode}}, {
473                     {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
474                     {"LOCAL_SESS_NAME", ""},
475                     {"PEER_SESS_NAME", ""},
476                     {"PEER_UDID", GetAnonymousDeviceID(deviceId)}});
477 
478             return false;
479         }
480     }
481     if (!CastDeviceDataManager::GetInstance().SetDeviceTransId(deviceId, transportId)) {
482         CloseSession(transportId);
483         return false;
484     }
485 
486     HiSysEventWriteWrap(__func__, {
487             {"BIZ_SCENE", GetBIZSceneType(GetProtocolType())},
488             {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::ESTABLISH_CONSULT_SESSION)},
489             {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
490             {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
491             {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
492             {"LOCAL_SESS_NAME", ""},
493             {"PEER_SESS_NAME", ""},
494             {"PEER_UDID", GetAnonymousDeviceID(deviceId)}});
495 
496     UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTED);
497     CLOGI("Out, sessionId = %{public}d", transportId);
498     return true;
499 }
500 
GetLocalDeviceInfo()501 std::unique_ptr<CastLocalDevice> ConnectionManager::GetLocalDeviceInfo()
502 {
503     CLOGI("GetLocalDeviceInfo in");
504     DmDeviceInfo local;
505     if (DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, local) != DM_OK) {
506         CLOGE("Cannot get the local device info from DM");
507         return nullptr;
508     };
509     auto device = std::make_unique<CastLocalDevice>();
510     device->deviceId = local.deviceId;
511     device->deviceType = DeviceType::DEVICE_CAST_PLUS;
512     device->deviceName = local.deviceName;
513     CLOGI("GetLocalDeviceInfo out");
514     return device;
515 }
516 
SendConsultInfo(const std::string & deviceId,int port)517 void ConnectionManager::SendConsultInfo(const std::string &deviceId, int port)
518 {
519     CLOGI("SendConsultInfo In");
520     auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
521     if (remote == std::nullopt) {
522         CLOGE("Get remote device is empty");
523         return;
524     }
525 
526     SendConsultData(*remote, port);
527 }
528 
SendConsultData(const CastInnerRemoteDevice & device,int port)529 void ConnectionManager::SendConsultData(const CastInnerRemoteDevice &device, int port)
530 {
531     CLOGI("In");
532     int transportId = CastDeviceDataManager::GetInstance().GetDeviceTransId(device.deviceId);
533     if (transportId == INVALID_ID) {
534         CLOGE("transport id is invalid");
535         return;
536     }
537 
538     json data;
539     data[VERSION_KEY] = VERSION;
540     data[OPERATION_TYPE_KEY] = OPERATION_CONSULT;
541     data[SEQUENCE_NUMBER] = rand();
542     json body;
543     GetConsultationData(device, port, body);
544     data[DATA_KEY] = body;
545 
546     std::string dataStr = data.dump();
547     int ret = SendBytes(transportId, dataStr.c_str(), dataStr.size());
548     if (ret != SOFTBUS_OK) {
549         CLOGE("failed to send consultion data, return:%{public}d", ret);
550         CastEngineDfx::WriteErrorEvent(SEND_CONSULTION_DATA_FAIL);
551         return;
552     }
553     CLOGD("return:%{public}d, data:%s", ret, dataStr.c_str());
554 }
555 
GetConsultationData(const CastInnerRemoteDevice & device,int port,json & body)556 std::string ConnectionManager::GetConsultationData(const CastInnerRemoteDevice &device, int port, json &body)
557 {
558     auto local = GetLocalDeviceInfo();
559     if (local == nullptr) {
560         CLOGE("local device info is nullptr");
561         return "";
562     }
563 
564     body[DEVICE_ID_KEY] = local->deviceId;
565     body[DEVICE_NAME_KEY] = local->deviceName;
566     body[KEY_SESSION_ID] = device.sessionId;
567     body[KEY_TRANSFER_MODE] = TRANSFER_MODE_SOFTBUS_SINGLE;
568 
569     ProtocolType protocolType;
570     GetSessionProtocolType(device.sessionId, protocolType);
571     body[PROTOCOL_TYPE_KEY] = protocolType;
572 
573     if (GetAuthVersion(device) == AUTH_VERSION_2) {
574         body[TYPE_SESSION_KEY] = device.sessionKey;
575     }
576 
577     CLOGI("Encrypt data, localIp %s, remote is %s, port %d", device.localIp.c_str(), device.remoteIp.c_str(), port);
578     EncryptPort(port, device.sessionKey, body);
579     EncryptIp(device.localIp, SOURCE_IP_KEY, device.sessionKey, body);
580     EncryptIp(device.remoteIp, SINK_IP_KEY, device.sessionKey, body);
581     return body.dump();
582 }
583 
EncryptPort(int port,const uint8_t * sessionKey,json & body)584 void ConnectionManager::EncryptPort(int port, const uint8_t *sessionKey, json &body)
585 {
586     std::unique_ptr<uint8_t[]> portArray = intToByteArray(port);
587     int portArraySize = 4;
588     ConstPacketData inputData = { portArray.get(), portArraySize };
589 
590     uint8_t encryptedPort[portArraySize + EncryptDecrypt::AES_IV_LEN];
591     PacketData outputData = { encryptedPort, 0 };
592     EncryptDecrypt::GetInstance().EncryptData(EncryptDecrypt::CTR_CODE, sessionKey, SESSION_KEY_LENGTH, inputData,
593         outputData);
594     CLOGD("encrypt result is %d ", outputData.length);
595     std::string encryptedPortLatin1(reinterpret_cast<const char *>(outputData.data), outputData.length);
596     std::string encryptedPortUtf8 = convLatin1ToUTF8(encryptedPortLatin1);
597     body[PORT_KEY] = encryptedPortUtf8;
598 }
599 
convLatin1ToUTF8(std::string & latin1)600 std::string ConnectionManager::convLatin1ToUTF8(std::string &latin1)
601 {
602     iconv_t cd = iconv_open("utf8", "iso88591");
603     if (cd == (iconv_t)-1) {
604         CLOGD("andy Failed to open iconv conversion descriptor");
605         return "";
606     }
607 
608     size_t inSize = latin1.size();
609     size_t outSize = inSize * 2;
610     std::string utf8(outSize, 0);
611 
612     char *inbuf = &latin1[0];
613     char *outbuf = &utf8[0];
614     size_t result = iconv(cd, &inbuf, &inSize, &outbuf, &outSize);
615     if (result == (size_t)-1) {
616         CLOGD("Failed to convert encoding");
617         iconv_close(cd);
618         return "";
619     }
620 
621     iconv_close(cd);
622     utf8.resize(outbuf - &utf8[0]);
623     return utf8;
624 }
625 
EncryptIp(const std::string & ip,const std::string & key,const uint8_t * sessionKey,json & body)626 void ConnectionManager::EncryptIp(const std::string &ip, const std::string &key, const uint8_t *sessionKey, json &body)
627 {
628     if (ip.empty()) {
629         return;
630     }
631     ConstPacketData inputData = { reinterpret_cast<const uint8_t *>(ip.c_str()), ip.size() };
632     uint8_t encrypted[ip.size() + EncryptDecrypt::AES_IV_LEN];
633     PacketData outputData = { encrypted, 0 };
634     EncryptDecrypt::GetInstance().EncryptData(EncryptDecrypt::CTR_CODE, sessionKey, SESSION_KEY_LENGTH, inputData,
635         outputData);
636     for (int i = 0; i < outputData.length; i++) {
637         body[key].push_back(encrypted[i]);
638     }
639     CLOGI("encrypt %s finish", key.c_str());
640 }
641 
intToByteArray(int32_t num)642 std::unique_ptr<uint8_t[]> ConnectionManager::intToByteArray(int32_t num)
643 {
644     std::unique_ptr<uint8_t[]> result = std::make_unique<uint8_t[]>(INT_FOUR);
645     int i = 0;
646     result[i] = (num >> FOURTH_BYTE_OFFSET) & 0xFF;
647     result[++i] = (num >> THIRD_BYTE_OFFSET) & 0xFF;
648     result[++i] = (num >> SECOND_BYTE_OFFSET) & 0xFF;
649     result[++i] = num & 0xFF;
650     return result;
651 }
652 
OnConsultSessionOpened(int transportId,bool isSource)653 void ConnectionManager::OnConsultSessionOpened(int transportId, bool isSource)
654 {
655     std::thread([transportId, isSource]() {
656         if (isSource) {
657             auto device = CastDeviceDataManager::GetInstance().GetDeviceByTransId(transportId);
658             if (device == std::nullopt) {
659                 return;
660             }
661 
662             if (ConnectionManager::GetInstance().IsHuaweiDevice(*device)) {
663                 ConnectionManager::GetInstance().QueryP2PIp(*device);
664             } else {
665                 ConnectionManager::GetInstance().NotifySessionEvent((*device).deviceId, ConnectEvent::AUTH_SUCCESS);
666             }
667             return;
668         }
669         ConnectionManager::GetInstance().GrabDevice();
670         ConnectionManager::GetInstance().NotifySessionIsReady(transportId);
671         }).detach();
672     return;
673 }
674 
NotifySessionIsReady(int transportId)675 void ConnectionManager::NotifySessionIsReady(int transportId)
676 {
677     int castSessionId = listener_->NotifySessionIsReady();
678     if (castSessionId == INVALID_ID) {
679         CLOGE("sessionId is invalid");
680         return;
681     }
682 
683     std::lock_guard<std::mutex> lock(mutex_);
684     transIdToCastSessionIdMap_.insert({ transportId, castSessionId });
685 }
686 
GetCastSessionId(int transportId)687 int ConnectionManager::GetCastSessionId(int transportId)
688 {
689     std::lock_guard<std::mutex> lock(mutex_);
690     for (const auto &element : transIdToCastSessionIdMap_) {
691         if (element.first == transportId) {
692             return element.second;
693         }
694     }
695     CLOGE("Invalid transport id:%{public}d", transportId);
696     return INVALID_ID;
697 }
698 
GetRemoteFromJsonData(const std::string & data)699 std::unique_ptr<CastInnerRemoteDevice> ConnectionManager::GetRemoteFromJsonData(const std::string &data)
700 {
701     CLOGI("GetRemoteFromJsonData in");
702     json jsonObject;
703     if (!jsonObject.accept(data)) {
704         CLOGE("something wrong for the json data!");
705         return nullptr;
706     }
707     jsonObject = json::parse(data, nullptr, false);
708     if (!jsonObject.contains(DATA_KEY)) {
709         CLOGE("json object have no data!");
710         return nullptr;
711     }
712 
713     json remote;
714     if (jsonObject[DATA_KEY].is_string()) {
715         std::string dataString = jsonObject[DATA_KEY];
716         remote = json::parse(dataString, nullptr, false);
717     } else if (jsonObject[DATA_KEY].is_object()) {
718         remote = jsonObject[DATA_KEY];
719     } else {
720         CLOGE("data key in json object is invalid!");
721         return nullptr;
722     }
723 
724     if (remote.is_discarded()) {
725         CLOGE("json object discarded!");
726         return nullptr;
727     }
728 
729     if (remote.contains(DEVICE_ID_KEY) && !remote[DEVICE_ID_KEY].is_string()) {
730         CLOGE("DEVICE_ID_KEY json data is not string");
731         return nullptr;
732     }
733 
734     if (remote.contains(DEVICE_NAME_KEY) && !remote[DEVICE_NAME_KEY].is_string()) {
735         CLOGE("DEVICE_NAME_KEY json data is not string");
736         return nullptr;
737     }
738 
739     if (remote.contains(KEY_SESSION_ID) && !remote[KEY_SESSION_ID].is_number()) {
740         CLOGE("KEY_SESSION_ID json data is not number");
741         return nullptr;
742     }
743 
744     auto device = std::make_unique<CastInnerRemoteDevice>();
745     device->deviceId = remote.contains(DEVICE_ID_KEY) ? remote[DEVICE_ID_KEY] : "";
746     device->deviceName = remote.contains(DEVICE_NAME_KEY) ? remote[DEVICE_NAME_KEY] : "";
747     device->deviceType = DeviceType::DEVICE_CAST_PLUS;
748     if (remote.contains(KEY_SESSION_ID)) {
749         device->sessionId = remote[KEY_SESSION_ID];
750     }
751     if (remote.contains(PROTOCOL_TYPE_KEY) && remote[PROTOCOL_TYPE_KEY].is_number()) {
752         device->protocolType = remote[PROTOCOL_TYPE_KEY];
753     }
754     return device;
755 }
756 
OnConsultDataReceived(int transportId,const void * data,unsigned int dataLen)757 void ConnectionManager::OnConsultDataReceived(int transportId, const void *data, unsigned int dataLen)
758 {
759     std::string dataStr(static_cast<const char *>(data), dataLen);
760     CLOGD("Received data: len:%{public}u, data:%s", dataLen, dataStr.c_str());
761 
762     auto device = GetRemoteFromJsonData(dataStr);
763     if (device == nullptr) {
764         return;
765     }
766     const std::string &deviceId = device->deviceId;
767     auto dmDevice = GetDmDeviceInfo(deviceId);
768     if (deviceId.compare(dmDevice.deviceId) != 0) {
769         CLOGE("Failed to get DmDeviceInfo");
770         return;
771     }
772     int castSessionId = INVALID_ID;
773 
774     constexpr int32_t sleepTimeMs = 50;
775     constexpr int32_t retryTimes = 20;
776     int32_t retryTime = 0;
777 
778     while (castSessionId == INVALID_ID) {
779         if (castSessionId != INVALID_ID || retryTime > retryTimes) {
780             break;
781         }
782         std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
783         castSessionId = GetCastSessionId(transportId);
784         retryTime++;
785     }
786     if (castSessionId == INVALID_ID) {
787         CLOGE("session id invalid");
788         return;
789     }
790     CLOGI("protocolType is %d", device->protocolType);
791     if (device->protocolType == ProtocolType::CAST_PLUS_STREAM) {
792         SetSessionProtocolType(castSessionId, device->protocolType);
793     }
794 
795     if (!CastDeviceDataManager::GetInstance().AddDevice(*device, dmDevice)) {
796         return;
797     }
798     if (!CastDeviceDataManager::GetInstance().SetDeviceRole(deviceId, true) ||
799         !UpdateDeviceState(deviceId, RemoteDeviceState::CONNECTED)) {
800         CastDeviceDataManager::GetInstance().RemoveDevice(deviceId);
801         return;
802     }
803     if (!listener_->NotifyRemoteDeviceIsReady(castSessionId, *device)) {
804         CastDeviceDataManager::GetInstance().RemoveDevice(deviceId);
805     }
806 
807     DestroyConsulationSession(deviceId);
808 }
809 
DestroyConsulationSession(const std::string & deviceId)810 void ConnectionManager::DestroyConsulationSession(const std::string &deviceId)
811 {
812     CLOGI("DestroyConsulationSession in");
813     int transportId = CastDeviceDataManager::GetInstance().ResetDeviceTransId(deviceId);
814     if (transportId != INVALID_ID) {
815         CloseSession(transportId);
816     }
817 
818     auto isSink = CastDeviceDataManager::GetInstance().GetDeviceRole(deviceId);
819     if (isSink == std::nullopt || (*isSink)) {
820         // The sink's Server is only removed when DisableDiscoverable or Deinit is performed.
821         return;
822     }
823 }
824 
DisconnectDevice(const std::string & deviceId)825 void ConnectionManager::DisconnectDevice(const std::string &deviceId)
826 {
827     DiscoveryManager::GetInstance().StopDiscovery();
828     if (!CastDeviceDataManager::GetInstance().IsDeviceUsed(deviceId)) {
829         CLOGE("Device(%s) is not used, remove it", deviceId.c_str());
830         CastDeviceDataManager::GetInstance().UpdateDeivceByDeviceId(deviceId);
831         return;
832     }
833 
834     DestroyConsulationSession(deviceId);
835     auto isActiveAuth = CastDeviceDataManager::GetInstance().GetDeviceIsActiveAuth(deviceId);
836     if (isActiveAuth == std::nullopt) {
837         return;
838     }
839     auto networkId = CastDeviceDataManager::GetInstance().GetDeviceNetworkId(deviceId);
840     if (networkId == std::nullopt) {
841         return;
842     }
843 
844     CastDeviceDataManager::GetInstance().UpdateDeivceByDeviceId(deviceId);
845 }
846 
EnableDiscoverable()847 bool ConnectionManager::EnableDiscoverable()
848 {
849     std::lock_guard lock(mutex_);
850     if (isDiscoverable_) {
851         CLOGW("service has been set discoverable");
852         return true;
853     }
854 
855     isDiscoverable_ = true;
856     return true;
857 }
858 
DisableDiscoverable()859 bool ConnectionManager::DisableDiscoverable()
860 {
861     std::lock_guard lock(mutex_);
862     if (!isDiscoverable_) {
863         return true;
864     }
865 
866     isDiscoverable_ = false;
867     return true;
868 }
869 
GrabDevice()870 void ConnectionManager::GrabDevice()
871 {
872     CLOGI("GrabDevice in");
873     if (grabState_ == DeviceGrabState::NO_GRAB) {
874         return;
875     }
876     if (listener_ == nullptr) {
877         return;
878     }
879     listener_->GrabDevice(sessionId_);
880 }
881 
UpdateGrabState(bool changeState,int32_t sessionId)882 void ConnectionManager::UpdateGrabState(bool changeState, int32_t sessionId)
883 {
884     CLOGI("GrabDevice in");
885     std::lock_guard<std::mutex> lock(mutex_);
886     sessionId_ = sessionId;
887     if (changeState) {
888         grabState_ = DeviceGrabState::GRAB_ALLOWED;
889         return;
890     }
891     grabState_ = DeviceGrabState::NO_GRAB;
892 }
893 
SetListener(std::shared_ptr<IConnectionManagerListener> listener)894 void ConnectionManager::SetListener(std::shared_ptr<IConnectionManagerListener> listener)
895 {
896     std::lock_guard<std::mutex> lock(mutex_);
897     listener_ = listener;
898 }
899 
HasListener()900 bool ConnectionManager::HasListener()
901 {
902     std::lock_guard<std::mutex> lock(mutex_);
903     return listener_ != nullptr;
904 }
905 
ResetListener()906 void ConnectionManager::ResetListener()
907 {
908     SetListener(nullptr);
909     SetSessionListener(nullptr);
910 }
911 
UpdateDeviceState(const std::string & deviceId,RemoteDeviceState state)912 bool ConnectionManager::UpdateDeviceState(const std::string &deviceId, RemoteDeviceState state)
913 {
914     CLOGD("UpdateDeviceState: %s", REMOTE_DEVICE_STATE_STRING[static_cast<size_t>(state)].c_str());
915     return CastDeviceDataManager::GetInstance().SetDeviceState(deviceId, state);
916 }
917 
ReportErrorByListener(const std::string & deviceId,EventCode currentEventCode)918 void ConnectionManager::ReportErrorByListener(const std::string &deviceId, EventCode currentEventCode)
919 {
920     std::lock_guard<std::mutex> lock(mutex_);
921     if (!listener_) {
922         return;
923     }
924     listener_->OnEvent(deviceId, currentEventCode);
925 }
926 
GetSessionProtocolType(int sessionId,ProtocolType & protocolType)927 int32_t ConnectionManager::GetSessionProtocolType(int sessionId, ProtocolType &protocolType)
928 {
929     std::lock_guard<std::mutex> lock(mutex_);
930     if (!listener_) {
931         return CAST_ENGINE_ERROR;
932     }
933     return listener_->GetSessionProtocolType(sessionId, protocolType);
934 }
935 
SetSessionProtocolType(int sessionId,ProtocolType protocolType)936 int32_t ConnectionManager::SetSessionProtocolType(int sessionId, ProtocolType protocolType)
937 {
938     std::lock_guard<std::mutex> lock(mutex_);
939     if (!listener_) {
940         return CAST_ENGINE_ERROR;
941     }
942     return listener_->SetSessionProtocolType(sessionId, protocolType);
943 }
944 
NotifySessionEvent(const std::string & deviceId,int result)945 bool ConnectionManager::NotifySessionEvent(const std::string &deviceId, int result)
946 {
947     CLOGI("NotifySessionEvent in");
948     std::lock_guard<std::mutex> lock(mutex_);
949     if (sessionListener_ == nullptr) {
950         CLOGE("sessionListener is NULL");
951         return false;
952     }
953     sessionListener_->NotifySessionEvent(deviceId, result);
954     return true;
955 }
956 
NotifyDeviceIsOffline(const std::string & deviceId)957 void ConnectionManager::NotifyDeviceIsOffline(const std::string &deviceId)
958 {
959     CLOGI("NotifyDeviceIsOffline in");
960     std::lock_guard<std::mutex> lock(mutex_);
961     if (!listener_) {
962         return;
963     }
964     listener_->NotifyDeviceIsOffline(deviceId);
965 }
966 
SetSessionListener(std::shared_ptr<IConnectManagerSessionListener> listener)967 void ConnectionManager::SetSessionListener(std::shared_ptr<IConnectManagerSessionListener> listener)
968 {
969     std::lock_guard<std::mutex> lock(mutex_);
970     sessionListener_ = listener;
971 }
972 
OnBindResult(const PeerTargetId & targetId,int32_t result,int32_t status,std::string content)973 void CastBindTargetCallback::OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status,
974     std::string content)
975 {
976     CLOGI("OnBindResult, device id:%s, content:%s, status: %{public}d, result: %{public}d", targetId.deviceId.c_str(),
977         content.c_str(), status, result);
978     json authInfo;
979     if (authInfo.accept(content)) {
980         authInfo = json::parse(content, nullptr, false);
981         int action = -1;
982         if (authInfo.contains(KEY_BIND_TARGET_ACTION) && authInfo[KEY_BIND_TARGET_ACTION].is_number()) {
983             action = authInfo[KEY_BIND_TARGET_ACTION];
984         }
985         if (result == DM_OK && status == DmAuthStatus::STATUS_DM_AUTH_FINISH && action != -1) {
986             HandleBindAction(targetId, action, authInfo);
987             if (action != ACTION_CONNECT_DEVICE) {
988                 CLOGI("bindtarget action %d handle finish, return", action);
989                 return;
990             }
991         }
992     }
993 
994     EventCode currentEventCode;
995     // Non-zero RESULT as FIRST consideration, and STATE secondarily.
996     if (result != 0) {
997         CastEngineDfx::WriteErrorEvent(AUTHENTICATE_DEVICE_FAIL);
998         OnBindResultFailedWriteWrap(__func__, result, GetAnonymousDeviceID(targetId.deviceId));
999         currentEventCode = EVENT_CODE_MAP.count(result) ? EVENT_CODE_MAP.at(result) : EventCode::UNKNOWN_EVENT;
1000     } else {
1001         if (EVENT_CODE_MAP.count(status)) {
1002             currentEventCode = EVENT_CODE_MAP.at(status);
1003         } else {
1004             CLOGI("unknown status %d, return ", status);
1005             return;
1006         }
1007         HiSysEventWriteWrap(__func__, {
1008                 {"BIZ_SCENE", static_cast<int32_t>(GetBIZSceneType(
1009                     ConnectionManager::GetInstance().GetProtocolType()))},
1010                 {"BIZ_STATE", static_cast<int32_t>(BIZStateType::BIZ_STATE_END)},
1011                 {"BIZ_STAGE", static_cast<int32_t>(BIZSceneStage::DEVICE_AUTHENTICATION)},
1012                 {"STAGE_RES", static_cast<int32_t>(StageResType::STAGE_RES_SUCCESS)},
1013                 {"ERROR_CODE", CAST_RADAR_SUCCESS}}, {
1014                 {"TO_CALL_PKG", DEVICE_MANAGER_NAME},
1015                 {"LOCAL_SESS_NAME", ""},
1016                 {"PEER_SESS_NAME", ""},
1017                 {"PEER_UDID", GetAnonymousDeviceID(targetId.deviceId)}});
1018     }
1019     CLOGI("EventCode: %{public}d", static_cast<int32_t>(currentEventCode));
1020     ConnectionManager::GetInstance().ReportErrorByListener(targetId.deviceId, currentEventCode);
1021 }
1022 
HandleBindAction(const PeerTargetId & targetId,int action,const json & authInfo)1023 void CastBindTargetCallback::HandleBindAction(const PeerTargetId &targetId, int action, const json &authInfo)
1024 {
1025     CLOGI("action is %d", action);
1026     switch (action) {
1027         case ACTION_CONNECT_DEVICE: {
1028             HandleConnectDeviceAction(targetId, authInfo);
1029             return;
1030         }
1031         case ACTION_QUERY_P2P_IP: {
1032             HandleQueryIpAction(targetId, authInfo);
1033             return;
1034         }
1035         case ACTION_SEND_MESSAGE: {
1036             CLOGI("action operate 3 send message");
1037             return;
1038         }
1039         default: {
1040             CLOGW("unknow action %d", action);
1041             return;
1042         }
1043     }
1044 }
1045 
HandleConnectDeviceAction(const PeerTargetId & targetId,const json & authInfo)1046 void CastBindTargetCallback::HandleConnectDeviceAction(const PeerTargetId &targetId, const json &authInfo)
1047 {
1048     CLOGI("handle connect device action");
1049     if (authInfo.contains(NETWORK_ID) && !authInfo[NETWORK_ID].is_string()) {
1050         CLOGE("networkId json data is not string");
1051         return;
1052     }
1053 
1054     const std::string networkId = authInfo[NETWORK_ID];
1055     const std::string deviceId = targetId.deviceId;
1056     if (!CastDeviceDataManager::GetInstance().SetDeviceNetworkId(targetId.deviceId, networkId)) {
1057         return;
1058     }
1059 
1060     if (authInfo.contains(KEY_TRANSFER_MODE) && authInfo[KEY_TRANSFER_MODE].is_number()) {
1061         int mode = authInfo[KEY_TRANSFER_MODE];
1062         ChannelType type = mode == TRANSFER_MODE_SOFTBUS_SINGLE ? ChannelType::SOFT_BUS : ChannelType::LEGACY_CHANNEL;
1063         CastDeviceDataManager::GetInstance().SetDeviceChannleType(deviceId, type);
1064     }
1065 
1066     if (authInfo.contains(AUTH_VERSION_KEY) && authInfo[AUTH_VERSION_KEY].is_string()) {
1067         std::string authVersion = authInfo[AUTH_VERSION_KEY];
1068         CLOGE("authVersion is %s", authVersion.c_str());
1069         if (authVersion == AUTH_VERSION_1) {
1070             // 获取sessionKey
1071             uint8_t sessionKey[SESSION_KEY_LENGTH] = {0};
1072             bool result = GetSessionKey(authInfo, sessionKey);
1073             if (!result) {
1074                 CLOGE("auth version 1.0, get sessionkey fail");
1075                 return;
1076             }
1077             result = CastDeviceDataManager::GetInstance().SetDeviceSessionKey(deviceId, sessionKey);
1078             CLOGD("auth version 1.0, set sessionkey result is %d", result);
1079             ConnectionManager::GetInstance().NotifySessionEvent(deviceId, ConnectEvent::AUTH_SUCCESS);
1080         } else {
1081             uint8_t sessionKey[SESSION_KEY_LENGTH] = {0};
1082             RAND_bytes(sessionKey, SESSION_KEY_LENGTH);
1083             bool result = CastDeviceDataManager::GetInstance().SetDeviceSessionKey(deviceId, sessionKey);
1084             CLOGD("auth version 2.0, set sessionkey result is %d", result);
1085             ConnectionManager::GetInstance().OpenConsultSession(deviceId);
1086         }
1087     }
1088 }
1089 
GetSessionKey(const json & authInfo,uint8_t * sessionKey)1090 bool CastBindTargetCallback::GetSessionKey(const json &authInfo, uint8_t *sessionKey)
1091 {
1092     if (authInfo.contains(TYPE_SESSION_KEY) && authInfo[TYPE_SESSION_KEY].is_array()) {
1093         for (int i = 0; i < SESSION_KEY_LENGTH; i++) {
1094             sessionKey[i] = authInfo[TYPE_SESSION_KEY][i];
1095             CLOGD("get session key auth version 1 %d", static_cast<uint8_t>(authInfo[TYPE_SESSION_KEY][i]));
1096         }
1097         return true;
1098     } else {
1099         CLOGE("get sessionkey from json data fail");
1100         return false;
1101     }
1102 }
1103 
HandleQueryIpAction(const PeerTargetId & targetId,const json & authInfo)1104 void CastBindTargetCallback::HandleQueryIpAction(const PeerTargetId &targetId, const json &authInfo)
1105 {
1106     CLOGI("query p2p finish, notify session auth success");
1107     auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(targetId.deviceId);
1108     if (remote == std::nullopt) {
1109         CLOGE("Get remote device is empty");
1110         return;
1111     }
1112     std::string localIp;
1113     std::string remoteIp;
1114     if (authInfo.contains(KEY_LOCAL_P2P_IP) && authInfo[KEY_LOCAL_P2P_IP].is_string()) {
1115         localIp = authInfo[KEY_LOCAL_P2P_IP];
1116     }
1117 
1118     if (authInfo.contains(KEY_REMOTE_P2P_IP) && authInfo[KEY_REMOTE_P2P_IP].is_string()) {
1119         remoteIp = authInfo[KEY_REMOTE_P2P_IP];
1120     }
1121     CastDeviceDataManager::GetInstance().SetDeviceIp(targetId.deviceId, localIp, remoteIp);
1122     ConnectionManager::GetInstance().NotifySessionEvent(targetId.deviceId, ConnectEvent::AUTH_SUCCESS);
1123 }
1124 
OnUnbindResult(const PeerTargetId & targetId,int32_t result,std::string content)1125 void CastUnBindTargetCallback::OnUnbindResult(const PeerTargetId &targetId, int32_t result, std::string content)
1126 {
1127     CLOGI("OnUnbindResult,device id:%s, result: %d, content: %s", targetId.deviceId.c_str(), result, content.c_str());
1128 }
1129 
OnDeviceOnline(const DmDeviceInfo & deviceInfo)1130 void CastDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
1131 {
1132     CLOGI("device(%s) is online", deviceInfo.deviceId);
1133     DiscoveryManager::GetInstance().NotifyDeviceIsOnline(deviceInfo);
1134     std::string deviceId = std::string(deviceInfo.deviceId);
1135     if (ConnectionManager::GetInstance().isBindTargetMap_.find(deviceId) ==
1136         ConnectionManager::GetInstance().isBindTargetMap_.end()) {
1137         return;
1138     }
1139 
1140     CLOGD("Online for bind target, networkId:%s", deviceInfo.networkId);
1141     ConnectionManager::GetInstance().isBindTargetMap_.erase(deviceId);
1142     if (!CastDeviceDataManager::GetInstance().SetDeviceNetworkId(deviceId, deviceInfo.networkId)) {
1143         return;
1144     }
1145     auto isActiveAuth = CastDeviceDataManager::GetInstance().GetDeviceIsActiveAuth(deviceId);
1146     if (isActiveAuth == std::nullopt || !(*isActiveAuth)) {
1147         return;
1148     }
1149     auto remote = CastDeviceDataManager::GetInstance().GetDeviceByDeviceId(deviceId);
1150     if (remote == std::nullopt) {
1151         CLOGE("Get remote device is empty");
1152         return;
1153     }
1154     if (!ConnectionManager::GetInstance().IsSingle(*remote)) {
1155         CLOGI("current device is not single device %s ", deviceId.c_str());
1156         return;
1157     }
1158     ConnectionManager::GetInstance().OpenConsultSession(deviceId);
1159 }
1160 
OnDeviceOffline(const DmDeviceInfo & deviceInfo)1161 void CastDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
1162 {
1163     CLOGI("device(%s) is offline", deviceInfo.deviceId);
1164     ConnectionManager::GetInstance().NotifyDeviceIsOffline(deviceInfo.deviceId);
1165 }
1166 
OnDeviceChanged(const DmDeviceInfo & deviceInfo)1167 void CastDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
1168 {
1169     CLOGI("device(%s) is changed", deviceInfo.deviceId);
1170 }
1171 
OnDeviceReady(const DmDeviceInfo & deviceInfo)1172 void CastDeviceStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
1173 {
1174     CLOGI("device(%s) is ready", deviceInfo.deviceId);
1175 }
1176 
SetRTSPPort(int port)1177 void ConnectionManager::SetRTSPPort(int port)
1178 {
1179     std::lock_guard<std::mutex> lock(mutex_);
1180     rtspPort_ = port;
1181 }
1182 
IsSingle(const CastInnerRemoteDevice & device)1183 bool ConnectionManager::IsSingle(const CastInnerRemoteDevice &device)
1184 {
1185     if (device.deviceTypeId == THIRD_TV) {
1186         return false;
1187     }
1188 
1189     if (device.customData.empty() && device.wifiPort == 0 && device.bleMac.empty()) {
1190         return true;
1191     }
1192 
1193     if (device.customData.empty()) {
1194         return device.wifiPort != 0 || !device.bleMac.empty();
1195     }
1196     return false;
1197 }
1198 
IsHuaweiDevice(const CastInnerRemoteDevice & device)1199 bool ConnectionManager::IsHuaweiDevice(const CastInnerRemoteDevice &device)
1200 {
1201     if (!device.customData.empty()) {
1202         return true;
1203     }
1204     return false;
1205 }
1206 
IsThirdDevice(const CastInnerRemoteDevice & device)1207 bool ConnectionManager::IsThirdDevice(const CastInnerRemoteDevice &device)
1208 {
1209     if (device.deviceTypeId == THIRD_TV) {
1210         return true;
1211     }
1212     return device.bleMac.empty() && device.wifiPort == 0;
1213 }
1214 
GetRTSPPort()1215 int ConnectionManager::GetRTSPPort()
1216 {
1217     std::lock_guard<std::mutex> lock(mutex_);
1218     return rtspPort_;
1219 }
1220 } // namespace CastEngineService
1221 } // namespace CastEngine
1222 } // namespace OHOS
1223