diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index 44448aa91b..54873a24ed 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -68,7 +68,7 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) { output = o; - session = "O9EaZ4bf"; // TODO: FIXME: generate session id. + session = ""; video_rtp = NULL; audio_rtp = NULL; @@ -118,7 +118,9 @@ int SrsRtspConn::do_cycle() srs_info("rtsp: got rtsp request"); if (req->is_options()) { - if ((ret = rtsp->send_message(new SrsRtspOptionsResponse(req->seq))) != ERROR_SUCCESS) { + SrsRtspOptionsResponse* res = new SrsRtspOptionsResponse(req->seq); + res->session = session; + if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("rtsp: send OPTIONS response failed. ret=%d", ret); } @@ -136,7 +138,10 @@ int SrsRtspConn::do_cycle() req->sdp->audio_stream_id.c_str(), req->sdp->audio_codec.c_str(), req->sdp->audio_sample_rate.c_str(), req->sdp->audio_channel.c_str() ); - if ((ret = rtsp->send_message(new SrsRtspResponse(req->seq))) != ERROR_SUCCESS) { + + SrsRtspResponse* res = new SrsRtspResponse(req->seq); + res->session = session; + if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("rtsp: send ANNOUNCE response failed. ret=%d", ret); } @@ -164,6 +169,11 @@ int SrsRtspConn::do_cycle() } srs_trace("rtsp: rtp listen at port=%d ok.", lpm); + // create session. + if (session.empty()) { + session = "O9EaZ4bf"; // TODO: FIXME: generate session id. + } + SrsRtspSetupResponse* res = new SrsRtspSetupResponse(req->seq); res->client_port_min = req->transport->client_port_min; res->client_port_max = req->transport->client_port_max; @@ -176,6 +186,15 @@ int SrsRtspConn::do_cycle() } return ret; } + } else if (req->is_record()) { + SrsRtspResponse* res = new SrsRtspResponse(req->seq); + res->session = session; + if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { + if (!srs_is_client_gracefully_close(ret)) { + srs_error("rtsp: send SETUP response failed. ret=%d", ret); + } + return ret; + } } } diff --git a/trunk/src/protocol/srs_rtsp_stack.cpp b/trunk/src/protocol/srs_rtsp_stack.cpp index f6709a280e..10a96dcd76 100644 --- a/trunk/src/protocol/srs_rtsp_stack.cpp +++ b/trunk/src/protocol/srs_rtsp_stack.cpp @@ -486,6 +486,11 @@ bool SrsRtspRequest::is_setup() return method == __SRS_METHOD_SETUP; } +bool SrsRtspRequest::is_record() +{ + return method == __SRS_METHOD_RECORD; +} + SrsRtspResponse::SrsRtspResponse(int cseq) { seq = cseq; @@ -513,6 +518,11 @@ int SrsRtspResponse::encode(stringstream& ss) << "Pragma: no-cache" << __SRS_RTSP_CRLF << "Server: " << RTMP_SIG_SRS_SERVER << __SRS_RTSP_CRLF; + // session if specified. + if (!session.empty()) { + ss << __SRS_TOKEN_SESSION << ":" << session << __SRS_RTSP_CRLF; + } + if ((ret = encode_header(ss)) != ERROR_SUCCESS) { srs_error("rtsp: encode header failed. ret=%d", ret); return ret; @@ -730,6 +740,13 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) srs_error("rtsp: parse transport failed, transport=%s. ret=%d", transport.c_str(), ret); return ret; } + } else if (token == __SRS_TOKEN_SESSION) { + if ((ret = recv_token_eof(req->session)) != ERROR_SUCCESS) { + if (!srs_is_client_gracefully_close(ret)) { + srs_error("rtsp: parse %s failed. ret=%d", __SRS_TOKEN_SESSION, ret); + } + return ret; + } } else { // unknown header name, parse util EOF. SrsRtspTokenState state = SrsRtspTokenStateNormal; diff --git a/trunk/src/protocol/srs_rtsp_stack.hpp b/trunk/src/protocol/srs_rtsp_stack.hpp index f0eedf3cc8..716486abb2 100644 --- a/trunk/src/protocol/srs_rtsp_stack.hpp +++ b/trunk/src/protocol/srs_rtsp_stack.hpp @@ -337,6 +337,10 @@ class SrsRtspRequest * assumed. It is interpreted according to [H14.14]. */ long content_length; + /** + * the session id. + */ + std::string session; /** * the sdp in announce, NULL for no sdp. @@ -357,6 +361,7 @@ class SrsRtspRequest virtual bool is_options(); virtual bool is_announce(); virtual bool is_setup(); + virtual bool is_record(); }; /** @@ -401,6 +406,10 @@ class SrsRtspResponse * for retransmissions of the same request). */ long seq; + /** + * the session id. + */ + std::string session; public: SrsRtspResponse(int cseq); virtual ~SrsRtspResponse();