• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "wfd_source_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 &param : 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