// RFC2326 10.6 PAUSE (p36)
// 1. A PAUSE request discards all queued PLAY requests. However, the pause
//	  point in the media stream MUST be maintained. A subsequent PLAY
//	  request without Range header resumes from the pause point.
int rtsp_server_pause(struct rtsp_server_t* rtsp, const char* uri)
{
	int64_t npt = -1L;
	const char *prange, *psession;
	struct rtsp_header_range_t range;

	prange = rtsp_get_header_by_name(rtsp->parser, "range");
	psession = rtsp_get_header_by_name(rtsp->parser, "Session");

	rtsp->session.session[0] = 0; // clear session value
	if (!psession || 0 != rtsp_header_session(psession, &rtsp->session))
	{
		// 454 Session Not Found
		return rtsp_server_reply(rtsp, 454);
	}

	if (prange && 0 == rtsp_header_range(prange, &range))
	{
		npt = range.from;
		// 10.6 The normal play time for the stream is set to the pause point. (p36)
		assert(range.type == RTSP_RANGE_NPT); // 3.6 Normal Play Time (p17)
		assert(range.to_value == RTSP_RANGE_TIME_NOVALUE);

		// 457 Invalid Range
		//rtsp_server_reply(req, 457, NULL);
		//return;
	}

	return rtsp->handler.onpause(rtsp->param, rtsp, uri, rtsp->session.session, -1L == npt ? NULL : &npt);
}
Beispiel #2
0
// RFC2326 10.6 PAUSE (p36)
// 1. A PAUSE request discards all queued PLAY requests. However, the pause
//	  point in the media stream MUST be maintained. A subsequent PLAY
//	  request without Range header resumes from the pause point.
static void rtsp_server_pause(struct rtsp_server_request_t *req, void* parser, const char* uri)
{
	int64_t npt = -1L;
	const char *prange, *psession;
	struct rtsp_header_range_t range;
	struct rtsp_header_session_t session;
	struct rtsp_server_context_t* ctx = req->server;

	prange = rtsp_get_header_by_name(parser, "range");
	psession = rtsp_get_header_by_name(parser, "Session");

	if(!psession || 0 != rtsp_header_session(psession, &session))
	{
		// 454 Session Not Found
		rtsp_server_reply(req, 454);
		return;
	}

	if(prange && 0 == rtsp_header_range(prange, &range))
	{
		npt = range.from;
		// 10.6 The normal play time for the stream is set to the pause point. (p36)
		assert(range.type == RTSP_RANGE_NPT); // 3.6 Normal Play Time (p17)
		assert(range.to_value == RTSP_RANGE_TIME_NOVALUE);

		// 457 Invalid Range
		//rtsp_server_reply(req, 457);
		//return;
	}

	ctx->handler.pause(ctx->ptr, req, uri, session.session, -1L==npt?NULL:&npt);
}
Beispiel #3
0
static void rtsp_server_play(struct rtsp_server_request_t *req, void* parser, const char* uri)
{
	int64_t npt = -1L;
	double scale = 0.0f;
	const char *pscale, *prange, *psession;
	struct rtsp_header_range_t range;
	struct rtsp_header_session_t session;
	struct rtsp_server_context_t* ctx = req->server;

	pscale = rtsp_get_header_by_name(parser, "scale");
	prange = rtsp_get_header_by_name(parser, "range");
	psession = rtsp_get_header_by_name(parser, "Session");

	if(!psession || 0 != rtsp_header_session(psession, &session))
	{
		// 454 (Session Not Found)
		rtsp_server_reply(req, 454);
		return;
	}

	if(pscale)
	{
		scale = atof(pscale);
	}

	if(prange && 0 == rtsp_header_range(prange, &range))
	{
		npt = range.from;
	}

	ctx->handler.play(ctx->ptr, req, uri, session.session, -1L==npt?NULL:&npt, pscale?&scale:NULL);
}
Beispiel #4
0
static void rtsp_server_setup(struct rtsp_server_request_t *req, void *parser, const char* uri)
{
	size_t n;
	const char *psession, *ptransport;
	struct rtsp_header_session_t session;
	struct rtsp_header_transport_t transport[16];
	struct rtsp_server_context_t* ctx = req->server;

	psession = rtsp_get_header_by_name(parser, "Session");
	ptransport = rtsp_get_header_by_name(parser, "Transport");

	memset(transport, 0, sizeof(transport));
	n = sizeof(transport)/sizeof(transport[0]);
	if(!ptransport || 0 != rtsp_header_transport_ex(ptransport, transport, &n) || 0 == n)
	{
		// 461 Unsupported Transport
		rtsp_server_reply(req, 461);
		return;
	}

	assert(n > 0);
	if(psession && 0 == rtsp_header_session(psession, &session))
	{
		ctx->handler.setup(ctx->ptr, req, uri, session.session, transport, n);
	}
	else
	{
		ctx->handler.setup(ctx->ptr, req, uri, NULL, transport, n);
	}
}
int rtsp_client_setup_onreply(struct rtsp_client_t* rtsp, void* parser)
{
	int code;
	const char *session;
	const char *transport;

	assert(RTSP_SETUP == rtsp->state);
	assert(rtsp->progress < rtsp->media_count);

	code = rtsp_get_status_code(parser);
	if (200 == code)
	{
		session = rtsp_get_header_by_name(parser, "Session");
		transport = rtsp_get_header_by_name(parser, "Transport");
		if (!session || 0 != rtsp_header_session(session, &rtsp->media[rtsp->progress].session)
			|| !transport || 0 != rtsp_header_transport(transport, &rtsp->media[rtsp->progress].transport))
		{
			printf("Get rtsp transport error.\n");
			return -EINVAL;
		}

		assert(strlen(session) < sizeof(rtsp->media[0].session.session));
		assert(!rtsp->aggregate || 0 == strcmp(rtsp->media[0].session.session, rtsp->media[rtsp->progress].session.session));

		if (rtsp->media_count == ++rtsp->progress)
		{
			return rtsp->handler.onsetup(rtsp->param);
		}
		else
		{
			// setup next media
			return rtsp_client_media_setup(rtsp);
		}
	}
	else if (401 == code)
	{
		// Unauthorized
		const char* authenticate;
		authenticate = rtsp_get_header_by_name(parser, "WWW-Authenticate");
		if (authenticate)
		{
			rtsp_client_www_authenticate(rtsp, authenticate);
		}
		return -EACCES; // try again
	}
	else
	{
		return -1;
	}
}
Beispiel #6
0
static void rtsp_server_teardown(struct rtsp_server_request_t *req, void *parser, const char* uri)
{
	const char *psession;
	struct rtsp_header_session_t session;
	struct rtsp_server_context_t* ctx = req->server;

	psession = rtsp_get_header_by_name(parser, "Session");
	if(!psession || 0 != rtsp_header_session(psession, &session))
	{
		// 454 (Session Not Found)
		rtsp_server_reply(req, 454);
		return;
	}

	ctx->handler.teardown(ctx->ptr, req, uri, session.session);
}
Beispiel #7
0
const char* rtsp_server_find_header(void* rtsp, const char* name)
{
	struct rtsp_server_request_t *req;
	req = (struct rtsp_server_request_t *)rtsp;
	return rtsp_get_header_by_name(req->parser, name);
}