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