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