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
OnP2pChrErrCodeReport(const int errCode)230 void WfdSourceScene::WfdP2pCallback::OnP2pChrErrCodeReport(const int errCode)
231 {
232 SHARING_LOGD("%{public}s.", __FUNCTION__);
233 }
234
WfdSourceScene()235 WfdSourceScene::WfdSourceScene()
236 {
237 SHARING_LOGD("id: %{public}u.", GetId());
238 p2pSysEvent_ = std::make_shared<SharingHiSysEvent>(BIZSceneType::P2P_START_DISCOVERY, P2P_PKG);
239 }
240
~WfdSourceScene()241 WfdSourceScene::~WfdSourceScene()
242 {
243 SHARING_LOGD("id: %{public}u.", GetId());
244 Release();
245 }
246
OnCheckWfdConnection()247 void WfdSourceScene::OnCheckWfdConnection()
248 {
249 ResetCheckWfdConnectionTimer();
250 OnInnerError(0, 0, SharingErrorCode::ERR_CONNECTION_TIMEOUT, "wfd connection timeout");
251 }
252
SetCheckWfdConnectionTimer()253 void WfdSourceScene::SetCheckWfdConnectionTimer()
254 {
255 int32_t interval = P2P_CONNECT_TIMEOUT * WFD_SEC_TO_MSEC;
256 if (timer_ != nullptr) {
257 timerId_ = timer_->Register(std::bind(&WfdSourceScene::OnCheckWfdConnection, this), interval);
258 timer_->Setup();
259 }
260 }
261
ResetCheckWfdConnectionTimer()262 void WfdSourceScene::ResetCheckWfdConnectionTimer()
263 {
264 if (timer_ != nullptr && timerId_ != 0) {
265 timer_->Unregister(timerId_);
266 timerId_ = 0;
267 }
268 }
269
Initialize()270 void WfdSourceScene::Initialize()
271 {
272 SHARING_LOGI("%{public}s.", __FUNCTION__);
273 SharingValue::Ptr values = nullptr;
274
275 auto ret = Config::GetInstance().GetConfig("khSharingWfd", "ctrlport", "defaultWfdCtrlport", values);
276 if (ret == CONFIGURE_ERROR_NONE) {
277 values->GetValue<int32_t>(ctrlPort_);
278 }
279
280 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "videoCodec", values);
281 if (ret == CONFIGURE_ERROR_NONE) {
282 int32_t videoCodec;
283 values->GetValue<int32_t>(videoCodec);
284 videoCodecId_ = static_cast<CodecId>(videoCodec);
285 videoCodecId_ = CodecId::CODEC_H264;
286 }
287
288 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "videoFormat", values);
289 if (ret == CONFIGURE_ERROR_NONE) {
290 int32_t videoFormat;
291 values->GetValue<int32_t>(videoFormat);
292 videoFormat_ = static_cast<VideoFormat>(videoFormat);
293 videoFormat_ = VideoFormat::VIDEO_1920X1080_25;
294 }
295
296 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "audioCodec", values);
297 if (ret == CONFIGURE_ERROR_NONE) {
298 int32_t audioCodec;
299 values->GetValue<int32_t>(audioCodec);
300 audioCodecId_ = static_cast<CodecId>(audioCodec);
301 audioCodecId_ = CodecId::CODEC_AAC;
302 }
303
304 ret = Config::GetInstance().GetConfig("khSharingWfd", "mediaFormat", "audioFormat", values);
305 if (ret == CONFIGURE_ERROR_NONE) {
306 int32_t audioFormat;
307 values->GetValue<int32_t>(audioFormat);
308 audioFormat_ = static_cast<AudioFormat>(audioFormat);
309 audioFormat_ = AudioFormat::AUDIO_48000_16_2;
310 }
311
312 p2pInstance_ = Wifi::WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
313 RETURN_IF_NULL(p2pInstance_);
314 if (shared_from_this() == nullptr) {
315 SHARING_LOGE("trace*********************WfdSourceScene NULL.");
316 }
317
318 sptr<WfdP2pCallback> wfdP2pCallback(new WfdP2pCallback(shared_from_this()));
319
320 std::vector<std::string> event = {EVENT_P2P_PEER_DEVICE_CHANGE, EVENT_P2P_DEVICE_STATE_CHANGE,
321 EVENT_P2P_CONN_STATE_CHANGE, EVENT_P2P_STATE_CHANGE,
322 EVENT_P2P_SERVICES_CHANGE, EVENT_P2P_DISCOVERY_CHANGE};
323 p2pInstance_->RegisterCallBack(wfdP2pCallback, event);
324 }
325
Release()326 void WfdSourceScene::Release()
327 {
328 SHARING_LOGI("%{public}s.", __FUNCTION__);
329 if (timer_ != nullptr) {
330 timer_->Shutdown();
331 timer_.reset();
332 }
333 auto sharingAdapter = sharingAdapter_.lock();
334 if (sharingAdapter != nullptr) {
335 std::lock_guard<std::mutex> lock(mutex_);
336 if ((connDev_ != nullptr) && (connDev_->contextId != INVALID_ID) && (connDev_->agentId != INVALID_ID)) {
337 auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
338 sessionMsg->type = EVENT_SESSION_TEARDOWN;
339 sessionMsg->toMgr = MODULE_CONTEXT;
340 sessionMsg->dstId = connDev_->contextId;
341 sessionMsg->agentId = connDev_->agentId;
342
343 SharingEvent event;
344 event.eventMsg = std::move(sessionMsg);
345 sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
346 sharingAdapter->DestroyAgent(connDev_->contextId, connDev_->agentId);
347 if ((contextId_ != INVALID_ID) && (agentId_ != INVALID_ID)) {
348 sharingAdapter->DestroyAgent(contextId_, agentId_);
349 }
350 }
351 }
352
353 if (p2pInstance_) {
354 p2pInstance_->RemoveGroup();
355 }
356 p2pInstance_.reset();
357 }
358
OnDomainMsg(std::shared_ptr<BaseDomainMsg> & msg)359 void WfdSourceScene::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
360 {
361 SHARING_LOGI("%{public}s.", __FUNCTION__);
362 }
363
OnRequest(std::shared_ptr<BaseMsg> msg,std::shared_ptr<BaseMsg> & reply)364 void WfdSourceScene::OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
365 {
366 RETURN_IF_NULL(msg);
367 switch (msg->GetMsgId()) {
368 case WfdSourceStartDiscoveryReq::MSG_ID: {
369 auto rsp = std::make_shared<WfdCommonRsp>();
370
371 rsp->ret = HandleStartDiscovery(msg, rsp);
372 reply = std::static_pointer_cast<BaseMsg>(rsp);
373 break;
374 }
375 case WfdSourceStopDiscoveryReq::MSG_ID: {
376 auto rsp = std::make_shared<WfdCommonRsp>();
377
378 rsp->ret = HandleStopDiscovery(msg, rsp);
379 reply = std::static_pointer_cast<BaseMsg>(rsp);
380 break;
381 }
382 case WfdSourceAddDeviceReq::MSG_ID: {
383 ResetCheckWfdConnectionTimer();
384 auto rsp = std::make_shared<WfdCommonRsp>();
385 rsp->ret = WfdSourceScene::HandleAddDevice(msg, rsp);
386 SetCheckWfdConnectionTimer();
387 reply = std::static_pointer_cast<BaseMsg>(rsp);
388 break;
389 }
390 case WfdSourceRemoveDeviceReq::MSG_ID: {
391 auto rsp = std::make_shared<WfdCommonRsp>();
392
393 rsp->ret = HandleRemoveDevice(msg, rsp);
394 reply = std::static_pointer_cast<BaseMsg>(rsp);
395 break;
396 }
397 case DestroyScreenCaptureReq::MSG_ID: {
398 auto data = std::static_pointer_cast<DestroyScreenCaptureReq>(msg);
399 auto rsp = std::make_shared<WfdCommonRsp>();
400 rsp->ret = HandleDestroyScreenCapture(data);
401 reply = std::static_pointer_cast<BaseMsg>(rsp);
402 break;
403 }
404 default:
405 SHARING_LOGW("unknown msg request.");
406 break;
407 }
408 }
409
HandleStartDiscovery(std::shared_ptr<BaseMsg> & baseMsg,std::shared_ptr<WfdCommonRsp> & reply)410 int32_t WfdSourceScene::HandleStartDiscovery(std::shared_ptr<BaseMsg> &baseMsg,
411 std::shared_ptr<WfdCommonRsp> &reply)
412 {
413 SHARING_LOGI("%{public}s.", __FUNCTION__);
414 (void)baseMsg;
415 (void)reply;
416 int32_t ret = 0;
417 if (p2pInstance_ == nullptr) {
418 SHARING_LOGW("p2pInstance is nullptr.");
419 return -1;
420 }
421 if (!isSourceRunning_) {
422 p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_START_DISCOVERY);
423 int32_t status = 0;
424 p2pInstance_->GetP2pEnableStatus(status);
425 switch (static_cast<Wifi::P2pState>(status)) {
426 case Wifi::P2pState::P2P_STATE_NONE: // fall-through
427 case Wifi::P2pState::P2P_STATE_IDLE: // fall-through
428 case Wifi::P2pState::P2P_STATE_STARTING: // fall-through
429 case Wifi::P2pState::P2P_STATE_CLOSING: {
430 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleStart current p2p state: CLOSING");
431 ret = -1;
432 break;
433 }
434 case Wifi::P2pState::P2P_STATE_STARTED: {
435 isSourceRunning_ = true;
436 WfdP2pStart();
437 break;
438 }
439 case Wifi::P2pState::P2P_STATE_CLOSED: {
440 isSourceRunning_ = true;
441 p2pInstance_->EnableP2p();
442 break;
443 }
444 default: {
445 SHARING_LOGI("none process case.");
446 break;
447 }
448 }
449 }
450 if (ret == 0) {
451 ret = p2pInstance_->DiscoverDevices();
452 isSourceDiscovering = true;
453 } else {
454 p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_START_DISCOVERY, BlzErrorCode::ERROR_FAIL);
455 }
456 return ret;
457 }
458
HandleStopDiscovery(std::shared_ptr<BaseMsg> & baseMsg,std::shared_ptr<WfdCommonRsp> & reply)459 int32_t WfdSourceScene::HandleStopDiscovery(std::shared_ptr<BaseMsg> &baseMsg,
460 std::shared_ptr<WfdCommonRsp> &reply)
461 {
462 SHARING_LOGI("%{public}s.", __FUNCTION__);
463 (void)baseMsg;
464 (void)reply;
465 if (!isSourceRunning_) {
466 SHARING_LOGW("p2p source is not running.");
467 return -1;
468 }
469
470 if (p2pInstance_ == nullptr) {
471 SHARING_LOGW("p2pInstance is nullptr.");
472 return -1;
473 }
474
475 int32_t ret = p2pInstance_->StopDiscoverDevices();
476 isSourceDiscovering = false;
477 return ret;
478 }
479
HandleAddDevice(std::shared_ptr<BaseMsg> & baseMsg,std::shared_ptr<WfdCommonRsp> & reply)480 int32_t WfdSourceScene::HandleAddDevice(std::shared_ptr<BaseMsg> &baseMsg,
481 std::shared_ptr<WfdCommonRsp> &reply)
482 {
483 SHARING_LOGI("%{public}s.", __FUNCTION__);
484 (void)reply;
485 if (!isSourceRunning_ || p2pInstance_ == nullptr) {
486 SHARING_LOGW("p2p source is not running.");
487 return -1;
488 }
489
490 std::shared_ptr<WfdSourceAddDeviceReq> msg = std::static_pointer_cast<WfdSourceAddDeviceReq>(baseMsg);
491 auto displayIds = OHOS::Rosen::DisplayManager::GetInstance().GetAllDisplayIds();
492 bool findDisplayId = false;
493 for (auto displayId : displayIds) {
494 SHARING_LOGD("displayId = %{public}" PRIu64, displayId);
495 if (msg->screenId == displayId) {
496 findDisplayId = true;
497 break;
498 }
499 }
500 if (!findDisplayId) {
501 SHARING_LOGE("can't find screenId %{public}" PRIu64, msg->screenId);
502 return ERR_BAD_PARAMETER;
503 }
504 p2pSysEvent_->ReportEnd(__func__, BIZSceneStage::P2P_DEVICE_FOUND);
505 p2pSysEvent_->ChangeScene(BIZSceneType::P2P_CONNECT_DEVICE);
506 p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_CONNECT_DEVICE);
507 Wifi::WifiP2pConfig config;
508 config.SetDeviceAddress(msg->deviceId);
509 config.SetDeviceAddressType(OHOS::Wifi::RANDOM_DEVICE_ADDRESS);
510 config.SetGroupOwnerIntent(GROUP_OWNER_INTENT_MAX - 1);
511
512 screenId_ = msg->screenId;
513 int32_t ret = p2pInstance_->P2pConnect(config);
514 SHARING_LOGE("connect device: %{public}s, ret = %{public}d", GetAnonyString(msg->deviceId).c_str(), ret);
515 return ret;
516 }
517
HandleRemoveDevice(std::shared_ptr<BaseMsg> & baseMsg,std::shared_ptr<WfdCommonRsp> & reply)518 int32_t WfdSourceScene::HandleRemoveDevice(std::shared_ptr<BaseMsg> &baseMsg,
519 std::shared_ptr<WfdCommonRsp> &reply)
520 {
521 SHARING_LOGI("%{public}s.", __FUNCTION__);
522 (void)reply;
523 auto sharingAdapter = sharingAdapter_.lock();
524 RETURN_INVALID_IF_NULL(sharingAdapter);
525
526 std::shared_ptr<WfdSourceRemoveDeviceReq> msg = std::static_pointer_cast<WfdSourceRemoveDeviceReq>(baseMsg);
527
528 std::lock_guard<std::mutex> lock(mutex_);
529 if ((connDev_ == nullptr) || (connDev_->mac != msg->deviceId) || connDev_->state != ConnectionState::CONNECTED) {
530 SHARING_LOGE("can not find dev, deviceId: %{public}s.", GetAnonyString(msg->deviceId).c_str());
531 return -1;
532 }
533 auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
534 sessionMsg->type = EVENT_SESSION_TEARDOWN;
535 sessionMsg->toMgr = MODULE_CONTEXT;
536 sessionMsg->dstId = connDev_->contextId;
537 sessionMsg->agentId = connDev_->agentId;
538
539 SharingEvent event;
540 event.eventMsg = std::move(sessionMsg);
541 sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
542
543 connDev_.reset();
544 int ret = sharingAdapter->DestroyAgent(contextId_, agentId_);
545 if (p2pInstance_) {
546 p2pSysEvent_->ChangeScene(BIZSceneType::P2P_DISCONNECT_DEVICE);
547 p2pSysEvent_->ReportStart(__func__, BIZSceneStage::P2P_DISCONNECT_DEVICE);
548 p2pInstance_->RemoveGroup();
549 }
550 return ret;
551 }
552
CreateScreenCapture()553 int32_t WfdSourceScene::CreateScreenCapture()
554 {
555 SHARING_LOGI("%{public}s.", __FUNCTION__);
556 auto sharingAdapter = sharingAdapter_.lock();
557 if (sharingAdapter != nullptr) {
558 std::unique_lock<std::mutex> lock(mutex_);
559
560 sharingAdapter->CreateAgent(contextId_, agentId_, AgentType::SINK_AGENT, "ScreenCaptureSession");
561 if (contextId_ == INVALID_ID || agentId_ == INVALID_ID) {
562 lock.unlock();
563 SHARING_LOGE("Create ScreenCapture sink agent failed");
564 return ERR_AGENT_CREATE;
565 } else {
566 SHARING_LOGI("Create ScreenCapture sink agent, contextId: %{public}u, agentId: %{public}u", contextId_,
567 agentId_);
568 }
569
570 auto startSessionMsg = std::make_shared<ScreenCaptureSessionEventMsg>();
571 startSessionMsg->mediaType = MEDIA_TYPE_AV;
572 startSessionMsg->type = EVENT_SESSION_INIT;
573 startSessionMsg->toMgr = MODULE_CONTEXT;
574 startSessionMsg->dstId = contextId_;
575 startSessionMsg->agentId = agentId_;
576 startSessionMsg->screenId = screenId_;
577 videoFormat_ = VideoFormat::VIDEO_1920X1080_25;
578
579 startSessionMsg->videoFormat = videoFormat_;
580 startSessionMsg->audioFormat = audioFormat_;
581
582 SharingEvent event;
583 event.eventMsg = std::move(startSessionMsg);
584
585 sharingAdapter->ForwardEvent(contextId_, agentId_, event, true);
586 sharingAdapter->Start(contextId_, agentId_);
587 }
588
589 return ERR_OK;
590 }
591
HandleDestroyScreenCapture(std::shared_ptr<DestroyScreenCaptureReq> & msg)592 int32_t WfdSourceScene::HandleDestroyScreenCapture(std::shared_ptr<DestroyScreenCaptureReq> &msg)
593 {
594 SHARING_LOGI("%{public}s.", __FUNCTION__);
595 (void)msg;
596 auto sharingAdapter = sharingAdapter_.lock();
597 if (sharingAdapter != nullptr) {
598 sharingAdapter->DestroyAgent(contextId_, agentId_);
599 }
600 return ERR_OK;
601 }
602
AppendCast(const std::string & deviceId)603 int32_t WfdSourceScene::AppendCast(const std::string &deviceId)
604 {
605 SHARING_LOGI("%{public}s.", __FUNCTION__);
606 auto sharingAdapter = sharingAdapter_.lock();
607 RETURN_INVALID_IF_NULL(sharingAdapter);
608
609 std::unique_lock<std::mutex> lock(mutex_);
610 if ((connDev_ == nullptr) || (connDev_->mac != deviceId)) {
611 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(deviceId).c_str());
612 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "AppendCast can't find the dev");
613 return -1;
614 }
615 auto port = SocketUtils::GetAvailableUdpPortPair();
616 if (port == 0) {
617 SHARING_LOGE("get udp port failed.");
618 return -1;
619 }
620
621 uint32_t contextId = contextId_;
622 uint32_t agentId = agentId_;
623 sharingAdapter->CreateAgent(contextId, agentId, AgentType::SRC_AGENT, "WfdSourceSession");
624 if (contextId == INVALID_ID || agentId == INVALID_ID) {
625 lock.unlock();
626 SHARING_LOGE("create source agent failed.");
627 return -1;
628 }
629 SHARING_LOGI("create source agent, contextId: %{public}u, agentId: %{public}u", contextId, agentId);
630 connDev_->contextId = contextId;
631 connDev_->agentId = agentId;
632
633 if (connDev_->isRunning == true) {
634 return 0;
635 }
636 connDev_->isRunning = true;
637
638 auto startSessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
639 startSessionMsg->type = EVENT_SESSION_INIT;
640 startSessionMsg->sinkAgentId = agentId_;
641 startSessionMsg->toMgr = MODULE_CONTEXT;
642 startSessionMsg->dstId = contextId;
643 startSessionMsg->agentId = agentId;
644 startSessionMsg->ip = connDev_->ip;
645 startSessionMsg->mac = connDev_->mac;
646 startSessionMsg->remotePort = connDev_->ctrlPort;
647 startSessionMsg->videoFormat = connDev_->videoFormatId;
648 startSessionMsg->audioFormat = connDev_->audioFormatId;
649 startSessionMsg->localPort = port;
650
651 SharingEvent event;
652 event.eventMsg = std::move(startSessionMsg);
653 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
654 sharingAdapter->Start(contextId, agentId);
655
656 return 0;
657 }
658
WfdP2pStart()659 void WfdSourceScene::WfdP2pStart()
660 {
661 SHARING_LOGI("%{public}s.", __FUNCTION__);
662 if (p2pInstance_) {
663 p2pInstance_->RemoveGroup();
664
665 Wifi::WifiP2pWfdInfo wfdInfo;
666 wfdInfo.SetWfdEnabled(true);
667 wfdInfo.SetDeviceInfo(0x10);
668 wfdInfo.SetCtrlPort(ctrlPort_);
669 wfdInfo.SetMaxThroughput(0x00c8);
670
671 p2pInstance_->SetP2pWfdInfo(wfdInfo);
672
673 SHARING_LOGD("WfdSourceScene DiscoverDevices.");
674 p2pInstance_->DiscoverDevices();
675 isSourceDiscovering = true;
676 }
677 }
678
WfdP2pStop()679 void WfdSourceScene::WfdP2pStop()
680 {
681 SHARING_LOGI("%{public}s.", __FUNCTION__);
682 auto sharingAdapter = sharingAdapter_.lock();
683 if (sharingAdapter != nullptr) {
684 std::lock_guard<std::mutex> lock(mutex_);
685 if ((connDev_ != nullptr) && (connDev_->contextId != INVALID_ID) && (connDev_->agentId != INVALID_ID)) {
686 auto sessionMsg = std::make_shared<WfdSourceSessionEventMsg>();
687 sessionMsg->type = EVENT_SESSION_TEARDOWN;
688 sessionMsg->toMgr = MODULE_CONTEXT;
689 sessionMsg->dstId = connDev_->contextId;
690 sessionMsg->agentId = connDev_->agentId;
691 SharingEvent event;
692 event.eventMsg = std::move(sessionMsg);
693 sharingAdapter->ForwardEvent(connDev_->contextId, connDev_->agentId, event, true);
694 }
695
696 if ((contextId_ != INVALID_ID) && (agentId_ != INVALID_ID)) {
697 sharingAdapter->DestroyAgent(contextId_, agentId_);
698 }
699 }
700
701 if (p2pInstance_) {
702 p2pInstance_->RemoveGroup();
703 }
704 }
705
OnDeviceFound(const std::vector<WfdCastDeviceInfo> & deviceInfos)706 void WfdSourceScene::OnDeviceFound(const std::vector<WfdCastDeviceInfo> &deviceInfos)
707 {
708 SHARING_LOGI("%{public}s.", __FUNCTION__);
709 auto ipcAdapter = ipcAdapter_.lock();
710 RETURN_IF_NULL(ipcAdapter);
711 auto msg = std::make_shared<WfdSourceDeviceFoundMsg>();
712 msg->deviceInfos = deviceInfos;
713 if (p2pSysEvent_->GetScene() == static_cast<int>(BIZSceneType::P2P_START_DISCOVERY)) {
714 for (auto &deviceInfo : deviceInfos) {
715 p2pSysEvent_->Report(__func__, BIZSceneStage::P2P_DEVICE_FOUND, StageResType::STAGE_RES_SUCCESS,
716 GetAnonyString(deviceInfo.deviceId));
717 }
718 }
719
720 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
721 ipcAdapter->SendRequest(msg, reply);
722 }
723
OnP2pPeerConnected(ConnectionInfo & connectionInfo)724 void WfdSourceScene::OnP2pPeerConnected(ConnectionInfo &connectionInfo)
725 {
726 SHARING_LOGE("OnP2pPeerConnected, deviceName: %{public}s, mac: %{public}s, ip: %{public}s, port: %{public}d.",
727 GetAnonyString(connectionInfo.deviceName).c_str(), GetAnonyString(connectionInfo.mac).c_str(),
728 GetAnonyString(connectionInfo.ip).c_str(), connectionInfo.ctrlPort);
729
730 if (!isSourceRunning_) {
731 SHARING_LOGW("source service is not running.");
732 return;
733 }
734
735 auto sharingAdapter = sharingAdapter_.lock();
736 if (sharingAdapter != nullptr) {
737 std::lock_guard<std::mutex> lock(mutex_);
738 if ((connDev_ != nullptr) && (connDev_->mac == connectionInfo.mac)) {
739 SHARING_LOGW("devcie is alerady connected, mac: %s.", GetAnonyString(connectionInfo.mac).c_str());
740 return;
741 }
742 connectionInfo.videoCodecId = videoCodecId_;
743 connectionInfo.videoFormatId = videoFormat_;
744 connectionInfo.audioCodecId = audioCodecId_;
745 connectionInfo.audioFormatId = audioFormat_;
746
747 connDev_ = std::make_unique<ConnectionInfo>(connectionInfo);
748 SHARING_LOGI("connected, devMac: %s, devIp: %s.", GetAnonyString(connectionInfo.mac).c_str(),
749 GetAnonyString(connectionInfo.ip).c_str());
750 }
751
752 OnConnectionChanged(connectionInfo);
753 }
754
OnP2pPeerDisconnected(ConnectionInfo & connectionInfo)755 void WfdSourceScene::OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)
756 {
757 SHARING_LOGI("%{public}s.", __FUNCTION__);
758 OnP2pPeerDisconnected(connectionInfo.mac);
759 }
760
OnP2pPeerDisconnected(const std::string & mac)761 void WfdSourceScene::OnP2pPeerDisconnected(const std::string &mac)
762 {
763 SHARING_LOGI("%{public}s.", __FUNCTION__);
764 {
765 std::lock_guard<std::mutex> lock(mutex_);
766 if ((connDev_ == nullptr) || (connDev_->mac != mac)) {
767 SHARING_LOGW("can not find dev, mac: %s.", GetAnonyString(mac).c_str());
768 return;
769 }
770 connDev_->state = ConnectionState::DISCONNECTED;
771 OnConnectionChanged(*connDev_);
772 connDev_.reset();
773 }
774
775 if ((contextId_ == INVALID_ID) || (agentId_ == INVALID_ID)) {
776 return;
777 }
778
779 auto sharingAdapter = sharingAdapter_.lock();
780 if (sharingAdapter != nullptr) {
781 sharingAdapter->DestroyAgent(contextId_, agentId_);
782 }
783
784 if (p2pInstance_) {
785 p2pInstance_->RemoveGroup();
786 }
787 }
788
ErrorCodeFiltering(int32_t & code)789 void WfdSourceScene::ErrorCodeFiltering(int32_t &code)
790 {
791 SHARING_LOGD("the error code is %{public}d.", code);
792 switch (ABSTRACT_ERR_BASE(code)) {
793 case SharingErrorCode::ERR_CONTEXT_AGENT_BASE: // fall-through
794 case SharingErrorCode::ERR_SESSION_BASE:
795 code = SharingErrorCode::ERR_GENERAL_ERROR;
796 SHARING_LOGD("the error change to %{public}d.", code);
797 break;
798 case SharingErrorCode::ERR_PROSUMER_BASE: {
799 switch (code) {
800 case ERR_PROSUMER_START:
801 code = SharingErrorCode::ERR_CONNECTION_FAILURE;
802 break;
803 case ERR_PROSUMER_TIMEOUT:
804 code = SharingErrorCode::ERR_CONNECTION_TIMEOUT;
805 break;
806 case ERR_PROSUMER_DESTROY:
807 code = SharingErrorCode::ERR_STATE_EXCEPTION;
808 break;
809 default:
810 code = SharingErrorCode::ERR_GENERAL_ERROR;
811 break;
812 }
813 break;
814 }
815 default:
816 SHARING_LOGI("none process case.");
817 break;
818 }
819 }
820
OnInnerError(uint32_t contextId,uint32_t agentId,SharingErrorCode errorCode,std::string message)821 void WfdSourceScene::OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)
822 {
823 SHARING_LOGI("%{public}s.", __FUNCTION__);
824 auto ipcAdapter = ipcAdapter_.lock();
825 RETURN_IF_NULL(ipcAdapter);
826
827 auto msg = std::make_shared<WfdErrorMsg>();
828 msg->contextId = contextId;
829 msg->agentId = agentId;
830 msg->errorCode = errorCode;
831
832 if (errorCode == SharingErrorCode::ERR_PROSUMER_TIMEOUT) {
833 msg->message =
834 "contextId: " + std::to_string(contextId) + ", agentId: " + std::to_string(agentId) + ", producer timeout";
835 } else {
836 msg->message = std::move(message);
837 }
838
839 ErrorCodeFiltering(msg->errorCode);
840 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
841
842 SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
843 ipcAdapter->SendRequest(msg, reply);
844 }
845
OnInnerDestroy(uint32_t contextId,uint32_t agentId,AgentType agentType)846 void WfdSourceScene::OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)
847 {
848 SHARING_LOGI("HandleInnerDestroy, contextId: %{public}u, agentId: %{public}u, agentType: %{public}s.", contextId,
849 agentId, std::string(magic_enum::enum_name(agentType)).c_str());
850 std::lock_guard<std::mutex> lock(mutex_);
851 if (connDev_ == nullptr) {
852 SHARING_LOGE("connDev_ is nullptr.");
853 return;
854 }
855
856 if ((contextId == connDev_->contextId) && ((agentId == connDev_->agentId) || agentId == agentId_)) {
857 connDev_->state = ConnectionState::DISCONNECTED;
858 OnConnectionChanged(*connDev_);
859 }
860 }
861
OnInnerEvent(SharingEvent & event)862 void WfdSourceScene::OnInnerEvent(SharingEvent &event)
863 {
864 RETURN_IF_NULL(event.eventMsg);
865
866 SHARING_LOGI("OnInnerEvent Type: %{public}s.", std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
867 switch (event.eventMsg->type) {
868 case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED: {
869 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
870 if (msg) {
871 std::lock_guard<std::mutex> lock(mutex_);
872 if ((connDev_ == nullptr) || (connDev_->mac != msg->mac)) {
873 SHARING_LOGE("connDev_ is nullptr or mac:%{private}s doesn't match.",
874 GetAnonyString(msg->mac).c_str());
875 return;
876 }
877 connDev_->state = ConnectionState::PLAYING;
878 OnConnectionChanged(*connDev_);
879 }
880 break;
881 }
882 case EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN: {
883 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
884 if (msg) {
885 OnP2pPeerDisconnected(msg->mac);
886 }
887 break;
888 }
889 default:
890 SHARING_LOGI("none process case.");
891 break;
892 }
893 }
894
OnConnectionChanged(ConnectionInfo & connectionInfo)895 void WfdSourceScene::OnConnectionChanged(ConnectionInfo &connectionInfo)
896 {
897 SHARING_LOGI("%{public}s.", __FUNCTION__);
898 auto ipcAdapter = ipcAdapter_.lock();
899 RETURN_IF_NULL(ipcAdapter);
900
901 auto msg = std::make_shared<WfdConnectionChangedMsg>();
902 msg->ip = connectionInfo.ip;
903 msg->mac = connectionInfo.mac;
904 msg->state = connectionInfo.state;
905 msg->surfaceId = connectionInfo.surfaceId;
906 msg->deviceName = connectionInfo.deviceName;
907 msg->primaryDeviceType = connectionInfo.primaryDeviceType;
908 msg->secondaryDeviceType = connectionInfo.secondaryDeviceType;
909
910 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
911 ipcAdapter->SendRequest(msg, reply);
912
913 if (connectionInfo.state == ConnectionState::CONNECTED) {
914 ResetCheckWfdConnectionTimer();
915 if (CreateScreenCapture() == ERR_OK) {
916 if (AppendCast(connectionInfo.mac) != 0) {
917 SHARING_LOGE("append cast error.");
918 OnInnerError(0, 0, SharingErrorCode::ERR_GENERAL_ERROR, "wfd connection timeout");
919 }
920 } else {
921 SHARING_LOGE("create screen capture error.");
922 OnInnerError(0, 0, SharingErrorCode::ERR_GENERAL_ERROR, "wfd connection timeout");
923 }
924 }
925 }
926
OnRemoteDied()927 void WfdSourceScene::OnRemoteDied()
928 {
929 SHARING_LOGI("%{public}s.", __FUNCTION__);
930 auto sharingAdapter = sharingAdapter_.lock();
931 if (sharingAdapter) {
932 sharingAdapter->ReleaseScene(GetId());
933 }
934 }
935
936 REGISTER_CLASS_REFLECTOR(WfdSourceScene);
937 } // namespace Sharing
938 } // namespace OHOS
939