Пример #1
0
GF_Err RTSP_WriteCommand(GF_RTSPSession *sess, GF_RTSPCommand *com, unsigned char *req_buffer, 
						 unsigned char **out_buffer, u32 *out_size)
{
	u32 i, cur_pos, size, count;
	char *buffer, temp[50];
	GF_RTSPTransport *trans;
	GF_X_Attribute *att;

	*out_buffer = NULL;

	size = RTSP_WRITE_STEPALLOC;
	buffer = (char *) gf_malloc(size);
	cur_pos = 0;

	//request
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, req_buffer);

	//then all headers
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Accept", com->Accept);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Accept-Encoding", com->Accept_Encoding);	
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Accept-Language", com->Accept_Language);	
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Authorization", com->Authorization);	
	if (com->Bandwidth) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Bandwidth: ");	
		RTSP_WRITE_INT(buffer, size, cur_pos, com->Bandwidth, 0);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	
	}
	if (com->Blocksize) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Blocksize: ");
		RTSP_WRITE_INT(buffer, size, cur_pos, com->Blocksize, 0);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Cache-Control", com->Cache_Control);	
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Conference", com->Conference);	
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Connection", com->Connection);
	//if we have a body write the content length
	if (com->body) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Content-Length: ");
		RTSP_WRITE_INT(buffer, size, cur_pos, (u32) strlen(com->body), 0);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	
	}
	//write the CSeq - use the SESSION CSeq
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "CSeq: ");
	RTSP_WRITE_INT(buffer, size, cur_pos, sess->CSeq, 0);
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	

	RTSP_WRITE_HEADER(buffer, size, cur_pos, "From", com->From);	
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Proxy-Authorization", com->Proxy_Authorization);	
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Proxy-Require", com->Proxy_Require);	

	//Range, only NPT
	if (com->Range && !com->Range->UseSMPTE) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Range: npt=");
		RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, com->Range->start);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");	
		if (com->Range->end > com->Range->start) {
			RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, com->Range->end);
		}
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	
	}

	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Referer", com->Referer);	
	if (com->Scale != 0.0) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Scale: ");	
		RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, com->Scale);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Session", com->Session);	
	if (com->Speed != 0.0) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Speed: ");	
		RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, com->Speed);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");	
	}

	//transport info
	count = gf_list_count(com->Transports);
	if (count) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Transport: ");
		for (i=0; i<count; i++) {
			//line separator for headers
			if (i) RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n ,");
			trans = (GF_RTSPTransport *) gf_list_get(com->Transports, i);

			//then write the structure
			RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->Profile);
			RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, (trans->IsUnicast ? ";unicast" : ";multicast"));
			if (trans->destination) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";destination=");
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->destination);
			}
			if (trans->source) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";source=");
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->source);
			}
			if (trans->IsRecord) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";mode=RECORD");
				if (trans->Append) RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";append");
			}
			if (trans->IsInterleaved) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";interleaved=");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->rtpID, 0);
				if (trans->rtcpID != trans->rtpID) {
					RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
					RTSP_WRITE_INT(buffer, size, cur_pos, trans->rtcpID, 0);
				}
			}
			if (trans->port_first) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, (trans->IsUnicast ? ";server_port=" : ";port="));
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_first, 0);
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_last, 0);
			}
			if (/*trans->IsUnicast && */trans->client_port_first) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";client_port=");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->client_port_first, 0);
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->client_port_last, 0);
			}
			//multicast specific
			if (!trans->IsUnicast) {
				if (trans->MulticastLayers) {
					RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";layers=");
					RTSP_WRITE_INT(buffer, size, cur_pos, trans->MulticastLayers, 0);
				}
				if (trans->TTL) {
					RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";ttl=");
					RTSP_WRITE_INT(buffer, size, cur_pos, trans->TTL, 0);
				}
			}
			if (trans->SSRC) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";ssrc=");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->SSRC, 0);
			}
		}
		//done with transport
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "User-Agent", com->User_Agent);	

	//eXtensions
	count = gf_list_count(com->Xtensions);
	for (i=0; i<count; i++) {
		att = (GF_X_Attribute *) gf_list_get(com->Xtensions, i);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "x-");
		RTSP_WRITE_HEADER(buffer, size, cur_pos, att->Name, att->Value);	
	}

	//the end of header
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	//then body
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, com->body);
	//the end of message ? to check, should not be needed...
//	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");

	*out_buffer = (unsigned char *)buffer;
	*out_size = (u32) strlen(buffer);
	return GF_OK;
}
Пример #2
0
GF_Err RTSP_WriteResponse(GF_RTSPSession *sess, GF_RTSPResponse *rsp,
                          unsigned char **out_buffer, u32 *out_size)
{
	u32 i, cur_pos, size, count;
	char *buffer, temp[50];
	GF_RTSPTransport *trans;
	GF_X_Attribute *att;
	GF_RTPInfo *info;


	*out_buffer = NULL;

	size = RTSP_WRITE_STEPALLOC;
	buffer = (char *) gf_malloc(size);
	cur_pos = 0;

	//RTSP line
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, GF_RTSP_VERSION);
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, " ");
	RTSP_WRITE_INT(buffer, size, cur_pos, rsp->ResponseCode, 0);
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, " ");
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, gf_rtsp_nc_to_string(rsp->ResponseCode));
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");

	//all headers
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Accept", rsp->Accept);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Accept-Encoding", rsp->Accept_Encoding);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Accept-Language", rsp->Accept_Language);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Allow", rsp->Allow);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Authorization", rsp->Authorization);
	if (rsp->Bandwidth) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Bandwidth: ");
		RTSP_WRITE_INT(buffer, size, cur_pos, rsp->Bandwidth, 0);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}
	if (rsp->Blocksize) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Blocksize: ");
		RTSP_WRITE_INT(buffer, size, cur_pos, rsp->Blocksize, 0);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Cache-Control", rsp->Cache_Control);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Conference", rsp->Conference);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Connection", rsp->Connection);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Content-Base", rsp->Content_Base);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Content-Encoding", rsp->Content_Encoding);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Content-Language", rsp->Content_Language);
	//if we have a body write the content length
	if (rsp->body) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Content-Length: ");
		RTSP_WRITE_INT(buffer, size, cur_pos, (u32) strlen(rsp->body), 0);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Content-Location", rsp->Content_Location);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Content-Type", rsp->Content_Type);
	//write the CSeq - use the RESPONSE CSeq
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "CSeq: ");
	RTSP_WRITE_INT(buffer, size, cur_pos, rsp->CSeq, 0);
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");

	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Date", rsp->Date);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Expires", rsp->Expires);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "From", rsp->From);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Host", rsp->Host);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "If-Match", rsp->If_Match);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "If-Modified-Since", rsp->If_Modified_Since);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Last-Modified", rsp->Last_Modified);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Location", rsp->Location);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Proxy-Authenticate", rsp->Proxy_Authenticate);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Proxy-Require", rsp->Proxy_Require);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Public", rsp->Public);

	//Range, only NPT
	if (rsp->Range && !rsp->Range->UseSMPTE) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Range: npt:");
		RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, rsp->Range->start);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
		if (rsp->Range->end > rsp->Range->start) {
			RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, rsp->Range->end);
		}
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}

	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Referer", rsp->Referer);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Require", rsp->Require);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Retry-After", rsp->Retry_After);

	//RTP Infos
	count = gf_list_count(rsp->RTP_Infos);
	if (count) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "RTPInfo: ");

		for (i=0; i<count; i++) {
			//line separator for headers
			if (i) RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n ,");
			info = (GF_RTPInfo*)gf_list_get(rsp->RTP_Infos, i);

			if (info->url) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "url=");
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, info->url);
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";");
			}
			RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "seq=");
			RTSP_WRITE_INT(buffer, size, cur_pos, info->seq, 0);
			RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";rtptime=");
			RTSP_WRITE_INT(buffer, size, cur_pos, info->rtp_time, 0);
		}
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}

	if (rsp->Scale != 0.0) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Scale: ");
		RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, rsp->Scale);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Server", rsp->Server);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Session", rsp->Session);
	if (rsp->Speed != 0.0) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Scale: ");
		RTSP_WRITE_FLOAT_WITHOUT_CHECK(buffer, size, cur_pos, rsp->Speed);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Timestamp", rsp->Timestamp);

	//transport info
	count = gf_list_count(rsp->Transports);
	if (count) {
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Transport: ");
		for (i=0; i<count; i++) {
			//line separator for headers
			if (i) RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n ,");
			trans = (GF_RTSPTransport*)gf_list_get(rsp->Transports, i);

			//then write the structure
			RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->Profile);
			RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, (trans->IsUnicast ? ";unicast" : ";multicast"));
			if (trans->destination) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";destination=");
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->destination);
			}
			if (trans->source) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";source=");
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->source);
			}
			if (trans->IsRecord) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";mode=RECORD");
				if (trans->Append) RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";append");
			}
			if (trans->IsInterleaved) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";interleaved=");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->rtpID, 0);
				if (trans->rtcpID != trans->rtpID) {
					RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
					RTSP_WRITE_INT(buffer, size, cur_pos, trans->rtcpID, 0);
				}
			}
			//multicast specific
			if (!trans->IsUnicast) {
				if (trans->MulticastLayers) {
					RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";layers=");
					RTSP_WRITE_INT(buffer, size, cur_pos, trans->MulticastLayers, 0);
				}
				if (trans->TTL) {
					RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";ttl=");
					RTSP_WRITE_INT(buffer, size, cur_pos, trans->TTL, 0);
				}
			}
			if (trans->port_first) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, (const char *) (trans->IsUnicast ? ";server_port=" : ";port="));
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_first, 0);
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_last, 0);
			}
			if (trans->IsUnicast && trans->client_port_first) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";client_port=");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->client_port_first, 0);
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->client_port_last, 0);
			}
			if (trans->SSRC) {
				RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, ";ssrc=");
				RTSP_WRITE_INT(buffer, size, cur_pos, trans->SSRC, 0);
			}
		}
		//done with transport
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	}

	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Unsupported", rsp->Unsupported);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "User-Agent", rsp->User_Agent);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Vary", rsp->Vary);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "Via", rsp->Via);
	RTSP_WRITE_HEADER(buffer, size, cur_pos, "WWW-Authenticate", rsp->WWW_Authenticate);

	//eXtensions
	count = gf_list_count(rsp->Xtensions);
	for (i=0; i<count; i++) {
		att = (GF_X_Attribute*)gf_list_get(rsp->Xtensions, i);
		RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "x-");
		RTSP_WRITE_HEADER(buffer, size, cur_pos, att->Name, att->Value);
	}
	//end of header
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n");
	//then body
	RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, rsp->body);

	*out_buffer = (unsigned char *) buffer;
	*out_size = (u32) strlen(buffer);
	return GF_OK;
}