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