Esempio n. 1
0
//return M4BadParam if invalid structure, M4SignalingFailure if bad formatting
//or M4OK
M4Err SDP_CheckInfo(SDPInfo *sdp)
{
	M4Err e;
	u32 i, j;
	SDPMedia *media;
	SDPConnection *conn;
	SDP_RTPMap *map;
	Bool HasGlobalConnection, HasSeveralPorts;

	if (!sdp || !sdp->media_desc || !sdp->Attributes) return M4BadParam;
	//we force at least one media per SDP
	if (!ChainGetCount(sdp->media_desc)) return M4SignalingFailure;

	//normative fields
	//o=
	if (!sdp->o_add_type || !sdp->o_address || !sdp->o_username || !sdp->o_session_id || !sdp->o_version) 
		return M4SignalingFailure;
	//s=
	if (!sdp->s_session_name) return M4SignalingFailure;
	//t=
//	if () return M4SignalingFailure;
	//c=
	if (sdp->c_connection) { 
		e = SDP_CheckConnection(sdp->c_connection);
		if (e) return e;
		//multiple addresses are only for media desc
		if (sdp->c_connection->add_count >= 2) return M4SignalingFailure;
		HasGlobalConnection = 1;
	} else {
		HasGlobalConnection = 0;
	}

	//then check all media
	for (i=0; i<ChainGetCount(sdp->media_desc); i++) {
		media = ChainGetEntry(sdp->media_desc, i);
		HasSeveralPorts = 0;

		//m= : force non-null port, profile and fmt_list
		if (!media->PortNumber || !media->Profile) return M4SignalingFailure;
		if (media->NumPorts) HasSeveralPorts = 1;

		//no connections specified - THIS IS AN ERROR IN SDP BUT NOT IN ALL RTSP SESSIONS...
//		if (!HasGlobalConnection && !ChainGetCount(media->Connections)) return M4SignalingFailure;
		//too many connections specified
		if (HasGlobalConnection && ChainGetCount(media->Connections)) return M4SignalingFailure;

		//check all connections, and make sure we don't have multiple addresses 
		//and multiple ports at the same time
		if (ChainGetCount(media->Connections)>1 && HasSeveralPorts) return M4SignalingFailure;
		for (j=0; j<ChainGetCount(media->Connections); j++) {
			conn = ChainGetEntry(media->Connections, j);
			e = SDP_CheckConnection(conn);
			if (e) return e;
			if ((conn->add_count >= 2) && HasSeveralPorts) return M4SignalingFailure; 
		}
		//RTPMaps. 0 is tolerated, but if some are specified check them
		for (j=0; j<ChainGetCount(media->RTPMaps); j++) {
			map = ChainGetEntry(media->RTPMaps, j);
			//RFC2327 is not clear here, but we assume the PayloadType should be a DYN one
			//however this depends on the profile (RTP/AVP or others) so don't check it
			//ClockRate SHALL NOT be NULL
			if (!map->payload_name || !map->ClockRate) return M4SignalingFailure;
		}
	}
	//Encryption: nothing tells wether the scope of the global key is eclusive or not.
	//we accept a global key + keys per media entry, assuming that the media key primes
	//on the global key


	return M4OK;
}
Esempio n. 2
0
//return GF_BAD_PARAM if invalid structure, GF_REMOTE_SERVICE_ERROR if bad formatting
//or GF_OK
GF_EXPORT
GF_Err gf_sdp_info_check(GF_SDPInfo *sdp)
{
	GF_Err e;
	u32 i, j, count;
	GF_SDPMedia *media;
	GF_SDPConnection *conn;
	GF_RTPMap *map;
	Bool HasGlobalConnection, HasSeveralPorts;

	if (!sdp || !sdp->media_desc || !sdp->Attributes) return GF_BAD_PARAM;
	//we force at least one media per SDP
	if (!gf_list_count(sdp->media_desc)) return GF_REMOTE_SERVICE_ERROR;

	//normative fields
	//o=
	if (!sdp->o_add_type || !sdp->o_address || !sdp->o_username || !sdp->o_session_id || !sdp->o_version) 
		return GF_REMOTE_SERVICE_ERROR;
	//s=
	//commented for intermedia demos
//	if (!sdp->s_session_name) return GF_REMOTE_SERVICE_ERROR;
	//t=
//	if () return GF_REMOTE_SERVICE_ERROR;
	//c=
	if (sdp->c_connection) { 
		e = SDP_CheckConnection(sdp->c_connection);
		if (e) return e;
		//multiple addresses are only for media desc
		if (sdp->c_connection->add_count >= 2) return GF_REMOTE_SERVICE_ERROR;
		HasGlobalConnection = 1;
	} else {
		HasGlobalConnection = 0;
	}

	//then check all media
	i=0;
	while ((media = (GF_SDPMedia*)gf_list_enum(sdp->media_desc, &i))) {
		HasSeveralPorts = 0;

		//m= : force non-null port, profile and fmt_list
		if (/*!media->PortNumber || */ !media->Profile) return GF_REMOTE_SERVICE_ERROR;
		if (media->NumPorts) HasSeveralPorts = 1;

		//no connections specified - THIS IS AN ERROR IN SDP BUT NOT IN ALL RTSP SESSIONS...
//		if (!HasGlobalConnection && !gf_list_count(media->Connections)) return GF_REMOTE_SERVICE_ERROR;
		//too many connections specified
		if (HasGlobalConnection && gf_list_count(media->Connections)) return GF_REMOTE_SERVICE_ERROR;

		//check all connections, and make sure we don't have multiple addresses 
		//and multiple ports at the same time
		count = gf_list_count(media->Connections);
		if (count>1 && HasSeveralPorts) return GF_REMOTE_SERVICE_ERROR;

		for (j=0; j<count; j++) {
			conn = (GF_SDPConnection*)gf_list_get(media->Connections, j);
			e = SDP_CheckConnection(conn);
			if (e) return e;
			if ((conn->add_count >= 2) && HasSeveralPorts) return GF_REMOTE_SERVICE_ERROR; 
		}
		//RTPMaps. 0 is tolerated, but if some are specified check them
		j=0;
		while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &j))) {
			//RFC2327 is not clear here, but we assume the PayloadType should be a DYN one
			//however this depends on the profile (RTP/AVP or others) so don't check it
			//ClockRate SHALL NOT be NULL
			if (!map->payload_name || !map->ClockRate) return GF_REMOTE_SERVICE_ERROR;
		}
	}
	//Encryption: nothing tells wether the scope of the global key is eclusive or not.
	//we accept a global key + keys per media entry, assuming that the media key primes
	//on the global key

	return GF_OK;
}