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