• 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 "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 &param : 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