• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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