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_sink_scene.h"
17 #include <unistd.h>
18 #include "common/common_macro.h"
19 #include "common/reflect_registration.h"
20 #include "common/sharing_log.h"
21 #include "configuration/include/config.h"
22 #include "const_def.h"
23 #include "extend/magic_enum/magic_enum.hpp"
24 #include "network/socket/socket_utils.h"
25 #include "utils/utils.h"
26 #include "wfd_session_def.h"
27
28 namespace OHOS {
29 namespace Sharing {
30
OnP2pStateChanged(int32_t state)31 void WfdSinkScene::WfdP2pCallback::OnP2pStateChanged(int32_t state)
32 {
33 SHARING_LOGD("state: %{public}d.", state);
34 auto parent = parent_.lock();
35 if (parent) {
36 switch (state) {
37 case (int32_t)Wifi::P2pState::P2P_STATE_NONE:
38 break;
39 case (int32_t)Wifi::P2pState::P2P_STATE_IDLE:
40 break;
41 case (int32_t)Wifi::P2pState::P2P_STATE_STARTING:
42 break;
43 case (int32_t)Wifi::P2pState::P2P_STATE_STARTED:
44 if (parent->isSinkRunning_) {
45 parent->WfdP2pStart();
46 }
47 break;
48 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSING:
49 break;
50 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSED:
51 if (parent->isSinkRunning_) {
52 parent->isSinkRunning_ = false;
53 parent->WfdP2pStop();
54 parent->OnInnerError("", SharingErrorCode::ERR_NETWORK_ERROR, "NETWORK ERROR, P2P MODULE STOPPED");
55 }
56 break;
57 default:
58 SHARING_LOGI("none process case.");
59 break;
60 }
61 }
62 }
63
OnP2pPersistentGroupsChanged(void)64 void WfdSinkScene::WfdP2pCallback::OnP2pPersistentGroupsChanged(void)
65 {
66 SHARING_LOGD("trace.");
67 }
68
OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice & device)69 void WfdSinkScene::WfdP2pCallback::OnP2pThisDeviceChanged(const Wifi::WifiP2pDevice &device)
70 {
71 SHARING_LOGD("trace.");
72 }
73
OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> & device)74 void WfdSinkScene::WfdP2pCallback::OnP2pPeersChanged(const std::vector<Wifi::WifiP2pDevice> &device)
75 {
76 SHARING_LOGD("trace.");
77 auto parent = parent_.lock();
78 if (parent) {
79 SHARING_LOGI("device size: %{public}zu.", device.size());
80 for (auto itDev : device) {
81 auto status = itDev.GetP2pDeviceStatus();
82 SHARING_LOGI("device mac: %{public}s, status: %{public}d.",
83 GetAnonyString(itDev.GetDeviceAddress()).c_str(), status);
84 switch (status) {
85 case Wifi::P2pDeviceStatus::PDS_AVAILABLE: {
86 ConnectionInfo connectionInfo;
87 connectionInfo.mac = itDev.GetDeviceAddress();
88 connectionInfo.deviceName = itDev.GetDeviceName();
89 connectionInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
90 connectionInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
91 connectionInfo.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
92 connectionInfo.state = ConnectionState::DISCONNECTED;
93
94 parent->OnP2pPeerDisconnected(connectionInfo);
95 break;
96 }
97 default:
98 SHARING_LOGI("none process case.");
99 break;
100 }
101 }
102 }
103 }
104
OnP2pPrivatePeersChanged(const std::string & priWfdInfo)105 void WfdSinkScene::WfdP2pCallback::OnP2pPrivatePeersChanged(const std::string &priWfdInfo)
106 {
107 SHARING_LOGD("trace.");
108 }
109
OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> & srvInfo)110 void WfdSinkScene::WfdP2pCallback::OnP2pServicesChanged(const std::vector<Wifi::WifiP2pServiceInfo> &srvInfo)
111 {
112 SHARING_LOGD("trace.");
113 }
114
OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo & info)115 void WfdSinkScene::WfdP2pCallback::OnP2pConnectionChanged(const Wifi::WifiP2pLinkedInfo &info)
116 {
117 SHARING_LOGD("trace.");
118 }
119
OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo & info)120 void WfdSinkScene::WfdP2pCallback::OnP2pGcJoinGroup(const OHOS::Wifi::GcInfo &info)
121 {
122 SHARING_LOGD("trace.");
123 auto parent = parent_.lock();
124 if (parent && parent->p2pInstance_) {
125 std::vector<Wifi::WifiP2pDevice> devices;
126 if (Wifi::ErrCode::WIFI_OPT_SUCCESS != parent->p2pInstance_->QueryP2pDevices(devices)) {
127 SHARING_LOGE("QueryP2pDevices failed");
128 return;
129 }
130 SHARING_LOGI("QueryP2pDevices ip:%{private}s addr: %{private}s host: %{private}s.",
131 GetAnonyString(info.ip).c_str(), GetAnonyString(info.mac).c_str(),
132 GetAnonyString(info.host).c_str());
133 if (info.ip == "0.0.0.0" || info.ip == "") {
134 SHARING_LOGE("device: %{private}s leased ip is: 0.0.0.0.", GetAnonyString(info.mac).c_str());
135 parent->OnInnerError(info.mac.c_str(), ERR_P2P_DHCP_INVALID_IP, "ip is: 0.0.0.0.");
136 return;
137 }
138
139 for (auto itDev : devices) {
140 ConnectionInfo connectionInfo;
141 connectionInfo.ip = info.ip;
142 connectionInfo.mac = itDev.GetDeviceAddress();
143 connectionInfo.primaryDeviceType = itDev.GetPrimaryDeviceType();
144 connectionInfo.secondaryDeviceType = itDev.GetSecondaryDeviceType();
145 connectionInfo.ctrlPort = itDev.GetWfdInfo().GetCtrlPort();
146 connectionInfo.state = ConnectionState::CONNECTED;
147 SHARING_LOGD("device connected, mac: %{private}s, ip: %{private}s, port: %{private}d",
148 connectionInfo.mac.c_str(), connectionInfo.ip.c_str(), connectionInfo.ctrlPort);
149 parent->OnP2pPeerConnected(connectionInfo);
150 return;
151 }
152 }
153 }
154
OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo & info)155 void WfdSinkScene::WfdP2pCallback::OnP2pGcLeaveGroup(const OHOS::Wifi::GcInfo &info)
156 {
157 return;
158 }
159
OnP2pDiscoveryChanged(bool isChange)160 void WfdSinkScene::WfdP2pCallback::OnP2pDiscoveryChanged(bool isChange)
161 {
162 SHARING_LOGD("isChange: %{public}d.", isChange);
163 }
164
OnP2pActionResult(Wifi::P2pActionCallback action,Wifi::ErrCode code)165 void WfdSinkScene::WfdP2pCallback::OnP2pActionResult(Wifi::P2pActionCallback action, Wifi::ErrCode code)
166 {
167 SHARING_LOGD("trace.");
168 }
169
OnConfigChanged(Wifi::CfgType type,char * data,int32_t dataLen)170 void WfdSinkScene::WfdP2pCallback::OnConfigChanged(Wifi::CfgType type, char *data, int32_t dataLen)
171 {
172 SHARING_LOGD("trace.");
173 }
174
WfdSinkScene()175 WfdSinkScene::WfdSinkScene()
176 {
177 SHARING_LOGI("id: %{public}u.", GetId());
178 }
179
~WfdSinkScene()180 WfdSinkScene::~WfdSinkScene()
181 {
182 SHARING_LOGI("id: %{public}u.", GetId());
183 Release();
184 }
185
Initialize()186 void WfdSinkScene::Initialize()
187 {
188 SHARING_LOGD("trace.");
189 SharingValue::Ptr values = nullptr;
190
191 auto ret = Config::GetInstance().GetConfig("sharingWfd", "ctrlport", "defaultWfdCtrlport", values);
192 if (ret == CONFIGURE_ERROR_NONE) {
193 values->GetValue<int32_t>(ctrlPort_);
194 }
195
196 ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "accessDevMaximum", values);
197 if (ret == CONFIGURE_ERROR_NONE) {
198 values->GetValue<int32_t>(accessDevMaximum_);
199 }
200
201 ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "surfaceMaximum", values);
202 if (ret == CONFIGURE_ERROR_NONE) {
203 values->GetValue<int32_t>(surfaceMaximum_);
204 }
205
206 ret = Config::GetInstance().GetConfig("sharingWfd", "abilityLimit", "foregroundMaximum", values);
207 if (ret == CONFIGURE_ERROR_NONE) {
208 values->GetValue<int32_t>(foregroundMaximum_);
209 }
210
211 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "videoCodec", values);
212 if (ret == CONFIGURE_ERROR_NONE) {
213 int32_t videoCodec;
214 values->GetValue<int32_t>(videoCodec);
215 videoCodecId_ = static_cast<CodecId>(videoCodec);
216 }
217
218 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "videoFormat", values);
219 if (ret == CONFIGURE_ERROR_NONE) {
220 int32_t videoFormat;
221 values->GetValue<int32_t>(videoFormat);
222 videoFormatId_ = static_cast<VideoFormat>(videoFormat);
223 }
224
225 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "audioCodec", values);
226 if (ret == CONFIGURE_ERROR_NONE) {
227 int32_t audioCodec;
228 values->GetValue<int32_t>(audioCodec);
229 audioCodecId_ = static_cast<CodecId>(audioCodec);
230 }
231
232 ret = Config::GetInstance().GetConfig("sharingWfd", "mediaFormat", "audioFormat", values);
233 if (ret == CONFIGURE_ERROR_NONE) {
234 int32_t audioFormat;
235 values->GetValue<int32_t>(audioFormat);
236 audioFormatId_ = static_cast<AudioFormat>(audioFormat);
237 }
238
239 p2pInstance_ = Wifi::WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
240 RETURN_IF_NULL(p2pInstance_);
241 sptr<WfdP2pCallback> wfdP2pCallback(new WfdP2pCallback(shared_from_this()));
242 std::vector<std::string> event = {EVENT_P2P_PEER_DEVICE_CHANGE, EVENT_P2P_CONN_STATE_CHANGE,
243 EVENT_P2P_GC_JOIN_GROUP, EVENT_P2P_GC_LEAVE_GROUP};
244 p2pInstance_->RegisterCallBack(wfdP2pCallback, event);
245 }
246
Release()247 void WfdSinkScene::Release()
248 {
249 SHARING_LOGD("trace.");
250 std::unique_lock<std::mutex> lock(mutex_);
251 auto sharingAdapter = sharingAdapter_.lock();
252 if (sharingAdapter != nullptr) {
253 for (auto &item : devConnectionMap_) {
254 uint32_t contextId = INVALID_ID;
255 uint32_t agentId = INVALID_ID;
256 if (item.second == nullptr) {
257 continue;
258 }
259
260 contextId = item.second->contextId;
261 agentId = item.second->agentId;
262
263 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
264 continue;
265 }
266
267 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
268 sessionMsg->type = EVENT_SESSION_TEARDOWN;
269 sessionMsg->toMgr = MODULE_CONTEXT;
270 sessionMsg->dstId = contextId;
271 sessionMsg->agentId = agentId;
272
273 SharingEvent event;
274 event.eventMsg = std::move(sessionMsg);
275 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
276
277 P2pRemoveClient(*(item.second));
278
279 sharingAdapter->DestroyAgent(contextId, agentId);
280 }
281 }
282
283 if (p2pInstance_) {
284 SHARING_LOGW("DisableP2p before.");
285 p2pInstance_->RemoveGroup();
286 SHARING_LOGW("DisableP2p end.");
287 }
288
289 devConnectionMap_.clear();
290 devSurfaceItemMap_.clear();
291 p2pInstance_.reset();
292 }
293
OnDomainMsg(std::shared_ptr<BaseDomainMsg> & msg)294 void WfdSinkScene::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
295 {
296 SHARING_LOGD("trace.");
297 }
298
OnRequest(std::shared_ptr<BaseMsg> msg,std::shared_ptr<BaseMsg> & reply)299 void WfdSinkScene::OnRequest(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
300 {
301 SHARING_LOGD("trace.");
302 RETURN_IF_NULL(msg);
303 SHARING_LOGI("recv msg, msg id: %{public}d.", msg->GetMsgId());
304 switch (msg->GetMsgId()) {
305 case WfdSinkStartReq::MSG_ID: {
306 auto data = std::static_pointer_cast<WfdSinkStartReq>(msg);
307 auto rsp = std::make_shared<WfdCommonRsp>();
308
309 rsp->ret = HandleStart(data, rsp);
310 reply = std::static_pointer_cast<BaseMsg>(rsp);
311 break;
312 }
313 case WfdSinkStopReq::MSG_ID: {
314 auto data = std::static_pointer_cast<WfdSinkStopReq>(msg);
315 auto rsp = std::make_shared<WfdCommonRsp>();
316
317 rsp->ret = HandleStop(data, rsp);
318 reply = std::static_pointer_cast<BaseMsg>(rsp);
319 break;
320 }
321 case WfdAppendSurfaceReq::MSG_ID: {
322 auto data = std::static_pointer_cast<WfdAppendSurfaceReq>(msg);
323 auto rsp = std::make_shared<WfdCommonRsp>();
324
325 rsp->ret = HandleAppendSurface(data, rsp);
326 reply = std::static_pointer_cast<BaseMsg>(rsp);
327 break;
328 }
329 case WfdRemoveSurfaceReq::MSG_ID: {
330 auto data = std::static_pointer_cast<WfdRemoveSurfaceReq>(msg);
331 auto rsp = std::make_shared<WfdCommonRsp>();
332
333 rsp->ret = HandleRemoveSurface(data, rsp);
334 reply = std::static_pointer_cast<BaseMsg>(rsp);
335 break;
336 }
337 case SetMediaFormatReq::MSG_ID: {
338 auto data = std::static_pointer_cast<SetMediaFormatReq>(msg);
339 auto rsp = std::make_shared<WfdCommonRsp>();
340
341 rsp->ret = HandleSetMediaFormat(data, rsp);
342 reply = std::static_pointer_cast<BaseMsg>(rsp);
343 break;
344 }
345 case SetSceneTypeReq::MSG_ID: {
346 auto data = std::static_pointer_cast<SetSceneTypeReq>(msg);
347 auto rsp = std::make_shared<WfdCommonRsp>();
348
349 rsp->ret = HandleSetSceneType(data, rsp);
350 reply = std::static_pointer_cast<BaseMsg>(rsp);
351 break;
352 }
353 case WfdPlayReq::MSG_ID: {
354 auto data = std::static_pointer_cast<WfdPlayReq>(msg);
355 auto rsp = std::make_shared<WfdCommonRsp>();
356
357 rsp->ret = HandlePlay(data, rsp);
358 reply = std::static_pointer_cast<BaseMsg>(rsp);
359 break;
360 }
361 case WfdPauseReq::MSG_ID: {
362 auto data = std::static_pointer_cast<WfdPauseReq>(msg);
363 auto rsp = std::make_shared<WfdCommonRsp>();
364
365 rsp->ret = HandlePause(data, rsp);
366 reply = std::static_pointer_cast<BaseMsg>(rsp);
367 break;
368 }
369 case MuteReq::MSG_ID: {
370 auto data = std::static_pointer_cast<MuteReq>(msg);
371 auto rsp = std::make_shared<WfdCommonRsp>();
372
373 rsp->ret = HandleMute(data, rsp);
374 reply = std::static_pointer_cast<BaseMsg>(rsp);
375 break;
376 }
377 case UnMuteReq::MSG_ID: {
378 auto data = std::static_pointer_cast<UnMuteReq>(msg);
379 auto rsp = std::make_shared<WfdCommonRsp>();
380
381 rsp->ret = HandleUnMute(data, rsp);
382 reply = std::static_pointer_cast<BaseMsg>(rsp);
383 break;
384 }
385 case WfdCloseReq::MSG_ID: {
386 auto data = std::static_pointer_cast<WfdCloseReq>(msg);
387 auto rsp = std::make_shared<WfdCommonRsp>();
388
389 rsp->ret = HandleClose(data, rsp);
390 reply = std::static_pointer_cast<BaseMsg>(rsp);
391 break;
392 }
393 case GetSinkConfigReq::MSG_ID: {
394 auto data = std::static_pointer_cast<GetSinkConfigReq>(msg);
395 auto rsp = std::make_shared<GetSinkConfigRsp>();
396
397 rsp->foregroundMaximum = INVALID_ID;
398 HandleGetConfig(data, rsp);
399 reply = std::static_pointer_cast<BaseMsg>(rsp);
400 break;
401 }
402 default:
403 SHARING_LOGW("unknown msg request.");
404 break;
405 }
406 }
407
HandleStart(std::shared_ptr<WfdSinkStartReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)408 int32_t WfdSinkScene::HandleStart(std::shared_ptr<WfdSinkStartReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
409 {
410 SHARING_LOGD("trace.");
411 (void)msg;
412 (void)reply;
413 if (isSinkRunning_) {
414 SHARING_LOGW("p2p sink is running.");
415 return 0;
416 }
417 RETURN_INVALID_IF_NULL(p2pInstance_);
418 int32_t ret = 0;
419 int32_t status = 0;
420 p2pInstance_->GetP2pEnableStatus(status);
421 switch (status) {
422 case (int32_t)Wifi::P2pState::P2P_STATE_NONE:
423 case (int32_t)Wifi::P2pState::P2P_STATE_IDLE:
424 case (int32_t)Wifi::P2pState::P2P_STATE_STARTING:
425 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSING:
426 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleStart current p2p state: CLOSING");
427 ret = -1;
428 break;
429 case (int32_t)Wifi::P2pState::P2P_STATE_STARTED:
430 isSinkRunning_ = true;
431 WfdP2pStart();
432 break;
433 case (int32_t)Wifi::P2pState::P2P_STATE_CLOSED:
434 isSinkRunning_ = true;
435 p2pInstance_->EnableP2p();
436 break;
437 default:
438 SHARING_LOGI("none process case.");
439 break;
440 }
441
442 return ret;
443 }
444
HandleStop(std::shared_ptr<WfdSinkStopReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)445 int32_t WfdSinkScene::HandleStop(std::shared_ptr<WfdSinkStopReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
446 {
447 SHARING_LOGD("handle stop, now connect device num: %{public}zu.", devConnectionMap_.size());
448 (void)msg;
449 (void)reply;
450 if (!isSinkRunning_) {
451 SHARING_LOGW("p2p sink is not running.");
452 return -1;
453 }
454
455 isSinkRunning_ = false;
456 WfdP2pStop();
457
458 return 0;
459 }
460
HandleAppendSurface(std::shared_ptr<WfdAppendSurfaceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)461 int32_t WfdSinkScene::HandleAppendSurface(std::shared_ptr<WfdAppendSurfaceReq> &msg,
462 std::shared_ptr<WfdCommonRsp> &reply)
463 {
464 SHARING_LOGD("trace.");
465 (void)reply;
466 RETURN_INVALID_IF_NULL(msg);
467 auto sharingAdapter = sharingAdapter_.lock();
468 RETURN_INVALID_IF_NULL(sharingAdapter);
469
470 {
471 std::unique_lock<std::mutex> lock(mutex_);
472 auto itemDev = devConnectionMap_.find(msg->deviceId);
473 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
474 lock.unlock();
475 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
476 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleAppendSurface can't find the dev");
477 return -1;
478 }
479 int32_t surfaceNum = 0;
480 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
481 if (!itemSurface->second->deleting) {
482 surfaceNum++;
483 }
484 itemSurface++;
485 }
486
487 if (surfaceNum >= surfaceMaximum_) {
488 lock.unlock();
489 SHARING_LOGE("surface is too much.");
490 OnInnerError(0, 0, SharingErrorCode::ERR_SERVICE_LIMIT, "HandleAppendSurface surface is too much");
491 return -1;
492 }
493
494 sptr<IBufferProducer> producer = iface_cast<IBufferProducer>(msg->surface);
495 sptr<Surface> surfacePtr = Surface::CreateSurfaceAsProducer(producer);
496 if (surfacePtr == nullptr) {
497 SHARING_LOGE("invalid surface.");
498 return -1;
499 }
500
501 uint64_t surfaceId = surfacePtr->GetUniqueId();
502 SHARING_LOGI("get surfaceId %{public}" PRIx64 ".", surfaceId);
503 if (devSurfaceItemMap_.count(surfaceId)) {
504 SHARING_LOGW("this surface is using, surfaceId: %{public}" PRIx64 ".", surfaceId);
505 lock.unlock();
506 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "HandleAppendSurface this surface is using");
507 return ERR_STATE_EXCEPTION;
508 }
509
510 int32_t foregroundSurfaceNum = 0;
511 for (auto item : devSurfaceItemMap_) {
512 if ((item.second != nullptr) && (item.second->deviceId == msg->deviceId) && (!item.second->deleting)) {
513 OnInnerError(0, 0, SharingErrorCode::ERR_STATE_EXCEPTION, "Only one surface can be set.");
514 return ERR_STATE_EXCEPTION;
515 }
516
517 if (item.second->sceneType == SceneType::FOREGROUND) {
518 foregroundSurfaceNum++;
519 }
520 }
521
522 auto devSurfaceItem = std::make_shared<DevSurfaceItem>();
523 devSurfaceItem->contextId = itemDev->second->contextId;
524 devSurfaceItem->agentId = itemDev->second->agentId;
525 devSurfaceItem->deviceId = itemDev->second->mac;
526 devSurfaceItem->surfacePtr = surfacePtr;
527 devSurfaceItem->sceneType = (foregroundSurfaceNum >= foregroundMaximum_) ? BACKGROUND : FOREGROUND;
528 devSurfaceItemMap_.emplace(surfaceId, devSurfaceItem);
529
530 if (itemDev->second->isRunning) {
531 uint32_t contextId = itemDev->second->contextId;
532 uint32_t agentId = itemDev->second->agentId;
533
534 auto startSessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
535 startSessionMsg->type = EVENT_WFD_REQUEST_IDR;
536 startSessionMsg->toMgr = MODULE_CONTEXT;
537 startSessionMsg->dstId = contextId;
538 startSessionMsg->agentId = agentId;
539
540 SharingEvent event;
541 event.eventMsg = std::move(startSessionMsg);
542 if (sharingAdapter) {
543 sharingAdapter->ForwardEvent(contextId, agentId, event, false);
544 sharingAdapter->AppendSurface(itemDev->second->contextId, itemDev->second->agentId, surfacePtr,
545 devSurfaceItem->sceneType);
546 }
547 }
548 }
549 return 0;
550 }
551
HandleRemoveSurface(std::shared_ptr<WfdRemoveSurfaceReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)552 int32_t WfdSinkScene::HandleRemoveSurface(std::shared_ptr<WfdRemoveSurfaceReq> &msg,
553 std::shared_ptr<WfdCommonRsp> &reply)
554 {
555 SHARING_LOGD("trace.");
556 (void)reply;
557 RETURN_INVALID_IF_NULL(msg);
558 auto sharingAdapter = sharingAdapter_.lock();
559 RETURN_INVALID_IF_NULL(sharingAdapter);
560 {
561 std::unique_lock<std::mutex> lock(mutex_);
562 auto itemDev = devConnectionMap_.find(msg->deviceId);
563 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
564 lock.unlock();
565 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
566 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleRemoveSurface can't find the dev");
567 return -1;
568 }
569
570 auto item = devSurfaceItemMap_.find(msg->surfaceId);
571 if (item == devSurfaceItemMap_.end()) {
572 lock.unlock();
573 SHARING_LOGE("can not find surfaceid, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
574 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleAppendSurface can't find the dev");
575 return -1;
576 }
577
578 SHARING_LOGW("del surface, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
579 sharingAdapter->RemoveSurface(itemDev->second->contextId, itemDev->second->agentId, msg->surfaceId);
580 }
581
582 return 0;
583 }
584
HandleSetMediaFormat(std::shared_ptr<SetMediaFormatReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)585 int32_t WfdSinkScene::HandleSetMediaFormat(std::shared_ptr<SetMediaFormatReq> &msg,
586 std::shared_ptr<WfdCommonRsp> &reply)
587 {
588 SHARING_LOGD("trace.");
589 (void)reply;
590 RETURN_INVALID_IF_NULL(msg);
591 {
592 std::unique_lock<std::mutex> lock(mutex_);
593 auto itemDev = devConnectionMap_.find(msg->deviceId);
594 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
595 lock.unlock();
596 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
597 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetMediaFormat can not find dev");
598 return -1;
599 }
600 itemDev->second->videoCodecId = static_cast<CodecId>(msg->videoAttr.codecType);
601 itemDev->second->videoFormatId = static_cast<VideoFormat>(msg->videoAttr.formatId);
602 itemDev->second->audioCodecId = static_cast<CodecId>(msg->audioAttr.codecType);
603 itemDev->second->audioFormatId = static_cast<AudioFormat>(msg->audioAttr.formatId);
604 }
605
606 return 0;
607 }
608
HandleSetSceneType(std::shared_ptr<SetSceneTypeReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)609 int32_t WfdSinkScene::HandleSetSceneType(std::shared_ptr<SetSceneTypeReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
610 {
611 SHARING_LOGD("trace.");
612 (void)reply;
613 RETURN_INVALID_IF_NULL(msg);
614 auto sharingAdapter = sharingAdapter_.lock();
615 RETURN_INVALID_IF_NULL(sharingAdapter);
616
617 uint32_t contextId = INVALID_ID;
618 uint32_t agentId = INVALID_ID;
619 {
620 std::unique_lock<std::mutex> lock(mutex_);
621 auto itemDev = devConnectionMap_.find(msg->deviceId);
622 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
623 lock.unlock();
624 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
625 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetSceneType can not find dev");
626 return -1;
627 }
628
629 auto itemSurface = devSurfaceItemMap_.find(msg->surfaceId);
630 if ((itemSurface == devSurfaceItemMap_.end()) || (itemSurface->second) || (itemSurface->second->deleting)) {
631 lock.unlock();
632 SHARING_LOGE("can not find surfaceid, surfaceid: %{public}" PRId64 ".", msg->surfaceId);
633 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleSetSceneType can't find the surfaceId");
634 return -1;
635 }
636
637 contextId = itemDev->second->contextId;
638 agentId = itemDev->second->agentId;
639
640 uint32_t foregroundSurfaceNum = 1;
641 if (msg->sceneType == SceneType::FOREGROUND) {
642 for (auto item : devSurfaceItemMap_) {
643 if ((item.first == msg->surfaceId) && (!item.second->deleting)) {
644 continue;
645 }
646
647 if (item.second->sceneType == SceneType::FOREGROUND) {
648 foregroundSurfaceNum++;
649 }
650 }
651
652 if (foregroundSurfaceNum > (uint32_t)foregroundMaximum_) {
653 lock.unlock();
654 SHARING_LOGE("foreground surfaces is too much.");
655 OnInnerError(0, 0, SharingErrorCode::ERR_SERVICE_LIMIT,
656 "HandleSetSceneType foreground surfaces is too much");
657 return -1;
658 } else {
659 itemSurface->second->sceneType = SceneType::FOREGROUND;
660 }
661 } else {
662 itemSurface->second->sceneType = SceneType::BACKGROUND;
663 }
664 }
665
666 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
667 SHARING_LOGW("invalid contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
668 return 0;
669 }
670
671 bool keyFrame = msg->sceneType == SceneType::BACKGROUND ? true : false;
672 auto ret = sharingAdapter->SetKeyPlay(contextId, agentId, msg->surfaceId, keyFrame);
673 if (!keyFrame) {
674 sharingAdapter->SetKeyRedirect(contextId, agentId, msg->surfaceId, true);
675 }
676
677 return ret;
678 }
679
HandlePlay(std::shared_ptr<WfdPlayReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)680 int32_t WfdSinkScene::HandlePlay(std::shared_ptr<WfdPlayReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
681 {
682 SHARING_LOGD("trace.");
683 (void)reply;
684 RETURN_INVALID_IF_NULL(msg);
685 auto sharingAdapter = sharingAdapter_.lock();
686 RETURN_INVALID_IF_NULL(sharingAdapter);
687
688 {
689 std::unique_lock<std::mutex> lock(mutex_);
690 auto itemDev = devConnectionMap_.find(msg->deviceId);
691 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
692 lock.unlock();
693 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
694 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandlePlay can not find dev");
695 return -1;
696 }
697
698 uint32_t contextId = itemDev->second->contextId;
699 uint32_t agentId = itemDev->second->agentId;
700 if (contextId == INVALID_ID || agentId == INVALID_ID) {
701 lock.unlock();
702 SHARING_LOGE("connected, create sink agent failed, devMac: %{private}s.",
703 GetAnonyString(msg->deviceId).c_str());
704 return -1;
705 }
706
707 if (itemDev->second->isRunning == true) {
708 lock.unlock();
709 return sharingAdapter->Resume(contextId, agentId, MEDIA_TYPE_AV);
710 } else {
711 itemDev->second->isRunning = true;
712 }
713
714 lock.unlock();
715
716 auto startSessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
717 startSessionMsg->type = EVENT_SESSION_INIT;
718 startSessionMsg->toMgr = MODULE_CONTEXT;
719 startSessionMsg->dstId = contextId;
720 startSessionMsg->agentId = agentId;
721 startSessionMsg->ip = itemDev->second->ip;
722 startSessionMsg->mac = itemDev->second->mac;
723 startSessionMsg->remotePort = itemDev->second->ctrlPort;
724 startSessionMsg->videoFormat = itemDev->second->videoFormatId;
725 startSessionMsg->audioFormat = itemDev->second->audioFormatId;
726 startSessionMsg->localPort = SocketUtils::GetAvailableUdpPortPair();
727
728 SharingEvent event;
729 event.eventMsg = std::move(startSessionMsg);
730
731 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
732 sharingAdapter->Start(contextId, agentId);
733
734 for (auto &item : devSurfaceItemMap_) {
735 if ((item.second != nullptr) && (itemDev->first == item.second->deviceId) && (!item.second->deleting)) {
736 if (item.second->surfacePtr != nullptr) {
737 sharingAdapter->AppendSurface(contextId, agentId, item.second->surfacePtr, item.second->sceneType);
738 }
739 }
740 }
741
742 sharingAdapter->Play(contextId, agentId);
743 }
744
745 return 0;
746 }
747
HandlePause(std::shared_ptr<WfdPauseReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)748 int32_t WfdSinkScene::HandlePause(std::shared_ptr<WfdPauseReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
749 {
750 SHARING_LOGD("trace.");
751 (void)reply;
752 RETURN_INVALID_IF_NULL(msg);
753 auto sharingAdapter = sharingAdapter_.lock();
754 RETURN_INVALID_IF_NULL(sharingAdapter);
755
756 uint32_t contextId = INVALID_ID;
757 uint32_t agentId = INVALID_ID;
758 {
759 std::unique_lock<std::mutex> lock(mutex_);
760 auto itemDev = devConnectionMap_.find(msg->deviceId);
761 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
762 lock.unlock();
763 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
764 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandlePause can not find dev");
765 return -1;
766 }
767
768 contextId = itemDev->second->contextId;
769 agentId = itemDev->second->agentId;
770 }
771
772 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
773 return -1;
774 }
775
776 return sharingAdapter->Pause(contextId, agentId, MEDIA_TYPE_AV);
777 }
778
HandleMute(std::shared_ptr<MuteReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)779 int32_t WfdSinkScene::HandleMute(std::shared_ptr<MuteReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
780 {
781 SHARING_LOGD("trace.");
782 (void)reply;
783 RETURN_INVALID_IF_NULL(msg);
784 auto sharingAdapter = sharingAdapter_.lock();
785 RETURN_INVALID_IF_NULL(sharingAdapter);
786
787 uint32_t contextId = INVALID_ID;
788 uint32_t agentId = INVALID_ID;
789 {
790 std::unique_lock<std::mutex> lock(mutex_);
791 auto itemDev = devConnectionMap_.find(msg->deviceId);
792 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
793 lock.unlock();
794 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
795 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleMute can not find dev");
796 return -1;
797 }
798
799 contextId = itemDev->second->contextId;
800 agentId = itemDev->second->agentId;
801 }
802
803 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
804 return -1;
805 }
806
807 return sharingAdapter->Pause(contextId, agentId, MEDIA_TYPE_AUDIO);
808 }
809
HandleUnMute(std::shared_ptr<UnMuteReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)810 int32_t WfdSinkScene::HandleUnMute(std::shared_ptr<UnMuteReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
811 {
812 SHARING_LOGD("trace.");
813 (void)reply;
814 RETURN_INVALID_IF_NULL(msg);
815 auto sharingAdapter = sharingAdapter_.lock();
816 RETURN_INVALID_IF_NULL(sharingAdapter);
817
818 uint32_t contextId = INVALID_ID;
819 uint32_t agentId = INVALID_ID;
820 {
821 std::unique_lock<std::mutex> lock(mutex_);
822 auto itemDev = devConnectionMap_.find(msg->deviceId);
823 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
824 lock.unlock();
825 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
826 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleUnMute can not find dev");
827 return -1;
828 }
829
830 contextId = itemDev->second->contextId;
831 agentId = itemDev->second->agentId;
832 }
833
834 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
835 return -1;
836 }
837
838 return sharingAdapter->Resume(contextId, agentId, MEDIA_TYPE_AUDIO);
839 }
840
HandleClose(std::shared_ptr<WfdCloseReq> & msg,std::shared_ptr<WfdCommonRsp> & reply)841 int32_t WfdSinkScene::HandleClose(std::shared_ptr<WfdCloseReq> &msg, std::shared_ptr<WfdCommonRsp> &reply)
842 {
843 SHARING_LOGD("trace.");
844 (void)reply;
845 RETURN_INVALID_IF_NULL(msg);
846 auto sharingAdapter = sharingAdapter_.lock();
847 RETURN_INVALID_IF_NULL(sharingAdapter);
848
849 uint32_t contextId = INVALID_ID;
850 uint32_t agentId = INVALID_ID;
851 ConnectionInfo connectionInfo;
852 {
853 std::unique_lock<std::mutex> lock(mutex_);
854 auto itemDev = devConnectionMap_.find(msg->deviceId);
855 if (itemDev == devConnectionMap_.end() || itemDev->second == nullptr) {
856 lock.unlock();
857 SHARING_LOGE("can not find dev, mac: %{private}s.", GetAnonyString(msg->deviceId).c_str());
858 OnInnerError(0, 0, SharingErrorCode::ERR_BAD_PARAMETER, "HandleClose can not find dev");
859 return -1;
860 }
861
862 connectionInfo.ip = itemDev->second->ip;
863 connectionInfo.mac = itemDev->second->mac;
864 connectionInfo.state = ConnectionState::DISCONNECTED;
865 connectionInfo.surfaceId = itemDev->second->surfaceId;
866 connectionInfo.deviceName = itemDev->second->deviceName;
867 connectionInfo.primaryDeviceType = itemDev->second->primaryDeviceType;
868 connectionInfo.secondaryDeviceType = itemDev->second->secondaryDeviceType;
869
870 contextId = itemDev->second->contextId;
871 agentId = itemDev->second->agentId;
872
873 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
874 if ((itemSurface->second != nullptr) && (msg->deviceId == itemSurface->second->deviceId)) {
875 itemSurface->second->deleting = true;
876 }
877 itemSurface++;
878 }
879
880 P2pRemoveClient(connectionInfo);
881
882 devConnectionMap_.erase(msg->deviceId);
883 }
884
885 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
886 return -1;
887 }
888
889 OnConnectionChanged(connectionInfo);
890 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
891 sessionMsg->type = EVENT_SESSION_TEARDOWN;
892 sessionMsg->toMgr = MODULE_CONTEXT;
893 sessionMsg->dstId = contextId;
894 sessionMsg->agentId = agentId;
895
896 SharingEvent event;
897 event.eventMsg = std::move(sessionMsg);
898 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
899
900 return sharingAdapter->DestroyAgent(contextId, agentId);
901 }
902
HandleGetConfig(std::shared_ptr<GetSinkConfigReq> & msg,std::shared_ptr<GetSinkConfigRsp> & reply)903 int32_t WfdSinkScene::HandleGetConfig(std::shared_ptr<GetSinkConfigReq> &msg, std::shared_ptr<GetSinkConfigRsp> &reply)
904 {
905 SHARING_LOGD("trace.");
906 (void)msg;
907 RETURN_INVALID_IF_NULL(reply);
908 reply->accessDevMaximum = accessDevMaximum_;
909 reply->foregroundMaximum = foregroundMaximum_;
910 reply->surfaceMaximum = surfaceMaximum_;
911
912 return 0;
913 }
914
WfdP2pStart()915 void WfdSinkScene::WfdP2pStart()
916 {
917 SHARING_LOGD("trace.");
918 if (p2pInstance_) {
919 p2pInstance_->RemoveGroup();
920
921 Wifi::WifiP2pWfdInfo wfdInfo;
922 wfdInfo.SetWfdEnabled(true);
923 wfdInfo.SetDeviceInfo(0x11);
924 wfdInfo.SetCtrlPort(ctrlPort_);
925 wfdInfo.SetMaxThroughput(0x00c8);
926
927 p2pInstance_->SetP2pWfdInfo(wfdInfo);
928
929 SHARING_LOGD("WfdSinkScene CreateGroup.");
930 std::vector<Wifi::WifiP2pGroupInfo> p2pGroups;
931 p2pInstance_->QueryP2pGroups(p2pGroups);
932
933 int32_t netWokrId = -2;
934 if (!p2pGroups.empty()) {
935 SHARING_LOGD("WfdSinkScene p2p group exists, the netWorkId:%{public}d.", netWokrId);
936 }
937
938 Wifi::WifiP2pDevice p2pDev;
939 p2pInstance_->QueryP2pLocalDevice(p2pDev);
940 auto hostAddr = p2pDev.GetDeviceAddress();
941
942 Wifi::WifiP2pConfig cfg;
943 cfg.SetGoBand(Wifi::GroupOwnerBand::GO_BAND_5GHZ);
944 cfg.SetNetId(netWokrId);
945 cfg.SetDeviceAddress(hostAddr);
946
947 p2pInstance_->CreateGroup(cfg);
948 SHARING_LOGD("WfdSinkScene DiscoverDevices.");
949 }
950 }
951
WfdP2pStop()952 void WfdSinkScene::WfdP2pStop()
953 {
954 SHARING_LOGD("trace.");
955 std::unique_lock<std::mutex> lock(mutex_);
956 auto sharingAdapter = sharingAdapter_.lock();
957 if (sharingAdapter != nullptr) {
958 for (auto item : devConnectionMap_) {
959 uint32_t contextId = item.second->contextId;
960 uint32_t agentId = item.second->agentId;
961
962 if ((contextId != INVALID_ID) && (agentId != INVALID_ID)) {
963 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
964 sessionMsg->type = EVENT_SESSION_TEARDOWN;
965 sessionMsg->toMgr = MODULE_CONTEXT;
966 sessionMsg->dstId = contextId;
967 sessionMsg->agentId = agentId;
968
969 SharingEvent event;
970 event.eventMsg = std::move(sessionMsg);
971 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
972
973 P2pRemoveClient(*(item.second));
974
975 sharingAdapter->DestroyAgent(contextId, agentId);
976 }
977 }
978 }
979
980 if (p2pInstance_) {
981 SHARING_LOGW("DisableP2p before.");
982 p2pInstance_->StopDiscoverDevices();
983 p2pInstance_->RemoveGroup();
984 SHARING_LOGW("DisableP2p end.");
985 }
986
987 devSurfaceItemMap_.clear();
988 devConnectionMap_.clear();
989 }
990
OnP2pPeerConnected(ConnectionInfo & connectionInfo)991 void WfdSinkScene::OnP2pPeerConnected(ConnectionInfo &connectionInfo)
992 {
993 SHARING_LOGD("trace.");
994 if (!isSinkRunning_) {
995 SHARING_LOGW("sink service is not running.");
996 return;
997 }
998
999 auto sharingAdapter = sharingAdapter_.lock();
1000 RETURN_IF_NULL(sharingAdapter);
1001
1002 if (devConnectionMap_.size() >= (uint32_t)accessDevMaximum_) {
1003 SHARING_LOGE("too more device.");
1004 P2pRemoveClient(connectionInfo);
1005
1006 auto ipcAdapter = ipcAdapter_.lock();
1007 RETURN_IF_NULL(ipcAdapter);
1008
1009 auto msg = std::make_shared<WfdErrorMsg>();
1010 msg->message = "Maximum number of devices reached";
1011 msg->errorCode = ERR_RECEIVING_LIMIT;
1012
1013 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1014 ipcAdapter->SendRequest(msg, reply);
1015
1016 return;
1017 }
1018
1019 {
1020 std::unique_lock<std::mutex> lock(mutex_);
1021 if (devConnectionMap_.count(connectionInfo.mac)) {
1022 SHARING_LOGW("devcie is alerady connected, mac: %{private}s.", GetAnonyString(connectionInfo.mac).c_str());
1023 return;
1024 }
1025
1026 uint32_t contextId = INVALID_ID;
1027 uint32_t agentId = INVALID_ID;
1028
1029 sharingAdapter->CreateAgent(contextId, agentId, AgentType::SINK_AGENT, "WfdSinkSession");
1030 if (contextId == INVALID_ID || agentId == INVALID_ID) {
1031 lock.unlock();
1032 SHARING_LOGE("connected, create sink agent failed, devMac: %{private}s.",
1033 GetAnonyString(connectionInfo.mac).c_str());
1034 return;
1035 } else {
1036 SHARING_LOGI("connected, create sink agent, contextId: %{public}u, "
1037 "agentId: %{public}u, devMac: %{private}s, devIp: %{private}s.",
1038 contextId, agentId, connectionInfo.mac.c_str(), connectionInfo.ip.c_str());
1039 }
1040
1041 connectionInfo.contextId = contextId;
1042 connectionInfo.agentId = agentId;
1043 connectionInfo.videoCodecId = videoCodecId_;
1044 connectionInfo.videoFormatId = videoFormatId_;
1045 connectionInfo.audioCodecId = audioCodecId_;
1046 connectionInfo.audioFormatId = audioFormatId_;
1047
1048 std::shared_ptr<ConnectionInfo> connectionInfoPtr = std::make_shared<ConnectionInfo>(connectionInfo);
1049 devConnectionMap_.emplace(connectionInfo.mac, connectionInfoPtr);
1050 SHARING_LOGI("connected, devMac: %{private}s, devIp: %{private}s.", GetAnonyString(connectionInfo.mac).c_str(),
1051 GetAnonyString(connectionInfo.ip).c_str());
1052 }
1053
1054 OnConnectionChanged(connectionInfo);
1055 }
1056
OnP2pPeerDisconnected(ConnectionInfo & connectionInfo)1057 void WfdSinkScene::OnP2pPeerDisconnected(ConnectionInfo &connectionInfo)
1058 {
1059 SHARING_LOGD("trace.");
1060 auto sharingAdapter = sharingAdapter_.lock();
1061 RETURN_IF_NULL(sharingAdapter);
1062
1063 uint32_t contextId = INVALID_ID;
1064 uint32_t agentId = INVALID_ID;
1065 {
1066 std::unique_lock<std::mutex> lock(mutex_);
1067 auto itemDev = devConnectionMap_.find(connectionInfo.mac);
1068 if (itemDev == devConnectionMap_.end()) {
1069 lock.unlock();
1070 SHARING_LOGW("can not find dev, mac: %{private}s.", GetAnonyString(connectionInfo.mac).c_str());
1071 return;
1072 }
1073
1074 contextId = itemDev->second->contextId;
1075 agentId = itemDev->second->agentId;
1076 connectionInfo.surfaceId = itemDev->second->surfaceId;
1077
1078 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1079 if (connectionInfo.mac == itemSurface->second->deviceId) {
1080 itemSurface->second->deleting = true;
1081 }
1082 itemSurface++;
1083 }
1084
1085 P2pRemoveClient(connectionInfo);
1086
1087 devConnectionMap_.erase(connectionInfo.mac);
1088 SHARING_LOGI("disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s.", contextId,
1089 agentId, connectionInfo.mac.c_str());
1090 }
1091
1092 OnConnectionChanged(connectionInfo);
1093
1094 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1095 return;
1096 }
1097
1098 auto sessionMsg = std::make_shared<WfdSinkSessionEventMsg>();
1099 sessionMsg->type = EVENT_SESSION_TEARDOWN;
1100 sessionMsg->toMgr = MODULE_CONTEXT;
1101 sessionMsg->dstId = contextId;
1102 sessionMsg->agentId = agentId;
1103
1104 SharingEvent event;
1105 event.eventMsg = std::move(sessionMsg);
1106
1107 sharingAdapter->ForwardEvent(contextId, agentId, event, true);
1108 sharingAdapter->DestroyAgent(contextId, agentId);
1109 }
1110
OnP2pPeerDisconnected(std::string & mac)1111 void WfdSinkScene::OnP2pPeerDisconnected(std::string &mac)
1112 {
1113 SHARING_LOGD("trace.");
1114 uint32_t contextId = INVALID_ID;
1115 uint32_t agentId = INVALID_ID;
1116 std::shared_ptr<ConnectionInfo> connectionInfo = nullptr;
1117 {
1118 std::unique_lock<std::mutex> lock(mutex_);
1119 auto itemDev = devConnectionMap_.find(mac);
1120 if (itemDev == devConnectionMap_.end()) {
1121 lock.unlock();
1122 SHARING_LOGW("can not find dev, mac: %{private}s.", GetAnonyString(mac).c_str());
1123 return;
1124 }
1125
1126 contextId = itemDev->second->contextId;
1127 agentId = itemDev->second->agentId;
1128 connectionInfo = itemDev->second;
1129
1130 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1131 if (mac == itemSurface->second->deviceId) {
1132 itemSurface->second->deleting = true;
1133 }
1134 itemSurface++;
1135 }
1136
1137 SHARING_LOGI("disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s.", contextId,
1138 agentId, mac.c_str());
1139 P2pRemoveClient(*connectionInfo);
1140
1141 devConnectionMap_.erase(mac);
1142 }
1143
1144 if ((contextId == INVALID_ID) || (agentId == INVALID_ID)) {
1145 return;
1146 }
1147
1148 auto sharingAdapter = sharingAdapter_.lock();
1149 if (sharingAdapter != nullptr) {
1150 sharingAdapter->DestroyAgent(contextId, agentId);
1151 }
1152
1153 if (connectionInfo != nullptr) {
1154 connectionInfo->state = ConnectionState::DISCONNECTED;
1155 OnConnectionChanged(*connectionInfo);
1156 }
1157 }
1158
ErrorCodeFiltering(int32_t & code)1159 void WfdSinkScene::ErrorCodeFiltering(int32_t &code)
1160 {
1161 SHARING_LOGD("the error code is %{public}d.", code);
1162 switch (ABSTRACT_ERR_BASE(code)) {
1163 case SharingErrorCode::ERR_CONTEXT_AGENT_BASE: // fall-through
1164 case SharingErrorCode::ERR_SESSION_BASE:
1165 code = SharingErrorCode::ERR_GENERAL_ERROR;
1166 SHARING_LOGD("the error change to %{public}d.", code);
1167 break;
1168 case SharingErrorCode::ERR_PROSUMER_BASE: {
1169 switch (code) {
1170 case ERR_PROSUMER_START:
1171 code = SharingErrorCode::ERR_CONNECTION_FAILURE;
1172 break;
1173 case ERR_PROSUMER_TIMEOUT:
1174 code = SharingErrorCode::ERR_CONNECTION_TIMEOUT;
1175 break;
1176 case ERR_PROSUMER_DESTROY:
1177 code = SharingErrorCode::ERR_STATE_EXCEPTION;
1178 break;
1179 default:
1180 code = SharingErrorCode::ERR_GENERAL_ERROR;
1181 break;
1182 }
1183 break;
1184 }
1185 default:
1186 SHARING_LOGI("none process case.");
1187 break;
1188 }
1189 }
1190
OnInnerError(uint32_t contextId,uint32_t agentId,SharingErrorCode errorCode,std::string message)1191 void WfdSinkScene::OnInnerError(uint32_t contextId, uint32_t agentId, SharingErrorCode errorCode, std::string message)
1192 {
1193 SHARING_LOGD("trace.");
1194 auto ipcAdapter = ipcAdapter_.lock();
1195 RETURN_IF_NULL(ipcAdapter);
1196
1197 auto msg = std::make_shared<WfdErrorMsg>();
1198 msg->contextId = contextId;
1199 msg->agentId = agentId;
1200 msg->errorCode = errorCode;
1201
1202 for (auto &item : devConnectionMap_) {
1203 if ((contextId == item.second->contextId) && (agentId == item.second->agentId)) {
1204 msg->mac = item.second->mac;
1205 break;
1206 }
1207 }
1208
1209 if (errorCode == SharingErrorCode::ERR_PROSUMER_TIMEOUT) {
1210 msg->message =
1211 "contextId: " + std::to_string(contextId) + ", agentId: " + std::to_string(agentId) + ", producer timeout";
1212 } else {
1213 msg->message = std::move(message);
1214 }
1215
1216 ErrorCodeFiltering(msg->errorCode);
1217 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1218
1219 SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
1220 ipcAdapter->SendRequest(msg, reply);
1221 }
1222
OnInnerError(std::string deviceId,SharingErrorCode errorCode,std::string message)1223 void WfdSinkScene::OnInnerError(std::string deviceId, SharingErrorCode errorCode, std::string message)
1224 {
1225 SHARING_LOGD("trace.");
1226 auto ipcAdapter = ipcAdapter_.lock();
1227 RETURN_IF_NULL(ipcAdapter);
1228
1229 auto msg = std::make_shared<WfdErrorMsg>();
1230 msg->message = message;
1231 msg->mac = deviceId;
1232 msg->errorCode = errorCode;
1233
1234 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1235
1236 SHARING_LOGW("receive errorCode: %{public}d.", errorCode);
1237 ipcAdapter->SendRequest(msg, reply);
1238 }
1239
OnInnerDestroy(uint32_t contextId,uint32_t agentId,AgentType agentType)1240 void WfdSinkScene::OnInnerDestroy(uint32_t contextId, uint32_t agentId, AgentType agentType)
1241 {
1242 SHARING_LOGI("HandleInnerDestroy, contextId: %{public}u, agentId: %{public}u, agentType: %{public}s.", contextId,
1243 agentId, std::string(magic_enum::enum_name(agentType)).c_str());
1244
1245 std::unique_lock<std::mutex> lock(mutex_);
1246 for (auto itemSurface = devSurfaceItemMap_.begin(); itemSurface != devSurfaceItemMap_.end();) {
1247 if ((itemSurface->second != nullptr) && (contextId == itemSurface->second->contextId) &&
1248 (agentId == itemSurface->second->agentId)) {
1249 devSurfaceItemMap_.erase(itemSurface++);
1250 } else {
1251 itemSurface++;
1252 }
1253 }
1254
1255 for (auto &item : devConnectionMap_) {
1256 if ((item.second != nullptr) && (contextId == item.second->contextId) && (agentId == item.second->agentId)) {
1257 ConnectionInfo connectionInfo;
1258 connectionInfo.ip = item.second->ip;
1259 connectionInfo.mac = item.second->mac;
1260 connectionInfo.deviceName = item.second->deviceName;
1261 connectionInfo.primaryDeviceType = item.second->primaryDeviceType;
1262 connectionInfo.secondaryDeviceType = item.second->secondaryDeviceType;
1263 connectionInfo.ctrlPort = item.second->ctrlPort;
1264 connectionInfo.state = ConnectionState::DISCONNECTED;
1265
1266 SHARING_LOGI(
1267 "disconnected, contextId: %{public}u, agentId: %{public}u, devMac: %{private}s, devIp: %{private}s.",
1268 contextId, agentId, connectionInfo.mac.c_str(), connectionInfo.ip.c_str());
1269 OnConnectionChanged(connectionInfo);
1270
1271 P2pRemoveClient(connectionInfo);
1272
1273 devConnectionMap_.erase(item.second->mac);
1274 break;
1275 }
1276 }
1277 }
1278
OnInnerEvent(SharingEvent & event)1279 void WfdSinkScene::OnInnerEvent(SharingEvent &event)
1280 {
1281 SHARING_LOGD("trace.");
1282 RETURN_IF_NULL(event.eventMsg);
1283
1284 SHARING_LOGI("eventType: %{public}s.", std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
1285 switch (event.eventMsg->type) {
1286 case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED: {
1287 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
1288 if (msg) {
1289 std::unique_lock<std::mutex> lock(mutex_);
1290 auto itConnection = devConnectionMap_.find(msg->mac);
1291 if (itConnection == devConnectionMap_.end()) {
1292 SHARING_LOGD("can't find dev %{private}s.", msg->mac.c_str());
1293 break;
1294 }
1295
1296 itConnection->second->state = ConnectionState::PLAYING;
1297 OnConnectionChanged(*itConnection->second);
1298 }
1299 break;
1300 }
1301 case EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN: {
1302 auto msg = ConvertEventMsg<WfdSceneEventMsg>(event);
1303 if (msg) {
1304 OnP2pPeerDisconnected(msg->mac);
1305 }
1306 break;
1307 }
1308 case EventType::EVENT_INTERACTION_ACCELERATION_DONE: {
1309 auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1310 SHARING_LOGD("On acceleration done, contextId: %{public}d agentId: %{public}d.", msg->contextId,
1311 msg->agentId);
1312 for (auto connectInfoPair : devConnectionMap_) {
1313 if (connectInfoPair.second != nullptr && connectInfoPair.second->contextId == msg->contextId &&
1314 connectInfoPair.second->agentId == msg->agentId) {
1315 SHARING_LOGD("On acceleration done, device found.");
1316 auto connectInfo = connectInfoPair.second;
1317 connectInfo->surfaceId = msg->surfaceId;
1318
1319 OnDecoderAccelerationDone(*connectInfo);
1320 break;
1321 }
1322 SHARING_LOGW("On acceleration done, device not found.");
1323 }
1324 break;
1325 }
1326 case EventType::EVENT_INTERACTION_STATE_REMOVE_SURFACE: {
1327 auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1328 SHARING_LOGD("On state remove surface, agentId: %{public}d.", msg->agentId);
1329 std::unique_lock<std::mutex> lock(mutex_);
1330 devSurfaceItemMap_.erase(msg->surfaceId);
1331 break;
1332 }
1333 case EVENT_INTERACTION_DECODER_DIED: {
1334 auto msg = ConvertEventMsg<InteractionEventMsg>(event);
1335 auto surfaceItem = devSurfaceItemMap_.find(msg->surfaceId);
1336 if (surfaceItem != devSurfaceItemMap_.end() && surfaceItem->second != nullptr) {
1337 auto itConnection = devConnectionMap_.find(surfaceItem->second->deviceId);
1338 OnDecoderDied(*itConnection->second);
1339 }
1340 break;
1341 }
1342 default:
1343 SHARING_LOGI("none process case.");
1344 break;
1345 }
1346 }
1347
OnConnectionChanged(ConnectionInfo & connectionInfo)1348 void WfdSinkScene::OnConnectionChanged(ConnectionInfo &connectionInfo)
1349 {
1350 SHARING_LOGD("trace.");
1351 auto ipcAdapter = ipcAdapter_.lock();
1352 RETURN_IF_NULL(ipcAdapter);
1353
1354 auto msg = std::make_shared<WfdConnectionChangedMsg>();
1355 msg->ip = connectionInfo.ip;
1356 msg->mac = connectionInfo.mac;
1357 msg->state = connectionInfo.state;
1358 msg->surfaceId = connectionInfo.surfaceId;
1359 msg->deviceName = connectionInfo.deviceName;
1360 msg->primaryDeviceType = connectionInfo.primaryDeviceType;
1361 msg->secondaryDeviceType = connectionInfo.secondaryDeviceType;
1362
1363 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1364 ipcAdapter->SendRequest(msg, reply);
1365 }
1366
P2pRemoveClient(ConnectionInfo & connectionInfo)1367 void WfdSinkScene::P2pRemoveClient(ConnectionInfo &connectionInfo)
1368 {
1369 SHARING_LOGI("p2p remove client: %{private}s.", GetAnonyString(connectionInfo.mac).c_str());
1370 if (!p2pInstance_) {
1371 SHARING_LOGE("p2p instance is null");
1372 return;
1373 }
1374
1375 OHOS::Wifi::GcInfo info;
1376 info.mac = connectionInfo.mac;
1377 info.ip = connectionInfo.ip;
1378 info.host = connectionInfo.deviceName;
1379
1380 p2pInstance_->RemoveGroupClient(info);
1381 }
1382
OnDecoderAccelerationDone(ConnectionInfo & connectionInfo)1383 void WfdSinkScene::OnDecoderAccelerationDone(ConnectionInfo &connectionInfo)
1384 {
1385 SHARING_LOGD("trace.");
1386 auto ipcAdapter = ipcAdapter_.lock();
1387 RETURN_IF_NULL(ipcAdapter);
1388
1389 auto msg = std::make_shared<WfdDecoderAccelerationDoneMsg>();
1390 msg->surfaceId = connectionInfo.surfaceId;
1391
1392 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1393 ipcAdapter->SendRequest(msg, reply);
1394 SHARING_LOGD("device ip: %{private}s, mac: %{private}s, state: %{public}s.",
1395 GetAnonyString(connectionInfo.ip).c_str(), GetAnonyString(connectionInfo.mac).c_str(),
1396 std::string(magic_enum::enum_name(connectionInfo.state)).c_str());
1397 }
1398
OnDecoderDied(ConnectionInfo & connectionInfo)1399 void WfdSinkScene::OnDecoderDied(ConnectionInfo &connectionInfo)
1400 {
1401 SHARING_LOGD("trace.");
1402 auto ipcAdapter = ipcAdapter_.lock();
1403 RETURN_IF_NULL(ipcAdapter);
1404
1405 auto msg = std::make_shared<WfdSurfaceFailureMsg>();
1406 msg->surfaceId = connectionInfo.surfaceId;
1407 auto reply = std::static_pointer_cast<BaseMsg>(std::make_shared<WfdCommonRsp>());
1408 ipcAdapter->SendRequest(msg, reply);
1409
1410 SHARING_LOGD("failed at device ip: %{private}s, mac: %{private}s, state: %{public}s.", connectionInfo.ip.c_str(),
1411 connectionInfo.mac.c_str(), std::string(magic_enum::enum_name(connectionInfo.state)).c_str());
1412 }
1413
OnRemoteDied()1414 void WfdSinkScene::OnRemoteDied()
1415 {
1416 SHARING_LOGD("trace.");
1417 auto sharingAdapter = sharingAdapter_.lock();
1418 if (sharingAdapter) {
1419 sharingAdapter->ReleaseScene(GetId());
1420 }
1421 }
1422
1423 REGISTER_CLASS_REFLECTOR(WfdSinkScene);
1424 } // namespace Sharing
1425 } // namespace OHOS
1426