1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 */
15
16 #include "wfd_source_scene.h"
17 #include <display_manager.h>
18 #include <unistd.h>
19 #include "common/common_macro.h"
20 #include "common/const_def.h"
21 #include "common/reflect_registration.h"
22 #include "common/sharing_log.h"
23 #include "configuration/include/config.h"
24 #include "extend/magic_enum/magic_enum.hpp"
25 #include "network/socket/socket_utils.h"
26 #include "screen_capture_def.h"
27 #include "utils/utils.h"
28 #include "wfd_session_def.h"
29
30 namespace OHOS {
31 namespace Sharing {
32
33 // The most inclination to be a group owner
34 constexpr uint32_t GROUP_OWNER_INTENT_MAX = 15;
35
OnP2pStateChanged(int32_t state)36 void WfdSourceScene::WfdP2pCallback::OnP2pStateChanged(int32_t state)
37 {
38 SHARING_LOGI("state: %{public}d.", state);
39 auto scene = scene_.lock();
40 if (scene) {
41 switch (static_cast<Wifi::P2pState>(state)) {
42 case Wifi::P2pState::P2P_STATE_NONE:
43 break;
44 case Wifi::P2pState::P2P_STATE_IDLE:
45 break;
46 case Wifi::P2pState::P2P_STATE_STARTING:
47 break;
48 case Wifi::P2pState::P2P_STATE_STARTED:
49 if (scene->isSourceRunning_) {
50 scene->WfdP2pStart();
51 }
52 break;
53 case Wifi::P2pState::P2P_STATE_CLOSING:
54 break;
55 case Wifi::P2pState::P2P_STATE_CLOSED:
56 if (scene->isSourceRunning_) {
57 scene->isSourceRunning_ = false;
58 scene->WfdP2pStop();
59 scene->OnInnerError(0, 0, SharingErrorCode::ERR_NETWORK_ERROR, "NETWORK ERROR, P2P MODULE STOPPED");
60 }
61 break;
62 default:
63 SHARING_LOGI("none process case.");
64 break;
65 }
66 }
67 }
68
OnP2pPersistentGroupsChanged(void)69 void WfdSourceScene::WfdP2pCallback::OnP2pPersistentGroupsChanged(void)
70 {
71 SHARING_LOGI("%{public}s.", __FUNCTION__);
72 }
73
OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)74 void WfdSourceScene::WfdP2pCallback::OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)
75 {
76 SHARING_LOGI("%{public}s.", __FUNCTION__);
77 auto scene = scene_.lock();
78 if (scene == nullptr) {
79 SHARING_LOGW("scene is nullptr.");
80 return;
81 }
82
83 if (scene->p2pInstance_ == nullptr) {
84 SHARING_LOGW("p2pInstance is nullptr.");
85 return;
86 }
87
88 Wifi::WifiP2pLinkedInfo info;
89 if (scene->p2pInstance_->QueryP2pLinkedInfo(info)) {
90 SHARING_LOGE("failed to query p2p link info.");
91 return;
92 }
93
94 Wifi::P2pConnectedState state = info.GetConnectState();
95 SHARING_LOGI("ConnectState: %{public}d.", state);
96 if (state != Wifi::P2pConnectedState::P2P_DISCONNECTED) {
97 return;
98 }
99
100 if (scene->connDev_ != nullptr) {
101 scene->OnP2pPeerDisconnected(scene->connDev_->mac);
102 }
103 }
104
OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)105 void WfdSourceScene::WfdP2pCallback::OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)
106 {
107 SHARING_LOGI("%{public}s.", __FUNCTION__);
108 auto scene = scene_.lock();
109 RETURN_IF_NULL(scene);
110
111 if (!scene->isSourceDiscovering) {
112 SHARING_LOGI("p2p source is not discovering.");
113 return;
114 }
115
116 SHARING_LOGI("device size: %{public}zu.", device.size());
117 std::vector<WfdCastDeviceInfo> foundedDevices;
118 for (auto itDev : device) {
119 auto status = itDev.GetP2pDeviceStatus();
120 SHARING_LOGI("device name: %{public}s, mac: %{public}s, status: %{public}d.",
121 GetAnonyString(itDev.GetDeviceName()).c_str(), GetAnonyString(itDev.GetDeviceAddress()).c_str(),
122 status);
123 if (status == Wifi::P2pDeviceStatus::PDS_AVAILABLE) {
124 std::string subelement;
125 Wifi::WifiP2pWfdInfo wfdInfo(itDev.GetWfdInfo());
126 wfdInfo.GetDeviceInfoElement(subelement);
127 SHARING_LOGI("\tsession available: %{public}d"
128 "\tdevice info: %{private}s.",
129 wfdInfo.isSessionAvailable(), subelement.c_str());
130
131 if (wfdInfo.isSessionAvailable()) {
132 WfdCastDeviceInfo deviceInfo;
133 deviceInfo.deviceId = itDev.GetDeviceAddress();
134 deviceInfo.deviceName = itDev.GetDeviceName();
135 deviceInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
136 deviceInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
137
138 foundedDevices.emplace_back(deviceInfo);
139 }
140 }
141 }
142
143 if (!foundedDevices.empty()) {
144 scene->OnDeviceFound(foundedDevices);
145 }
146 }
147
OnP2pPrivatePeersChanged(const std::string &priWfdInfo)148 void WfdSourceScene::WfdP2pCallback::OnP2pPrivatePeersChanged(const std::string &priWfdInfo)
149 {
150 SHARING_LOGI("%{public}s.", __FUNCTION__);
151 }
152
OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)153 void WfdSourceScene::WfdP2pCallback::OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)
154 {
155 SHARING_LOGI("%{public}s.", __FUNCTION__);
156 }
157
OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)158 void WfdSourceScene::WfdP2pCallback::OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)
159 {
160 Wifi::P2pConnectedState state = info.GetConnectState();
161 SHARING_LOGI("OnP2pConnectionChanged ConnectState: %{public}d.", state);
162
163 auto scene = scene_.lock();
164 if (scene == nullptr || scene->p2pInstance_ == nullptr) {
165 SHARING_LOGW("scene is nullptr.");
166 return;
167 }
168
169 if (state != Wifi::P2pConnectedState::P2P_CONNECTED) {
170 scene->p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_DISCONNECT_DEVICE);
171 return;
172 }
173 scene->p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_CONNECT_DEVICE);
174 SHARING_LOGD("goip: %{private}s.", GetAnonyString(info.GetGroupOwnerAddress()).c_str());
175 if (info.GetGroupOwnerAddress() == "") {
176 return;
177 }
178
179 Wifi::WifiP2pGroupInfo group;
180 if (Wifi::ErrCode::WIFI_OPT_SUCCESS != scene->p2pInstance_->GetCurrentGroup(group)) {
181 SHARING_LOGE("GetCurrentGroup failed");
182 return;
183 }
184
185 Wifi::WifiP2pDevice goDevice = group.GetOwner();
186
187 ConnectionInfo connectionInfo;
188 connectionInfo.ip = info.GetGroupOwnerAddress();
189 connectionInfo.mac = goDevice.GetDeviceAddress();
190 connectionInfo.deviceName = goDevice.GetDeviceName();
191 connectionInfo.primaryDeviceType = goDevice.GetPrimaryDeviceType();
192 connectionInfo.secondaryDeviceType = goDevice.GetSecondaryDeviceType();
193 connectionInfo.ctrlPort = goDevice.GetWfdInfo().GetCtrlPort();
194 connectionInfo.state = ConnectionState::CONNECTED;
195
196 SHARING_LOGD("device connected, mac: %{private}s, ip: %{private}s, port: %{private}d.",
197 GetAnonyString(connectionInfo.mac).c_str(), GetAnonyString(connectionInfo.ip).c_str(),
198 connectionInfo.ctrlPort);
199 scene->OnP2pPeerConnected(connectionInfo);
200 }
201
OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)202 void WfdSourceScene::WfdP2pCallback::OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)
203 {
204 SHARING_LOGD("trace.");
205 }
206
OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)207 void WfdSourceScene::WfdP2pCallback::OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)
208 {
209 SHARING_LOGD("trace.");
210 }
211
OnP2pDiscoveryChanged(bool isChange)212 void WfdSourceScene::WfdP2pCallback::OnP2pDiscoveryChanged(bool isChange)
213 {
214 SHARING_LOGD("isChange: %{public}d.", isChange);
215 }
216
OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)217 void WfdSourceScene::WfdP2pCallback::OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)
218 {
219 SHARING_LOGD("action: %{public}hhu, code: %{public}d.", action, code);
220 }
221
OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)222 void WfdSourceScene::WfdP2pCallback::OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)
223 {
224 (void)type;
225 (void)data;
226 (void)dataLen;
227 SHARING_LOGI("%{public}s.", __FUNCTION__);
228 }
229
WfdSourceScene()230 WfdSourceScene::WfdSourceScene()
231 {
232 SHARING_LOGD("id: %{public}u.", GetId());
233 p2pSysEvent_ = std::make_shared<SharingHiSysEvent>(BIZSceneType::P2P_START_DISCOVERY, P2P_PKG);
234 }
235
~WfdSourceScene()236 WfdSourceScene::~WfdSourceScene()
237 {
238 SHARING_LOGD("id: %{public}u.", GetId());
239 Release();
240 }
241
OnCheckWfdConnection()242 void WfdSourceScene::OnCheckWfdConnection()
243 {
244 ResetCheckWfdConnectionTimer();
245 OnInnerError(0, 0, SharingErrorCode::ERR_CONNECTION_TIMEOUT, "wfd connection timeout");
246 }
247
SetCheckWfdConnectionTimer()248 void WfdSourceScene::SetCheckWfdConnectionTimer()
249 {
250 int32_t interval = P2P_CONNECT_TIMEOUT * WFD_SEC_TO_MSEC;
251 if (timer_ != nullptr) {
252 timerId_ = timer_->Register(std::bind(&WfdSourceScene::OnCheckWfdConnection, this), interval);
253 timer_->Setup();
254 }
255 }
256
ResetCheckWfdConnectionTimer()257 void WfdSourceScene::ResetCheckWfdConnectionTimer()
258 {
259 if (timer_ != nullptr && timerId_ != 0) {
260 timer_->Unregister(timerId_);
261 timerId_ = 0;
262 }
263 }
264
Initialize()265 void WfdSourceScene::Initialize()
266 {
267 SHARING_LOGI("%{public}s.", __FUNCTION__);
268 SharingValue::Ptr values = nullptr;
269
270 auto ret = Config::GetInstance().GetConfig("khSharingWfd", "ctrlport", "defaultWfdCtrlport", values);
271 if (ret == CONFIGURE_ERROR_NONE) {
272 values->GetValue<int32_t>(ctrlPort_);
273 }
274
275 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "videoCodec", values);
276 if (ret == CONFIGURE_ERROR_NONE) {
277 int32_t videoCodec;
278 values->GetValue<int32_t>(videoCodec);
279 videoCodecId_ = static_cast<CodecId>(videoCodec);
280 videoCodecId_ = CodecId::CODEC_H264;
281 }
282
283 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "videoFormat", values);
284 if (ret == CONFIGURE_ERROR_NONE) {
285 int32_t videoFormat;
286 values->GetValue<int32_t>(videoFormat);
287 videoFormat_ = static_cast<VideoFormat>(videoFormat);
288 videoFormat_ = VideoFormat::VIDEO_1920X1080_25;
289 }
290
291 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "audioCodec", values);
292 if (ret == CONFIGURE_ERROR_NONE) {
293 int32_t audioCodec;
294 values->GetValue<int32_t>(audioCodec);
295 audioCodecId_ = static_cast<CodecId>(audioCodec);
296 audioCodecId_ = CodecId::CODEC_AAC;
297 }
298
299 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "audioFormat", values);
300 if (ret == CONFIGURE_ERROR_NONE) {
301 int32_t audioFormat;
302 values->GetValue<int32_t>(audioFormat);
303 audioFormat_ = static_cast<AudioFormat>(audioFormat);
304 audioFormat_ = AudioFormat::AUDIO_48000_16_2;
305 }
306
307 p2pInstance_ = Wifi::WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
308 RETURN_IF_NULL(p2pInstance_);
309 if (shared_from_this() == nullptr) {
310 SHARING_LOGE("trace*********************WfdSourceScene NULL.");
311 }
312
313 sptr<WfdP2pCallback> wfdP2pCallback(new WfdP2pCallback(shared_from_this()));
314
315 std::vector<std::string> event = {EVENT_P2P_PEER_DEVICE_CHANGE, EVENT_P2P_DEVICE_STATE_CHANGE,
316 EVENT_P2P_CONN_STATE_CHANGE, EVENT_P2P_STATE_CHANGE,
317 EVENT_P2P_SERVICES_CHANGE, EVENT_P2P_DISCOVERY_CHANGE};
318 p2pInstance_->RegisterCallBack(wfdP2pCallback, event);
319 }
320
Release()321 void WfdSourceScene::Release()
322 {
323 SHARING_LOGI("%{public}s.", __FUNCTION__);
324 if (timer_ != nullptr) {
325 timer_->Shutdown();
326 timer_.reset();
327 }
328 auto sharingAdapter = sharingAdapter_.lock();
329 if (sharingAdapter != nullptr) {
330 std::lock_guard<std::mutex> lock(mutex_);
331 if ((connDev_ != nullptr) && (connDev_->contextId != INVALID_ID) && (connDev_->agentId != INVALID_ID)) {
332 auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
333 sessionMsg->type = EVENT_SESSION_TEARDOWN;
334 sessionMsg->toMgr = MODULE_CONTEXT;
335 sessionMsg->dstId = connDev_->contextId;
336 sessionMsg->agentId = connDev_->agentId;
337
338 SharingEvent event;
339 event.eventMsg = std::move(sessionMsg);
340 sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
341 sharingAdapter->DestroyAgent(connDev_->contextId, connDev_->agentId);
342 if ((contextId_ != INVALID_ID) && (agentId_ != INVALID_ID)) {
343 sharingAdapter->DestroyAgent(contextId_, agentId_);
344 }
345 }
346 }
347
348 if (p2pInstance_) {
349 p2pInstance_->RemoveGroup();
350 }
351 p2pInstance_.reset();
352 }
353
OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)354 void WfdSourceScene::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
355 {
356 SHARING_LOGI("%{public}s.", __FUNCTION__);
357 }
358
OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)359 void WfdSourceScene::OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
360 {
361 RETURN_IF_NULL(msg);
362 switch (msg->GetMsgId()) {
363 case WfdSourceStartDiscoveryReq::MSG_ID: {
364 auto rsp = std::make_shared<WfdCommonRsp>();
365
366 rsp->ret = HandleStartDiscovery(msg, rsp);
367 reply = std::static_pointer_cast<BaseMsg>(rsp);
368 break;
369 }
370 case WfdSourceStopDiscoveryReq::MSG_ID: {
371 auto rsp = std::make_shared<WfdCommonRsp>();
372
373 rsp->ret = HandleStopDiscovery(msg, rsp);
374 reply = std::static_pointer_cast<BaseMsg>(rsp);
375 break;
376 }
377 case WfdSourceAddDeviceReq::MSG_ID: {
378 ResetCheckWfdConnectionTimer();
379 auto rsp = std::make_shared<WfdCommonRsp>();
380 rsp->ret = WfdSourceScene::HandleAddDevice(msg, rsp);
381 SetCheckWfdConnectionTimer();
382 reply = std::static_pointer_cast<BaseMsg>(rsp);
383 break;
384 }
385 case WfdSourceRemoveDeviceReq::MSG_ID: {
386 auto rsp = std::make_shared<WfdCommonRsp>();
387
388 rsp->ret = HandleRemoveDevice(msg, rsp);
389 reply = std::static_pointer_cast<BaseMsg>(rsp);
390 break;
391 }
392 case DestroyScreenCaptureReq::MSG_ID: {
393 auto data = std::static_pointer_cast<DestroyScreenCaptureReq>(msg);
394 auto rsp = std::make_shared<WfdCommonRsp>();
395 rsp->ret = HandleDestroyScreenCapture(data);
396 reply = std::static_pointer_cast<BaseMsg>(rsp);
397 break;
398 }
399 default:
400 SHARING_LOGW("unknown msg request.");
401 break;
402 }
403 }
404
HandleStartDiscovery(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)405 int32_t WfdSourceScene::HandleStartDiscovery(std::shared_ptr<BaseMsg> &baseMsg,
406 std::shared_ptr<WfdCommonRsp> &reply)
407 {
408 SHARING_LOGI("%{public}s.", __FUNCTION__);
409 (void)baseMsg;
410 (void)reply;
411 int32_t ret = 0;
412 if (p2pInstance_ == nullptr) {
413 SHARING_LOGW("p2pInstance is nullptr.");
414 return -1;
415 }
416 if (!isSourceRunning_) {
417 p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_START_DISCOVERY);
418 int32_t status = 0;
419 p2pInstance_->GetP2pEnableStatus(status);
420 switch (static_cast<Wifi::P2pState>(status)) {
421 case Wifi::P2pState::P2P_STATE_NONE: // fall-through
422 case Wifi::P2pState::P2P_STATE_IDLE: // fall-through
423 case Wifi::P2pState::P2P_STATE_STARTING: // fall-through
424 case Wifi::P2pState::P2P_STATE_CLOSING: {
425 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleStart current p2p state: CLOSING");
426 ret = -1;
427 break;
428 }
429 case Wifi::P2pState::P2P_STATE_STARTED: {
430 isSourceRunning_ = true;
431 WfdP2pStart();
432 break;
433 }
434 case Wifi::P2pState::P2P_STATE_CLOSED: {
435 isSourceRunning_ = true;
436 p2pInstance_->EnableP2p();
437 break;
438 }
439 default: {
440 SHARING_LOGI("none process case.");
441 break;
442 }
443 }
444 }
445 if (ret == 0) {
446 ret = p2pInstance_->DiscoverDevices();
447 isSourceDiscovering = true;
448 } else {
449 p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_START_DISCOVERY, BlzErrorCode::ERROR_FAIL);
450 }
451 return ret;
452 }
453
HandleStopDiscovery(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)454 int32_t WfdSourceScene::HandleStopDiscovery(std::shared_ptr<BaseMsg> &baseMsg,
455 std::shared_ptr<WfdCommonRsp> &reply)
456 {
457 SHARING_LOGI("%{public}s.", __FUNCTION__);
458 (void)baseMsg;
459 (void)reply;
460 if (!isSourceRunning_) {
461 SHARING_LOGW("p2p source is not running.");
462 return -1;
463 }
464
465 if (p2pInstance_ == nullptr) {
466 SHARING_LOGW("p2pInstance is nullptr.");
467 return -1;
468 }
469
470 int32_t ret = p2pInstance_->StopDiscoverDevices();
471 isSourceDiscovering = false;
472 return ret;
473 }
474
HandleAddDevice(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)475 int32_t WfdSourceScene::HandleAddDevice(std::shared_ptr<BaseMsg> &baseMsg,
476 std::shared_ptr<WfdCommonRsp> &reply)
477 {
478 SHARING_LOGI("%{public}s.", __FUNCTION__);
479 (void)reply;
480 if (!isSourceRunning_ || p2pInstance_ == nullptr) {
481 SHARING_LOGW("p2p source is not running.");
482 return -1;
483 }
484
485 std::shared_ptr<WfdSourceAddDeviceReq> msg = std::static_pointer_cast<WfdSourceAddDeviceReq>(baseMsg);
486 auto displayIds = OHOS::Rosen::DisplayManager::GetInstance().GetAllDisplayIds();
487 bool findDisplayId = false;
488 for (auto displayId : displayIds) {
489 SHARING_LOGD("displayId = %{public}" PRIu64, displayId);
490 if (msg->screenId == displayId) {
491 findDisplayId = true;
492 break;
493 }
494 }
495 if (!findDisplayId) {
496 SHARING_LOGE("can't find screenId %{public}" PRIu64, msg->screenId);
497 return ERR_BAD_PARAMETER;
498 }
499 p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_DEVICE_FOUND);
500 p2pSysEvent_->ChangeScene(BIZSceneType::P2P_CONNECT_DEVICE);
501 p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_CONNECT_DEVICE);
502 Wifi::WifiP2pConfig config;
503 config.SetDeviceAddress(msg->deviceId);
504 config.SetDeviceAddressType(OHOS::Wifi::RANDOM_DEVICE_ADDRESS);
505 config.SetGroupOwnerIntent(GROUP_OWNER_INTENT_MAX - 1);
506
507 screenId_ = msg->screenId;
508 int32_t ret = p2pInstance_->P2pConnect(config);
509 SHARING_LOGE("connect device: %{public}s, ret = %{public}d", GetAnonyString(msg->deviceId).c_str(), ret);
510 return ret;
511 }
512
HandleRemoveDevice(std::shared_ptr<BaseMsg> &baseMsg, std::shared_ptr<WfdCommonRsp> &reply)513 int32_t WfdSourceScene::HandleRemoveDevice(std::shared_ptr<BaseMsg> &baseMsg,
514 std::shared_ptr<WfdCommonRsp> &reply)
515 {
516 SHARING_LOGI("%{public}s.", __FUNCTION__);
517 (void)reply;
518 auto sharingAdapter = sharingAdapter_.lock();
519 RETURN_INVALID_IF_NULL(sharingAdapter);
520
521 std::shared_ptr<WfdSourceRemoveDeviceReq> msg = std::static_pointer_cast<WfdSourceRemoveDeviceReq>(baseMsg);
522
523 std::lock_guard<std::mutex> lock(mutex_);
524 if ((connDev_ == nullptr) || (connDev_->mac != msg->deviceId) || connDev_->state != ConnectionState::CONNECTED) {
525 SHARING_LOGE("can not find dev, deviceId: %{public}s.", GetAnonyString(msg->deviceId).c_str());
526 return -1;
527 }
528 auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
529 sessionMsg->type = EVENT_SESSION_TEARDOWN;
530 sessionMsg->toMgr = MODULE_CONTEXT;
531 sessionMsg->dstId = connDev_->contextId;
532 sessionMsg->agentId = connDev_->agentId;
533
534 SharingEvent event;
535 event.eventMsg = std::move(sessionMsg);
536 sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
537
538 connDev_.reset();
539 int ret = sharingAdapter->DestroyAgent(contextId_, agentId_);
540 if (p2pInstance_) {
541 p2pSysEvent_->ChangeScene(BIZSceneType::P2P_DISCONNECT_DEVICE);
542 p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_DISCONNECT_DEVICE);
543 p2pInstance_->RemoveGroup();
544 }
545 return ret;
546 }
547
CreateScreenCapture()548 int32_t WfdSourceScene::CreateScreenCapture()
549 {
550 SHARING_LOGI("%{public}s.", __FUNCTION__);
551 auto sharingAdapter = sharingAdapter_.lock();
552 if (sharingAdapter != nullptr) {
553 std::unique_lock<std::mutex> lock(mutex_);
554
555 sharingAdapter->CreateAgent(contextId_, agentId_, AgentType::SINK_AGENT, "ScreenCaptureSession");
556 if (contextId_ == INVALID_ID || agentId_ == INVALID_ID) {
557 lock.unlock();
558 SHARING_LOGE("Create ScreenCapture sink agent failed");
559 return ERR_AGENT_CREATE;
560 } else {
561 SHARING_LOGI("Create ScreenCapture sink agent, contextId: %{public}u, agentId: %{public}u", contextId_,
562 agentId_);
563 }
564
565 auto startSessionMsg = std::make_shared<ScreenCaptureSessionEventMsg>();
566 startSessionMsg->mediaType = MEDIA_TYPE_AV;
567 startSessionMsg->type = EVENT_SESSION_INIT;
568 startSessionMsg->toMgr = MODULE_CONTEXT;
569 startSessionMsg->dstId = contextId_;
570 startSessionMsg->agentId = agentId_;
571 startSessionMsg->screenId = screenId_;
572 videoFormat_ = VideoFormat::VIDEO_1920X1080_25;
573
574 startSessionMsg->videoFormat = videoFormat_;
575 startSessionMsg->audioFormat = audioFormat_;
576
577 SharingEvent event;
578 event.eventMsg = std::move(startSessionMsg);
579
580 sharingAdapter->ForwardEvent(contextId_, agentId_, event, true);
581 sharingAdapter->Start(contextId_, agentId_);
582 }
583
584 return ERR_OK;
585 }
586
HandleDestroyScreenCapture(std::shared_ptr<DestroyScreenCaptureReq> &msg)587 int32_t WfdSourceScene::HandleDestroyScreenCapture(std::shared_ptr<DestroyScreenCaptureReq> &msg)
588 {
589 SHARING_LOGI("%{public}s.", __FUNCTION__);
590 (void)msg;
591 auto sharingAdapter = sharingAdapter_.lock();
592 if (sharingAdapter != nullptr) {
593 sharingAdapter->DestroyAgent(contextId_, agentId_);
594 }
595 return ERR_OK;
596 }
597
AppendCast(const std::string &deviceId)598 int32_t WfdSourceScene::AppendCast(const std::string &deviceId)
599 {
600 SHARING_LOGI("%{public}s.", __FUNCTION__);
601 auto sharingAdapter = sharingAdapter_.lock();
602 RETURN_INVALID_IF_NULL(sharingAdapter);
603
604 std::unique_lock<std::mutex> lock(mutex_);
605 if ((connDev_ == nullptr) || (connDev_->mac != deviceId)) {
606 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(deviceId).c_str());
607 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "AppendCast can't find the dev");
608 return -1;
609 }
610 auto port = SocketUtils::GetAvailableUdpPortPair();
611 if (port == 0) {
612 SHARING_LOGE("get udp port failed.");
613 return -1;
614 }
615
616 uint32_t contextId = contextId_;
617 uint32_t agentId = agentId_;
618 sharingAdapter->CreateAgent(contextId, agentId, AgentType::SRC_AGENT, "WfdSourceSession");
619 if (contextId == INVALID_ID || agentId == INVALID_ID) {
620 lock.unlock();
621 SHARING_LOGE("create source agent failed.");
622 return -1;
623 }
624 SHARING_LOGI("create source agent, contextId: %{public}u, agentId: %{public}u", contextId, agentId);
625 connDev_->contextId = contextId;
626 connDev_->agentId = agentId;
627
628 if (connDev_->isRunning == true) {
629 return 0;
630 }
631 connDev_->isRunning = true;
632
633 auto startSessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
634 startSessionMsg->type = EVENT_SESSION_INIT;
635 startSessionMsg->sinkAgentId = agentId_;
636 startSessionMsg->toMgr = MODULE_CONTEXT;
637 startSessionMsg->dstId = contextId;
638 startSessionMsg->agentId = agentId;
639 startSessionMsg->ip = connDev_->ip;
640 startSessionMsg->mac = connDev_->mac;
641 startSessionMsg->remotePort = connDev_->ctrlPort;
642 startSessionMsg->videoFormat = connDev_->videoFormatId;
643 startSessionMsg->audioFormat = connDev_->audioFormatId;
644 startSessionMsg->localPort = port;
645
646 SharingEvent event;
647 event.eventMsg = std::move(startSessionMsg);
648 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
649 sharingAdapter->Start(contextId, agentId);
650
651 return 0;
652 }
653
WfdP2pStart()654 void WfdSourceScene::WfdP2pStart()
655 {
656 SHARING_LOGI("%{public}s.", __FUNCTION__);
657 if (p2pInstance_) {
658 p2pInstance_->RemoveGroup();
659
660 Wifi::WifiP2pWfdInfo wfdInfo;
661 wfdInfo.SetWfdEnabled(true);
662 wfdInfo.SetDeviceInfo(0x10);
663 wfdInfo.SetCtrlPort(ctrlPort_);
664 wfdInfo.SetMaxThroughput(0x00c8);
665
666 p2pInstance_->SetP2pWfdInfo(wfdInfo);
667
668 SHARING_LOGD("WfdSourceScene DiscoverDevices.");
669 p2pInstance_->DiscoverDevices();
670 isSourceDiscovering = true;
671 }
672 }
673
WfdP2pStop()674 void WfdSourceScene::WfdP2pStop()
675 {
676 SHARING_LOGI("%{public}s.", __FUNCTION__);
677 auto sharingAdapter = sharingAdapter_.lock();
678 if (sharingAdapter != nullptr) {
679 std::lock_guard<std::mutex> lock(mutex_);
680 if ((connDev_ != nullptr) && (connDev_->contextId != INVALID_ID) && (connDev_->agentId != INVALID_ID)) {
681 auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
682 sessionMsg->type = EVENT_SESSION_TEARDOWN;
683 sessionMsg->toMgr = MODULE_CONTEXT;
684 sessionMsg->dstId = connDev_->contextId;
685 sessionMsg->agentId = connDev_->agentId;
686 SharingEvent event;
687 event.eventMsg = std::move(sessionMsg);
688 sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
689 }
690
691 if ((contextId_ != INVALID_ID) && (agentId_ != INVALID_ID)) {
692 sharingAdapter->DestroyAgent(contextId_, agentId_);
693 }
694 }
695
696 if (p2pInstance_) {
697 p2pInstance_->RemoveGroup();
698 }
699 }
700
OnDeviceFound(const std::vector<WfdCastDeviceInfo> &deviceInfos)701 void WfdSourceScene::OnDeviceFound(const std::vector<WfdCastDeviceInfo> &deviceInfos)
702 {
703 SHARING_LOGI("%{public}s.", __FUNCTION__);
704 auto ipcAdapter = ipcAdapter_.lock();
705 RETURN_IF_NULL(ipcAdapter);
706 auto msg = std::make_shared<WfdSourceDeviceFoundMsg>();
707 msg->deviceInfos = deviceInfos;
708 if (p2pSysEvent_->GetScene() == static_cast<int>(BIZSceneType::P2P_START_DISCOVERY)) {
709 for (auto &deviceInfo : deviceInfos) {
710 p2pSysEvent_->Report(__func__, BIZSceneStage::P2P_DEVICE_FOUND, StageResType::STAGE_RES_SUCCESS,
711 GetAnonyString(deviceInfo.deviceId));
712 }
713 }
714
715 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
716 ipcAdapter->SendRequest(msg, reply);
717 }
718
OnP2pPeerConnected(ConnectionInfo &connectionInfo)719 void WfdSourceScene::OnP2pPeerConnected(ConnectionInfo &connectionInfo)
720 {
721 SHARING_LOGE("OnP2pPeerConnected, deviceName: %{public}s, mac: %{public}s, ip: %{public}s, port: %{public}d.",
722 GetAnonyString(connectionInfo.deviceName).c_str(), GetAnonyString(connectionInfo.mac).c_str(),
723 GetAnonyString(connectionInfo.ip).c_str(), connectionInfo.ctrlPort);
724
725 if (!isSourceRunning_) {
726 SHARING_LOGW("source service is not running.");
727 return;
728 }
729
730 auto sharingAdapter = sharingAdapter_.lock();
731 if (sharingAdapter != nullptr) {
732 std::lock_guard<std::mutex> lock(mutex_);
733 if ((connDev_ != nullptr) && (connDev_->mac == connectionInfo.mac)) {
734 SHARING_LOGW("devcie is alerady connected, mac: %s.", GetAnonyString(connectionInfo.mac).c_str());
735 return;
736 }
737 connectionInfo.videoCodecId = videoCodecId_;
738 connectionInfo.videoFormatId = videoFormat_;
739 connectionInfo.audioCodecId = audioCodecId_;
740 connectionInfo.audioFormatId = audioFormat_;
741
742 connDev_ = std::make_unique<ConnectionInfo>(connectionInfo);
743 SHARING_LOGI("connected, devMac: %s, devIp: %s.", GetAnonyString(connectionInfo.mac).c_str(),
744 GetAnonyString(connectionInfo.ip).c_str());
745 }
746
747 OnConnectionChanged(connectionInfo);
748 }
749
OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)750 void WfdSourceScene::OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)
751 {
752 SHARING_LOGI("%{public}s.", __FUNCTION__);
753 OnP2pPeerDisconnected(connectionInfo.mac);
754 }
755
OnP2pPeerDisconnected(const std::string &mac)756 void WfdSourceScene::OnP2pPeerDisconnected(const std::string &mac)
757 {
758 SHARING_LOGI("%{public}s.", __FUNCTION__);
759 {
760 std::lock_guard<std::mutex> lock(mutex_);
761 if ((connDev_ == nullptr) || (connDev_->mac != mac)) {
762 SHARING_LOGW("can not find dev, mac: %s.", GetAnonyString(mac).c_str());
763 return;
764 }
765 connDev_->state = ConnectionState::DISCONNECTED;
766 OnConnectionChanged(*connDev_);
767 connDev_.reset();
768 }
769
770 if ((contextId_ == INVALID_ID) || (agentId_ == INVALID_ID)) {
771 return;
772 }
773
774 auto sharingAdapter = sharingAdapter_.lock();
775 if (sharingAdapter != nullptr) {
776 sharingAdapter->DestroyAgent(contextId_, agentId_);
777 }
778
779 if (p2pInstance_) {
780 p2pInstance_->RemoveGroup();
781 }
782 }
783
ErrorCodeFiltering(int32_t &code)784 void WfdSourceScene::ErrorCodeFiltering(int32_t &code)
785 {
786 SHARING_LOGD("the error code is %{public}d.", code);
787 switch (ABSTRACT_ERR_BASE(code)) {
788 case SharingErrorCode::ERR_CONTEXT_AGENT_BASE: // fall-through
789 case SharingErrorCode::ERR_SESSION_BASE:
790 code = SharingErrorCode::ERR_GENERAL_ERROR;
791 SHARING_LOGD("the error change to %{public}d.", code);
792 break;
793 case SharingErrorCode::ERR_PROSUMER_BASE: {
794 switch (code) {
795 case ERR_PROSUMER_START:
796 code = SharingErrorCode::ERR_CONNECTION_FAILURE;
797 break;
798 case ERR_PROSUMER_TIMEOUT:
799 code = SharingErrorCode::ERR_CONNECTION_TIMEOUT;
800 break;
801 case ERR_PROSUMER_DESTROY:
802 code = SharingErrorCode::ERR_STATE_EXCEPTION;
803 break;
804 default:
805 code = SharingErrorCode::ERR_GENERAL_ERROR;
806 break;
807 }
808 break;
809 }
810 default:
811 SHARING_LOGI("none process case.");
812 break;
813 }
814 }
815
OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)816 void WfdSourceScene::OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)
817 {
818 SHARING_LOGI("%{public}s.", __FUNCTION__);
819 auto ipcAdapter = ipcAdapter_.lock();
820 RETURN_IF_NULL(ipcAdapter);
821
822 auto msg = std::make_shared<WfdErrorMsg>();
823 msg->contextId = contextId;
824 msg->agentId = agentId;
825 msg->errorCode = errorCode;
826
827 if (errorCode == SharingErrorCode::ERR_PROSUMER_TIMEOUT) {
828 msg->message =
829 "contextId: " + std::to_string(contextId) + ", agentId: " + std::to_string(agentId) + ", producer timeout";
830 } else {
831 msg->message = std::move(message);
832 }
833
834 ErrorCodeFiltering(msg->errorCode);
835 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
836
837 SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
838 ipcAdapter->SendRequest(msg, reply);
839 }
840
OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)841 void WfdSourceScene::OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)
842 {
843 SHARING_LOGI("HandleInnerDestroy, contextId: %{public}u, agentId: %{public}u, agentType: %{public}s.", contextId,
844 agentId, std::string(magic_enum::enum_name(agentType)).c_str());
845 std::lock_guard<std::mutex> lock(mutex_);
846 if (connDev_ == nullptr) {
847 SHARING_LOGE("connDev_ is nullptr.");
848 return;
849 }
850
851 if ((contextId == connDev_->contextId) && ((agentId == connDev_->agentId) || agentId == agentId_)) {
852 connDev_->state = ConnectionState::DISCONNECTED;
853 OnConnectionChanged(*connDev_);
854 }
855 }
856
OnInnerEvent(SharingEvent &event)857 void WfdSourceScene::OnInnerEvent(SharingEvent &event)
858 {
859 RETURN_IF_NULL(event.eventMsg);
860
861 SHARING_LOGI("OnInnerEvent Type: %{public}s.", std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
862 switch (event.eventMsg->type) {
863 case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED: {
864 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
865 if (msg) {
866 std::lock_guard<std::mutex> lock(mutex_);
867 if ((connDev_ == nullptr) || (connDev_->mac != msg->mac)) {
868 SHARING_LOGE("connDev_ is nullptr or mac:%{private}s doesn't match.",
869 GetAnonyString(msg->mac).c_str());
870 return;
871 }
872 connDev_->state = ConnectionState::PLAYING;
873 OnConnectionChanged(*connDev_);
874 }
875 break;
876 }
877 case EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN: {
878 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
879 if (msg) {
880 OnP2pPeerDisconnected(msg->mac);
881 }
882 break;
883 }
884 default:
885 SHARING_LOGI("none process case.");
886 break;
887 }
888 }
889
OnConnectionChanged(ConnectionInfo &connectionInfo)890 void WfdSourceScene::OnConnectionChanged(ConnectionInfo &connectionInfo)
891 {
892 SHARING_LOGI("%{public}s.", __FUNCTION__);
893 auto ipcAdapter = ipcAdapter_.lock();
894 RETURN_IF_NULL(ipcAdapter);
895
896 auto msg = std::make_shared<WfdConnectionChangedMsg>();
897 msg->ip = connectionInfo.ip;
898 msg->mac = connectionInfo.mac;
899 msg->state = connectionInfo.state;
900 msg->surfaceId = connectionInfo.surfaceId;
901 msg->deviceName = connectionInfo.deviceName;
902 msg->primaryDeviceType = connectionInfo.primaryDeviceType;
903 msg->secondaryDeviceType = connectionInfo.secondaryDeviceType;
904
905 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
906 ipcAdapter->SendRequest(msg, reply);
907
908 if (connectionInfo.state == ConnectionState::CONNECTED) {
909 ResetCheckWfdConnectionTimer();
910 if (CreateScreenCapture() == ERR_OK) {
911 if (AppendCast(connectionInfo.mac) != 0) {
912 SHARING_LOGE("append cast error.");
913 OnInnerError(0, 0, SharingErrorCode::ERR_GENERAL_ERROR, "wfd connection timeout");
914 }
915 } else {
916 SHARING_LOGE("create screen capture error.");
917 OnInnerError(0, 0, SharingErrorCode::ERR_GENERAL_ERROR, "wfd connection timeout");
918 }
919 }
920 }
921
OnRemoteDied()922 void WfdSourceScene::OnRemoteDied()
923 {
924 SHARING_LOGI("%{public}s.", __FUNCTION__);
925 auto sharingAdapter = sharingAdapter_.lock();
926 if (sharingAdapter) {
927 sharingAdapter->ReleaseScene(GetId());
928 }
929 }
930
931 REGISTER_CLASS_REFLECTOR(WfdSourceScene);
932 } // namespace Sharing
933 } // namespace OHOS
934