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_session.h"
17 #include <iomanip>
18 #include "common/common_macro.h"
19 #include "common/reflect_registration.h"
20 #include "common/sharing_log.h"
21 #include "mediachannel/media_channel_def.h"
22 #include "screen_capture_def.h"
23 #include "utils/utils.h"
24 #include "wfd_media_def.h"
25 #include "wfd_message.h"
26
27 namespace OHOS {
28 namespace Sharing {
WfdSourceNetworkSession(std::weak_ptr<INetworkSession> sessionPtr,std::weak_ptr<WfdSourceSession> serverPtr)29 WfdSourceSession::WfdSourceNetworkSession::WfdSourceNetworkSession(std::weak_ptr<INetworkSession> sessionPtr,
30 std::weak_ptr<WfdSourceSession> serverPtr)
31 : sessionPtr_(sessionPtr), serverPtr_(serverPtr)
32 {
33 SHARING_LOGI("%{public}s.", __FUNCTION__);
34 }
35
~WfdSourceNetworkSession()36 WfdSourceSession::WfdSourceNetworkSession::~WfdSourceNetworkSession()
37 {
38 SHARING_LOGI("%{public}s.", __FUNCTION__);
39 if (timer_ != nullptr) {
40 timer_->Shutdown();
41 timer_.reset();
42 }
43 }
44
UnsetKeepAliveTimer()45 void WfdSourceSession::WfdSourceNetworkSession::UnsetKeepAliveTimer()
46 {
47 SHARING_LOGD("trace.");
48 if (timer_ != nullptr) {
49 timer_->Unregister(timerId_);
50 timerId_ = 0;
51 }
52 }
53
SetKeepAliveTimer()54 void WfdSourceSession::WfdSourceNetworkSession::SetKeepAliveTimer()
55 {
56 SHARING_LOGD("trace.");
57 int32_t interval = RTSP_INTERACTION_TIMEOUT * WFD_SEC_TO_MSEC;
58 if (timer_ != nullptr) {
59 timerId_ = timer_->Register(std::bind(&WfdSourceNetworkSession::OnSendKeepAlive, this), interval);
60 timer_->Setup();
61 }
62 }
63
OnSessionReadData(int32_t fd,DataBuffer::Ptr buf)64 void WfdSourceSession::WfdSourceNetworkSession::OnSessionReadData(int32_t fd, DataBuffer::Ptr buf)
65 {
66 SHARING_LOGI("%{public}s.", __FUNCTION__);
67 auto server = serverPtr_.lock();
68 if (server) {
69 auto session = sessionPtr_.lock();
70 if (session) {
71 server->OnServerReadData(fd, buf, session);
72 }
73 }
74 }
75
OnSessionWriteable(int32_t fd)76 void WfdSourceSession::WfdSourceNetworkSession::OnSessionWriteable(int32_t fd)
77 {
78 SHARING_LOGI("%{public}s.", __FUNCTION__);
79 }
80
OnSessionClose(int32_t fd)81 void WfdSourceSession::WfdSourceNetworkSession::OnSessionClose(int32_t fd)
82 {
83 SHARING_LOGI("%{public}s.", __FUNCTION__);
84 auto server = serverPtr_.lock();
85 if (server) {
86 auto statusMsg = std::make_shared<SessionStatusMsg>();
87 statusMsg->msg = std::make_shared<EventMsg>();
88 statusMsg->status = STATE_SESSION_ERROR;
89 statusMsg->msg->errorCode = ERR_NETWORK_ERROR;
90 server->NotifyAgentSessionStatus(statusMsg);
91 }
92 }
93
OnSessionException(int32_t fd)94 void WfdSourceSession::WfdSourceNetworkSession::OnSessionException(int32_t fd)
95 {
96 SHARING_LOGI("%{public}s.", __FUNCTION__);
97 auto server = serverPtr_.lock();
98 if (server) {
99 auto statusMsg = std::make_shared<SessionStatusMsg>();
100 statusMsg->msg = std::make_shared<EventMsg>();
101 statusMsg->status = STATE_SESSION_ERROR;
102 statusMsg->msg->errorCode = ERR_NETWORK_ERROR;
103 server->NotifyAgentSessionStatus(statusMsg);
104 }
105 }
106
OnSendKeepAlive() const107 void WfdSourceSession::WfdSourceNetworkSession::OnSendKeepAlive() const
108 {
109 SHARING_LOGI("%{public}s.", __FUNCTION__);
110 auto session = sessionPtr_.lock();
111 if (session) {
112 auto server = serverPtr_.lock();
113 if (server) {
114 server->SendM16Request(session);
115 }
116 }
117 }
118
WfdSourceSession()119 WfdSourceSession::WfdSourceSession()
120 {
121 SHARING_LOGI("%{public}s.", __FUNCTION__);
122 sysEvent_ = std::make_shared<SharingHiSysEvent>(BIZSceneType::WFD_SOURCE_PLAY, WFD_SOURCE);
123 std::stringstream ss;
124 ss << std::setw(8) << std::setfill('f') << (int64_t)this; // width:8
125 sessionID_ = ss.str();
126 }
127
~WfdSourceSession()128 WfdSourceSession::~WfdSourceSession()
129 {
130 SHARING_LOGI("%{public}s.", __FUNCTION__);
131 StopWfdSession();
132 }
133
NotifyServiceError()134 void WfdSourceSession::NotifyServiceError()
135 {
136 SHARING_LOGI("%{public}s.", __FUNCTION__);
137 auto statusMsg = std::make_shared<SessionStatusMsg>();
138 statusMsg->msg = std::make_shared<EventMsg>();
139 statusMsg->status = STATE_SESSION_ERROR;
140 statusMsg->msg->requestId = 0;
141 statusMsg->msg->errorCode = ERR_INTERACTION_FAILURE;
142
143 NotifyAgentSessionStatus(statusMsg);
144 }
145
UpdateOperation(SessionStatusMsg::Ptr & statusMsg)146 void WfdSourceSession::UpdateOperation(SessionStatusMsg::Ptr &statusMsg)
147 {
148 SHARING_LOGI("%{public}s.", __FUNCTION__);
149 RETURN_IF_NULL(statusMsg);
150 RETURN_IF_NULL(statusMsg->msg);
151
152 status_ = static_cast<SessionRunningStatus>(statusMsg->status);
153 SHARING_LOGI("status: %{public}s.", std::string(magic_enum::enum_name(status_)).c_str());
154 switch (status_) {
155 case SESSION_START:
156 if (!StartWfdSession()) {
157 SHARING_LOGE("session start connection failed, sessionId: %{public}u.", GetId());
158 statusMsg->msg->errorCode = ERR_CONNECTION_FAILURE;
159 statusMsg->status = STATE_SESSION_ERROR;
160 break;
161 } else {
162 return;
163 }
164 case SESSION_STOP:
165 statusMsg->status = STATE_SESSION_STOPED;
166 StopWfdSession();
167 break;
168 case SESSION_PAUSE:
169 statusMsg->status = STATE_SESSION_PAUSED;
170 break;
171 case SESSION_RESUME:
172 statusMsg->status = STATE_SESSION_RESUMED;
173 break;
174 case SESSION_DESTROY:
175 statusMsg->status = STATE_SESSION_DESTROYED;
176 break;
177 default:
178 SHARING_LOGI("none process case.");
179 break;
180 }
181
182 NotifyAgentSessionStatus(statusMsg);
183 }
184
UpdateMediaStatus(SessionStatusMsg::Ptr & statusMsg)185 void WfdSourceSession::UpdateMediaStatus(SessionStatusMsg::Ptr &statusMsg)
186 {
187 SHARING_LOGI("%{public}s.", __FUNCTION__);
188 RETURN_IF_NULL(statusMsg);
189 RETURN_IF_NULL(statusMsg->msg);
190
191 SHARING_LOGI("update media notify status: %{public}s.",
192 std::string(magic_enum::enum_name(static_cast<MediaNotifyStatus>(statusMsg->status))).c_str());
193 switch (statusMsg->status) {
194 case STATE_PROSUMER_CREATE_SUCCESS:
195 NotifyProsumerInit(statusMsg);
196 break;
197 case STATE_PROSUMER_START_SUCCESS:
198 break;
199 case STATE_PROSUMER_STOP_SUCCESS:
200 break;
201 case STATE_PROSUMER_DESTROY_SUCCESS:
202 break;
203 case STATE_PROSUMER_RESUME_SUCCESS:
204 break;
205 default:
206 SHARING_LOGI("none process case.");
207 break;
208 }
209 }
210
NotifyProsumerInit(SessionStatusMsg::Ptr & statusMsg)211 void WfdSourceSession::NotifyProsumerInit(SessionStatusMsg::Ptr &statusMsg)
212 {
213 SHARING_LOGI("%{public}s.", __FUNCTION__);
214 RETURN_IF_NULL(statusMsg);
215 RETURN_IF_NULL(statusMsg->msg);
216
217 auto eventMsg = std::make_shared<WfdProducerEventMsg>();
218 eventMsg->type = EventType::EVENT_WFD_MEDIA_INIT;
219 eventMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
220 eventMsg->port = sinkRtpPort_;
221 eventMsg->ip = sinkIp_;
222 eventMsg->localPort = sourceRtpPort_;
223 eventMsg->localIp = sourceIp_;
224 SHARING_LOGD("sinkRtpPort %{public}d, sinkIp %{public}s sourceRtpPort %{public}d.", sinkRtpPort_,
225 GetAnonyString(sinkIp_).c_str(), sourceRtpPort_);
226 statusMsg->msg = std::move(eventMsg);
227 statusMsg->status = NOTIFY_SESSION_PRIVATE_EVENT;
228
229 NotifyAgentSessionStatus(statusMsg);
230 }
231
HandleEvent(SharingEvent & event)232 int32_t WfdSourceSession::HandleEvent(SharingEvent &event)
233 {
234 SHARING_LOGI("%{public}s.", __FUNCTION__);
235 RETURN_INVALID_IF_NULL(event.eventMsg);
236 SHARING_LOGI("event: type: %{public}s, from: %{public}u, sessionId: %{public}u.",
237 std::string(magic_enum::enum_name(event.eventMsg->type)).c_str(), event.eventMsg->fromMgr, GetId());
238
239 switch (event.eventMsg->type) {
240 case EventType::EVENT_SESSION_INIT: {
241 HandleSessionInit(event);
242 break;
243 }
244 case EventType::EVENT_WFD_STATE_MEDIA_INIT: {
245 HandleProsumerInitState(event);
246 break;
247 }
248 case EventType::EVENT_AGENT_KEYMODE_STOP:
249 break;
250 case EventType::EVENT_SESSION_TEARDOWN:
251 break;
252 default:
253 break;
254 }
255 return 0;
256 }
257
NotifyAgentSessionStatus(SessionStatusMsg::Ptr & statusMsg)258 void WfdSourceSession::NotifyAgentSessionStatus(SessionStatusMsg::Ptr &statusMsg)
259 {
260 SHARING_LOGI("%{public}s.", __FUNCTION__);
261 RETURN_IF_NULL(statusMsg);
262 if (statusMsg->status == NOTIFY_PROSUMER_CREATE) {
263 statusMsg->className = "WfdRtpProducer";
264 }
265 Notify(statusMsg);
266 }
267
StartWfdSession()268 bool WfdSourceSession::StartWfdSession()
269 {
270 sysEvent_->ReportStart(__func__, BIZSceneStage::WFD_SOURCE_PLAY_TCP_SERVER);
271 SHARING_LOGI("%{public}s.", __FUNCTION__);
272 if (wfdDefaultPort_ > 0) {
273 if (!NetworkFactory::CreateTcpServer(wfdDefaultPort_, shared_from_this(), rtspServerPtr_, "")) {
274 SHARING_LOGE("start rtsp server [port:%{public}d] failed.", wfdDefaultPort_);
275 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_TCP_SERVER, BlzErrorCode::ERROR_FAIL);
276 return false;
277 }
278 }
279 SHARING_LOGD("start reveiver server success.");
280 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_TCP_SERVER, StageResType::STAGE_RES_SUCCESS);
281 return true;
282 }
283
StopWfdSession()284 bool WfdSourceSession::StopWfdSession()
285 {
286 SHARING_LOGI("%{public}s.", __FUNCTION__);
287 if (rtspServerPtr_) {
288 rtspServerPtr_->Stop();
289 rtspServerPtr_.reset();
290 }
291 return true;
292 }
293
HandleSessionInit(SharingEvent & event)294 void WfdSourceSession::HandleSessionInit(SharingEvent &event)
295 {
296 SHARING_LOGI("%{public}s.", __FUNCTION__);
297 auto inputMsg = ConvertEventMsg<WfdSourceSessionEventMsg>(event);
298 if (inputMsg) {
299 sinkAgentId_ = inputMsg->sinkAgentId;
300 sourceMac_ = inputMsg->mac;
301 sourceIp_ = inputMsg->ip;
302 sysEvent_->SetPeerMac(GetAnonyString(sourceMac_));
303 wfdDefaultPort_ = inputMsg->remotePort != 0 ? inputMsg->remotePort : DEFAULT_WFD_CTRLPORT;
304 sourceRtpPort_ = inputMsg->localPort;
305 videoFormat_ = inputMsg->videoFormat;
306 audioFormat_ = inputMsg->audioFormat;
307 SHARING_LOGD("sourceIp %s, sourceMac %s controlPort %d sourceRtpPort %d videoFormat %d audioFormat %d.",
308 GetAnonyString(sourceIp_).c_str(), GetAnonyString(sourceMac_).c_str(), wfdDefaultPort_,
309 sourceRtpPort_, videoFormat_, audioFormat_);
310 } else {
311 SHARING_LOGE("unknow event msg.");
312 }
313 }
314
HandleProsumerInitState(SharingEvent & event)315 void WfdSourceSession::HandleProsumerInitState(SharingEvent &event)
316 {
317 SHARING_LOGI("%{public}s.", __FUNCTION__);
318 RETURN_IF_NULL(event.eventMsg);
319
320 auto inputMsg = ConvertEventMsg<WfdSourceSessionEventMsg>(event);
321 auto statusMsg = std::make_shared<SessionStatusMsg>();
322 statusMsg->msg = std::make_shared<EventMsg>();
323 statusMsg->status = STATE_SESSION_ERROR;
324 statusMsg->msg->errorCode = ERR_SESSION_START;
325
326 if (inputMsg) {
327 statusMsg->msg->requestId = inputMsg->requestId;
328 if (inputMsg->errorCode == ERR_OK) {
329 statusMsg->status = STATE_SESSION_STARTED;
330 statusMsg->msg->errorCode = ERR_OK;
331 } else {
332 SHARING_LOGE("producer inited failed, producerId: %{public}u.", inputMsg->prosumerId);
333 }
334 } else {
335 SHARING_LOGE("producer inited failed: unknow msg.");
336 return;
337 }
338
339 NotifyAgentSessionStatus(statusMsg);
340 }
341
OnAccept(std::weak_ptr<INetworkSession> session)342 void WfdSourceSession::OnAccept(std::weak_ptr<INetworkSession> session)
343 {
344 SHARING_LOGI("%{public}s.", __FUNCTION__);
345 auto sessionPtr = session.lock();
346 if (sessionPtr) {
347 rtspServerFd_ = sessionPtr->GetSocketInfo()->GetPeerFd();
348 sourceIp_ = sessionPtr->GetSocketInfo()->GetLocalIp();
349 sinkIp_ = sessionPtr->GetSocketInfo()->GetPeerIp();
350 SHARING_LOGD("primarySinkIp %s ,sourceIp %s.", GetAnonyString(sinkIp_).c_str(),
351 GetAnonyString(sourceIp_).c_str());
352 auto sa = std::make_shared<WfdSourceNetworkSession>(session, shared_from_this());
353 sessionPtr->RegisterCallback(std::move(sa));
354 sessionPtr->Start();
355 if (!SendM1Request(sessionPtr)) {
356 SHARING_LOGE("WFD source SendM1Request error.");
357 }
358 }
359 }
360
OnServerReadData(int32_t fd,DataBuffer::Ptr buf,INetworkSession::Ptr session)361 void WfdSourceSession::OnServerReadData(int32_t fd, DataBuffer::Ptr buf, INetworkSession::Ptr session)
362 {
363 if (rtspServerFd_ != fd || session == nullptr) {
364 SHARING_LOGW("OnServerReadData rtspServerFd_: %{public}d, fd: %{public}d.", rtspServerFd_, fd);
365 return;
366 }
367
368 RtspResponse response;
369 RtspRequest request;
370 std::string message(buf->Peek(), buf->Size());
371 SHARING_LOGD("sessionId: %{public}u, Recv WFD sink message:\n%{public}s", GetId(), message.c_str());
372 auto ret = response.Parse(message);
373 if (ret.code == RtspErrorType::OK) {
374 SHARING_LOGD("Recv RTSP Response message.");
375 HandleResponse(response, message, session);
376
377 if (ret.info.size() > 2 && ret.info.back() == '$') { // size at least bigger than 2
378 ret.info.pop_back();
379 SHARING_LOGW("packet splicing need parse again\n%{public}s.", ret.info.c_str());
380 ret = request.Parse(ret.info);
381 if (ret.code == RtspErrorType::OK) {
382 SHARING_LOGD("Recv RTSP Request [method:%{public}s] message.", request.GetMethod().c_str());
383 HandleRequest(request, session);
384 return;
385 }
386 }
387 return;
388 }
389
390 ret = request.Parse(message);
391 if (ret.code == RtspErrorType::OK) {
392 SHARING_LOGD("Recv RTSP Request [method:%{public}s] message.", request.GetMethod().c_str());
393 HandleRequest(request, session);
394 return;
395 }
396
397 SHARING_LOGD("invalid WFD rtsp message.");
398 if (ret.code == RtspErrorType::INCOMPLETE_MESSAGE) {
399 lastMessage_ = message;
400 SHARING_LOGD("return with '%{public}s'.", ret.info.c_str());
401 return;
402 } else {
403 message = lastMessage_ + message;
404 ret = request.Parse(message);
405 if (ret.code == RtspErrorType::OK) {
406 SHARING_LOGD("spliced the Request message Successfully.");
407 HandleRequest(request, session);
408 return;
409 } else {
410 lastMessage_.clear();
411 return;
412 }
413 }
414 }
415
HandleRequest(const RtspRequest & request,INetworkSession::Ptr & session)416 bool WfdSourceSession::HandleRequest(const RtspRequest &request, INetworkSession::Ptr &session)
417 {
418 SHARING_LOGI("%{public}s.", __FUNCTION__);
419 if (!lastMessage_.empty()) {
420 lastMessage_.clear();
421 }
422
423 int incomingCSeq = request.GetCSeq();
424 if (request.GetMethod() == RTSP_METHOD_OPTIONS) { // M2
425 return HandleOptionRequest(request, incomingCSeq, session);
426 } else if (request.GetMethod() == RTSP_METHOD_SETUP) { // M6
427 return HandleSetupRequest(request, incomingCSeq, session);
428 } else if (request.GetMethod() == RTSP_METHOD_PLAY) { // M7
429 return HandlePlayRequest(request, incomingCSeq, session);
430 } else if (request.GetMethod() == RTSP_METHOD_PAUSE) {
431 return HandlePauseRequest(request, incomingCSeq, session);
432 } else if (request.GetMethod() == RTSP_METHOD_TEARDOWN) {
433 return HandleTeardownRequest(request, incomingCSeq, session);
434 } else if (request.GetMethod() == RTSP_METHOD_SET_PARAMETER) {
435 return HandleIDRRequest(request, incomingCSeq, session);
436 } else {
437 SHARING_LOGE("RTSP Request [method:%{public}s] message shouldn't be here.", request.GetMethod().c_str());
438 }
439 return true;
440 }
441
HandleIDRRequest(const RtspRequest & request,int32_t cseq,INetworkSession::Ptr & session)442 bool WfdSourceSession::HandleIDRRequest(const RtspRequest &request, int32_t cseq, INetworkSession::Ptr &session)
443 {
444 SHARING_LOGI("%{public}s.", __FUNCTION__);
445 if (request.GetSession() == sessionID_) {
446 std::list<std::string> params = request.GetBody();
447 for (auto ¶m : params) {
448 if (param == WFD_PARAM_IDR_REQUEST) {
449 SHARING_LOGD("receive idr request.");
450 return SendCommonResponse(cseq, session);
451 }
452 }
453 }
454 return true;
455 }
456
HandleOptionRequest(const RtspRequest & request,int32_t cseq,INetworkSession::Ptr & session)457 bool WfdSourceSession::HandleOptionRequest(const RtspRequest &request, int32_t cseq, INetworkSession::Ptr &session)
458 {
459 SHARING_LOGI("%{public}s.", __FUNCTION__);
460 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M2_REQ);
461 if (SendM2Response(cseq, session)) {
462 if (SendM3Request(session)) {
463 return true;
464 }
465 }
466 return false;
467 }
468
HandleSetupRequest(const RtspRequest & request,int32_t cseq,INetworkSession::Ptr & session)469 bool WfdSourceSession::HandleSetupRequest(const RtspRequest &request, int32_t cseq, INetworkSession::Ptr &session)
470 {
471 SHARING_LOGI("%{public}s.", __FUNCTION__);
472 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M6_REQ);
473 return SendM6Response(session, cseq);
474 }
475
HandlePlayRequest(const RtspRequest & request,int32_t cseq,INetworkSession::Ptr & session)476 bool WfdSourceSession::HandlePlayRequest(const RtspRequest &request, int32_t cseq, INetworkSession::Ptr &session)
477 {
478 SHARING_LOGI("%{public}s.", __FUNCTION__);
479 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M7_REQ);
480 auto statusMsg = std::make_shared<SessionStatusMsg>();
481 auto eventMsg = std::make_shared<ScreenCaptureSessionEventMsg>();
482 eventMsg->agentId = sinkAgentId_;
483 eventMsg->codecId = wfdAudioCodec_.codecId;
484 eventMsg->audioFormat = wfdAudioCodec_.format;
485 statusMsg->msg = std::move(eventMsg);
486 statusMsg->msg->type = EVENT_WFD_NOTIFY_RTSP_PLAYED;
487 statusMsg->msg->requestId = 0;
488 statusMsg->msg->errorCode = ERR_OK;
489 statusMsg->msg->toMgr = MODULE_CONTEXT;
490 statusMsg->status = NOTIFY_SESSION_PRIVATE_EVENT;
491 if (prosumerState_ == ERR_PROSUMER_PAUSE) {
492 prosumerState_ = ERR_PROSUMER_RESUME;
493 } else {
494 if (session != nullptr) {
495 auto sa = session->GetCallback();
496 std::shared_ptr<WfdSourceNetworkSession> agent = std::static_pointer_cast<WfdSourceNetworkSession>(sa);
497 if (agent != nullptr) {
498 agent->SetKeepAliveTimer();
499 }
500 }
501 prosumerState_ = ERR_PROSUMER_START;
502 }
503 NotifyAgentSessionStatus(statusMsg);
504 return SendM7Response(session, cseq);
505 }
506
HandlePauseRequest(const RtspRequest & request,int32_t cseq,INetworkSession::Ptr & session)507 bool WfdSourceSession::HandlePauseRequest(const RtspRequest &request, int32_t cseq, INetworkSession::Ptr &session)
508 {
509 SHARING_LOGI("%{public}s.", __FUNCTION__);
510 auto statusMsg = std::make_shared<SessionStatusMsg>();
511 statusMsg->msg = std::make_shared<EventMsg>();
512 prosumerState_ = ERR_PROSUMER_PAUSE;
513 statusMsg->status = NOTIFY_PROSUMER_PAUSE;
514 statusMsg->msg->errorCode = ERR_PROSUMER_PAUSE;
515 prosumerState_ = ERR_PROSUMER_START;
516 NotifyAgentSessionStatus(statusMsg);
517 return SendCommonResponse(cseq, session);
518 }
519
HandleTeardownRequest(const RtspRequest & request,int32_t cseq,INetworkSession::Ptr & session)520 bool WfdSourceSession::HandleTeardownRequest(const RtspRequest &request, int32_t cseq, INetworkSession::Ptr &session)
521 {
522 SHARING_LOGI("%{public}s.", __FUNCTION__);
523 auto statusMsg = std::make_shared<SessionStatusMsg>();
524 statusMsg->msg = std::make_shared<EventMsg>();
525 statusMsg->status = NOTIFY_PROSUMER_DESTROY;
526 statusMsg->msg->errorCode = ERR_PROSUMER_DESTROY;
527 NotifyAgentSessionStatus(statusMsg);
528 prosumerState_ = ERR_PROSUMER_STOP;
529 if (session != nullptr) {
530 auto sa = session->GetCallback();
531 std::shared_ptr<WfdSourceNetworkSession> agent = std::static_pointer_cast<WfdSourceNetworkSession>(sa);
532 if (agent != nullptr) {
533 agent->UnsetKeepAliveTimer();
534 }
535 }
536 return SendCommonResponse(cseq, session);
537 }
538
HandleResponse(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)539 bool WfdSourceSession::HandleResponse(const RtspResponse &response, const std::string &message,
540 INetworkSession::Ptr &session)
541 {
542 SHARING_LOGD("sessionID %{public}s.", response.GetSession().c_str());
543 if (!lastMessage_.empty()) {
544 lastMessage_.clear();
545 }
546
547 if (response.GetCSeq() != cseq_) {
548 SHARING_LOGE("sessionId: %{public}u, response CSeq(%{public}d) does not match expected CSeq(%{public}d).",
549 GetId(), response.GetCSeq(), cseq_);
550 return false;
551 }
552 if (wfdState_ >= WfdSessionState::M7) {
553 rtspTimeoutCounts_ = MAX_RTSP_TIMEOUT_COUNTS;
554 }
555 switch (wfdState_) {
556 case WfdSessionState::M1:
557 return HandleM1Response(response, message, session);
558 case WfdSessionState::M3:
559 return HandleM3Response(response, message, session);
560 case WfdSessionState::M4:
561 return HandleM4Response(response, message, session);
562 case WfdSessionState::M5:
563 return HandleM5Response(response, message, session);
564 case WfdSessionState::M7_WAIT:
565 return HandleM7Response(response, message, session);
566 case WfdSessionState::M8:
567 return HandleM8Response(response, message, session);
568 default:
569 break;
570 }
571 return true;
572 }
573
HandleM1Response(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)574 bool WfdSourceSession::HandleM1Response(const RtspResponse &response, const std::string &message,
575 INetworkSession::Ptr &session)
576 {
577 SHARING_LOGI("%{public}s.", __FUNCTION__);
578 (void)message;
579 (void)session;
580 if (response.GetStatus() != RTSP_STATUS_OK) {
581 SHARING_LOGE("WFD source peer handle 'OPTIONS' method error.");
582 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M1_RSP, BlzErrorCode::ERROR_FAIL);
583 return false;
584 }
585
586 std::string publics = response.GetToken(RTSP_TOKEN_PUBLIC);
587 if (publics.empty() || publics.find(RTSP_METHOD_WFD) == std::string::npos ||
588 publics.find(RTSP_METHOD_SET_PARAMETER) == std::string::npos ||
589 publics.find(RTSP_METHOD_GET_PARAMETER) == std::string::npos) {
590 SHARING_LOGE("WFD source peer do not support all methods.");
591 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M1_RSP, BlzErrorCode::ERROR_FAIL);
592 return false;
593 }
594 SHARING_LOGI("WFD RTSP M1 response ok.");
595 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M1_RSP);
596 return true;
597 }
598
HandleM3Response(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)599 bool WfdSourceSession::HandleM3Response(const RtspResponse &response, const std::string &message,
600 INetworkSession::Ptr &session)
601 {
602 SHARING_LOGI("%{public}s.", __FUNCTION__);
603 (void)message;
604 if (response.GetStatus() != RTSP_STATUS_OK) {
605 SHARING_LOGE("WFD source peer handle 'SETUP' method error.");
606 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M3_RSP, BlzErrorCode::ERROR_FAIL);
607 return false;
608 }
609
610 WfdRtspM3Response m3Res;
611 auto ret = m3Res.Parse(message);
612 if (ret.code == RtspErrorType::OK) {
613 sinkRtpPort_ = m3Res.GetClientRtpPorts();
614 audioFormat_ = m3Res.GetAudioCodecs(wfdAudioCodec_);
615 videoFormat_ = m3Res.GetVideoFormats();
616 wfdVideoFormatsInfo_ = m3Res.GetWfdVideoFormatsInfo();
617 SHARING_LOGD("sinkRtpPort:%{public}d, audioFormat:%{public}d, audioCodec:%{public}d, videoFormat:%{public}d.",
618 sinkRtpPort_, wfdAudioCodec_.format, wfdAudioCodec_.codecId, videoFormat_);
619 std::string value = m3Res.GetContentProtection();
620 if (value == "" || value == "none") {
621 SHARING_LOGE("WFD sink doesn't support hdcp.");
622 }
623 if (!SendM4Request(session)) {
624 SHARING_LOGE("send m4 request error.");
625 return false;
626 }
627 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M3_RSP);
628 return true;
629 }
630 SHARING_LOGE("WFD source parse 'SETUP' message error.");
631 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M3_RSP, BlzErrorCode::ERROR_FAIL);
632 return false;
633 }
634
HandleM4Response(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)635 bool WfdSourceSession::HandleM4Response(const RtspResponse &response, const std::string &message,
636 INetworkSession::Ptr &session)
637 {
638 SHARING_LOGI("%{public}s.", __FUNCTION__);
639 (void)message;
640 if (response.GetStatus() != RTSP_STATUS_OK) {
641 SHARING_LOGE("WFD source peer handle 'SETUP' method error.");
642 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M4_RSP, BlzErrorCode::ERROR_FAIL);
643 return false;
644 }
645
646 WfdRtspM4Response m4Res;
647 auto ret = m4Res.Parse(message);
648 if (ret.code == RtspErrorType::OK) {
649 if (!SendM5Request(session)) {
650 SHARING_LOGE("send m5 request error.");
651 return false;
652 }
653 SessionStatusMsg::Ptr statusMsg = std::make_shared<SessionStatusMsg>();
654 statusMsg->msg = std::make_shared<EventMsg>();
655 statusMsg->msg->requestId = 0;
656 statusMsg->msg->errorCode = ERR_OK;
657 statusMsg->status = NOTIFY_PROSUMER_CREATE;
658
659 NotifyAgentSessionStatus(statusMsg);
660 }
661 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M4_RSP);
662 return true;
663 }
664
HandleM5Response(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)665 bool WfdSourceSession::HandleM5Response(const RtspResponse &response, const std::string &message,
666 INetworkSession::Ptr &session)
667 {
668 SHARING_LOGI("%{public}s.", __FUNCTION__);
669 (void)message;
670 (void)session;
671 if (response.GetStatus() != RTSP_STATUS_OK) {
672 SHARING_LOGE("WFD source peer handle 'SETUP' method error.");
673 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M5_RSP, BlzErrorCode::ERROR_FAIL);
674 return false;
675 }
676
677 WfdRtspM5Response m5Res;
678 auto ret = m5Res.Parse(message);
679 if (ret.code != RtspErrorType::OK) {
680 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M5_RSP, BlzErrorCode::ERROR_FAIL);
681 return false;
682 }
683 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_RECV_M5_RSP);
684 return true;
685 }
686
HandleM7Response(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)687 bool WfdSourceSession::HandleM7Response(const RtspResponse &response, const std::string &message,
688 INetworkSession::Ptr &session)
689 {
690 SHARING_LOGI("%{public}s.", __FUNCTION__);
691 (void)message;
692 (void)session;
693 if (response.GetStatus() != RTSP_STATUS_OK) {
694 SHARING_LOGE("WFD source peer handle 'PLAY' method error.");
695 wfdState_ = WfdSessionState::M6;
696 return false;
697 } else {
698 SHARING_LOGI("WFD RTSP PLAY ok, start receiver to recv the stream.");
699 wfdState_ = WfdSessionState::M7;
700 }
701
702 SHARING_LOGI("WFD RTSP PLAY ok, start receiver to recv the stream.");
703 return true;
704 }
705
HandleM8Response(const RtspResponse & response,const std::string & message,INetworkSession::Ptr & session)706 bool WfdSourceSession::HandleM8Response(const RtspResponse &response, const std::string &message,
707 INetworkSession::Ptr &session)
708 {
709 SHARING_LOGI("%{public}s.", __FUNCTION__);
710 (void)message;
711 (void)session;
712 if (response.GetStatus() != RTSP_STATUS_OK) {
713 SHARING_LOGE("WFD source peer handle 'TEARDOWN' method error.");
714 return false;
715 }
716
717 // notify wfd scene rtsp teardown
718 auto statusMsg = std::make_shared<SessionStatusMsg>();
719 auto eventMsg = std::make_shared<WfdSceneEventMsg>();
720 eventMsg->type = EventType::EVENT_WFD_NOTIFY_RTSP_TEARDOWN;
721 eventMsg->toMgr = ModuleType::MODULE_INTERACTION;
722 eventMsg->mac = sourceMac_;
723 statusMsg->msg = std::move(eventMsg);
724 statusMsg->status = NOTIFY_SESSION_PRIVATE_EVENT;
725 NotifyAgentSessionStatus(statusMsg);
726 SHARING_LOGI("WFD RTSP TEARDOWN ok, stop recv the stream, disconnect socket.");
727 return true;
728 }
729
SendM1Request(INetworkSession::Ptr & session)730 bool WfdSourceSession::SendM1Request(INetworkSession::Ptr &session)
731 {
732 SHARING_LOGI("%{public}s.", __FUNCTION__);
733 if (!rtspServerPtr_ || !session) {
734 return false;
735 }
736 WfdRtspM1Request m1Request(++cseq_);
737 std::string m1Req(m1Request.Stringify());
738 SHARING_LOGD("%{public}s.", m1Req.c_str());
739
740 bool ret = session->Send(m1Req.c_str(), m1Req.size());
741 if (!ret) {
742 SHARING_LOGE("Failed to send M1 request.");
743 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M1_REQ, BlzErrorCode::ERROR_FAIL);
744 return false;
745 }
746 wfdState_ = WfdSessionState::M1;
747 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M1_REQ, StageResType::STAGE_RES_SUCCESS);
748 return ret;
749 }
750
SendM2Response(int32_t cseq,INetworkSession::Ptr & session)751 bool WfdSourceSession::SendM2Response(int32_t cseq, INetworkSession::Ptr &session)
752 {
753 SHARING_LOGI("%{public}s.", __FUNCTION__);
754 if (!rtspServerPtr_ || !session) {
755 return false;
756 }
757 WfdRtspM2Response m2Response(cseq, RTSP_STATUS_OK);
758 std::string m2Res(m2Response.Stringify());
759 SHARING_LOGD("%{public}s.", m2Res.c_str());
760
761 bool ret = session->Send(m2Res.c_str(), m2Res.size());
762 if (!ret) {
763 SHARING_LOGE("Failed to send M2 response.");
764 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M2_RSP, BlzErrorCode::ERROR_FAIL);
765 return false;
766 }
767 wfdState_ = WfdSessionState::M2;
768 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M2_RSP, StageResType::STAGE_RES_SUCCESS);
769 return ret;
770 }
771
SendM3Request(INetworkSession::Ptr & session)772 bool WfdSourceSession::SendM3Request(INetworkSession::Ptr &session)
773 {
774 SHARING_LOGI("%{public}s.", __FUNCTION__);
775 if (!rtspServerPtr_ || !session) {
776 return false;
777 }
778 WfdRtspM3Request m3Request(++cseq_, WFD_RTSP_URL_DEFAULT);
779 std::string m3Req(m3Request.Stringify());
780 SHARING_LOGD("%{public}s.", m3Req.c_str());
781
782 bool ret = session->Send(m3Req.c_str(), m3Req.size());
783 if (!ret) {
784 SHARING_LOGE("Failed to send M3 request.");
785 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M3_REQ, BlzErrorCode::ERROR_FAIL);
786 return false;
787 }
788 wfdState_ = WfdSessionState::M3;
789 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M3_REQ, StageResType::STAGE_RES_SUCCESS);
790 return ret;
791 }
792
SendM4Request(INetworkSession::Ptr & session)793 bool WfdSourceSession::SendM4Request(INetworkSession::Ptr &session)
794 {
795 SHARING_LOGI("%{public}s.", __FUNCTION__);
796 if (!rtspServerPtr_ || !session) {
797 return false;
798 }
799
800 WfdRtspM4Request m4Request(++cseq_, WFD_RTSP_URL_DEFAULT);
801 m4Request.SetPresentationUrl(sourceIp_);
802 m4Request.SetVideoFormats(wfdVideoFormatsInfo_, videoFormat_);
803 m4Request.SetAudioCodecs(wfdAudioCodec_);
804 m4Request.SetClientRtpPorts(sinkRtpPort_);
805 std::string m4Req(m4Request.Stringify());
806 SHARING_LOGD("%{public}s.", m4Req.c_str());
807
808 bool ret = session->Send(m4Req.c_str(), m4Req.size());
809 if (!ret) {
810 SHARING_LOGE("Failed to send M4 request.");
811 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M4_REQ, BlzErrorCode::ERROR_FAIL);
812 return false;
813 }
814 wfdState_ = WfdSessionState::M4;
815 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M4_REQ, StageResType::STAGE_RES_SUCCESS);
816 return ret;
817 }
818
SendM5Request(INetworkSession::Ptr & session)819 bool WfdSourceSession::SendM5Request(INetworkSession::Ptr &session)
820 {
821 SHARING_LOGI("%{public}s.", __FUNCTION__);
822 if (!rtspServerPtr_ || !session) {
823 return false;
824 }
825 WfdRtspM5Request m5Request(++cseq_);
826 m5Request.SetTriggerMethod(RTSP_METHOD_SETUP);
827 std::string m5Req(m5Request.Stringify());
828 SHARING_LOGD("%{public}s.", m5Req.c_str());
829
830 bool ret = session->Send(m5Req.c_str(), m5Req.size());
831 if (!ret) {
832 SHARING_LOGE("Failed to send M5 request.");
833 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M5_REQ, BlzErrorCode::ERROR_FAIL);
834 return false;
835 }
836 wfdState_ = WfdSessionState::M5;
837 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M5_REQ, StageResType::STAGE_RES_SUCCESS);
838 return ret;
839 }
840
SendM6Response(INetworkSession::Ptr & session,int32_t cseq)841 bool WfdSourceSession::SendM6Response(INetworkSession::Ptr &session, int32_t cseq)
842 {
843 SHARING_LOGI("%{public}s.", __FUNCTION__);
844 if (!rtspServerPtr_ || !session) {
845 return false;
846 }
847 WfdRtspM6Response m6Response(cseq, RTSP_STATUS_OK, sessionID_, rtspTimeout_);
848 m6Response.SetClientPort(sinkRtpPort_);
849 m6Response.SetServerPort(sourceRtpPort_);
850 std::string m6Res(m6Response.StringifyEx());
851 SHARING_LOGD("%{public}s.", m6Res.c_str());
852
853 bool ret = session->Send(m6Res.c_str(), m6Res.size());
854 if (!ret) {
855 SHARING_LOGE("Failed to send M6 response.");
856 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M6_RSP, BlzErrorCode::ERROR_FAIL);
857 }
858 wfdState_ = WfdSessionState::M7_WAIT;
859 sysEvent_->Report(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M6_RSP, StageResType::STAGE_RES_SUCCESS);
860 return ret;
861 }
862
SendM7Response(INetworkSession::Ptr & session,int32_t cseq)863 bool WfdSourceSession::SendM7Response(INetworkSession::Ptr &session, int32_t cseq)
864 {
865 SHARING_LOGI("%{public}s.", __FUNCTION__);
866 if (!rtspServerPtr_ || !session) {
867 return false;
868 }
869 WfdRtspM7Response m7Response(cseq, RTSP_STATUS_OK, sessionID_);
870 m7Response.SetSession(sessionID_);
871 m7Response.SetTimeout(rtspTimeout_);
872 std::string m7Res(m7Response.StringifyEx());
873 SHARING_LOGD("%{public}s.", m7Res.c_str());
874
875 bool ret = session->Send(m7Res.c_str(), m7Res.size());
876 if (!ret) {
877 SHARING_LOGE("Failed to send M7 response.");
878 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M7_RSP, BlzErrorCode::ERROR_FAIL);
879 }
880 wfdState_ = WfdSessionState::M7;
881 sysEvent_->ReportEnd(__func__, BIZSceneStage::WFD_SOURCE_PLAY_SEND_M7_RSP);
882 return ret;
883 }
884
SendM8Response(INetworkSession::Ptr & session,int32_t cseq)885 bool WfdSourceSession::SendM8Response(INetworkSession::Ptr &session, int32_t cseq)
886 {
887 SHARING_LOGI("%{public}s.", __FUNCTION__);
888 if (!rtspServerPtr_ || !session) {
889 return false;
890 }
891 WfdRtspM8Response m8Response(cseq, RTSP_STATUS_OK);
892 m8Response.SetSession(sessionID_);
893 std::string m8Res(m8Response.Stringify());
894 SHARING_LOGD("%{public}s.", m8Res.c_str());
895
896 bool ret = session->Send(m8Res.c_str(), m8Res.size());
897 if (!ret) {
898 SHARING_LOGE("Failed to send M8 response.");
899 }
900 wfdState_ = WfdSessionState::M8;
901 return ret;
902 }
903
SendCommonResponse(int32_t cseq,INetworkSession::Ptr & session)904 bool WfdSourceSession::SendCommonResponse(int32_t cseq, INetworkSession::Ptr &session)
905 {
906 SHARING_LOGI("%{public}s.", __FUNCTION__);
907 if (!rtspServerPtr_ || !session) {
908 return false;
909 }
910 RtspResponse m4Response(cseq, RTSP_STATUS_OK);
911 m4Response.SetSession(sessionID_);
912 std::string m4Res(m4Response.Stringify());
913 SHARING_LOGD("%{public}s.", m4Res.c_str());
914
915 bool ret = session->Send(m4Res.c_str(), m4Res.size());
916 if (!ret) {
917 SHARING_LOGE("Failed to send M4 response.");
918 }
919 return ret;
920 }
921
SendM16Request(INetworkSession::Ptr & session)922 bool WfdSourceSession::SendM16Request(INetworkSession::Ptr &session)
923 {
924 SHARING_LOGI("%{public}s.", __FUNCTION__);
925 if (rtspTimeoutCounts_ <= 0) {
926 NotifyServiceError();
927 return false;
928 }
929
930 if (!rtspServerPtr_ || !session) {
931 return false;
932 }
933 WfdRtspM16Request m16Request(++cseq_, WFD_RTSP_URL_DEFAULT, sessionID_);
934 std::string m16Req(m16Request.Stringify());
935 SHARING_LOGD("%{public}s.", m16Req.c_str());
936
937 bool ret = session->Send(m16Req.c_str(), m16Req.size());
938 if (!ret) {
939 SHARING_LOGE("Failed to send M16 request.");
940 }
941 rtspTimeoutCounts_--;
942 return ret;
943 }
944
945 REGISTER_CLASS_REFLECTOR(WfdSourceSession);
946 } // namespace Sharing
947 } // namespace OHOS
948