• 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 
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