diff -r c9ff263c29ad -r e684f11070d5 src/jlibrtp/RtcpPkt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jlibrtp/RtcpPkt.java Sat Mar 14 22:15:41 2009 +0100 @@ -0,0 +1,134 @@ +/** + * Java RTP Library (jlibrtp) + * Copyright (C) 2006 Arne Kepp + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package jlibrtp; + +import java.net.InetAddress; +/** + * Common RTCP packet headers. + * + * @author Arne Kepp + */ +public class RtcpPkt { + /** Whether a problem has been encountered during parsing */ + protected int problem = 0; + /** The version, always 2, 2 bits */ + protected int version = 2; + /** Padding , 1 bit */ + protected int padding = 0; + /** Number of items, e.g. receiver report blocks. Usage may vary. 5 bits */ + protected int itemCount = 0; + /** The type of RTCP packet, 8 bits */ + protected int packetType = -1; + /** The length of the RTCP packet, in 32 bit blocks minus 1. 16 bits*/ + protected int length = -1; + /** The ssrc that sent this, usually dictated by RTP Session */ + protected long ssrc = -1; + + /** Contains the actual data (eventually) */ + protected byte[] rawPkt = null; + + /** Only used for feedback messages: Time message was generated */ + protected long time = -1; + /** Only used for feedback message: Whether this packet was received */ + protected boolean received = false; + + + /** + * Parses the common header of an RTCP packet + * + * @param start where in this.rawPkt the headers start + * @return true if parsing succeeded and header cheks + */ + protected boolean parseHeaders(int start) { + version = ((rawPkt[start+0] & 0xC0) >>> 6); + padding = ((rawPkt[start+0] & 0x20) >>> 5); + itemCount = (rawPkt[start+0] & 0x1F); + packetType = (int) rawPkt[start+1]; + if(packetType < 0) { + packetType += 256; + } + length = StaticProcs.bytesToUIntInt(rawPkt, start+2); + + if(RTPSession.rtpDebugLevel > 9) { + System.out.println(" <-> RtcpPkt.parseHeaders() version:"+version+" padding:"+padding+" itemCount:"+itemCount + +" packetType:"+packetType+" length:"+length); + } + + if(packetType > 207 || packetType < 200) + System.out.println("RtcpPkt.parseHeaders problem discovered, packetType " + packetType); + + if(version == 2 && length < 65536) { + return true; + } else { + System.out.println("RtcpPkt.parseHeaders() failed header checks, check size and version"); + this.problem = -1; + return false; + } + } + /** + * Writes the common header of RTCP packets. + * The values should be filled in when the packet is initiliazed and this function + * called at the very end of .encode() + */ + protected void writeHeaders() { + byte aByte = 0; + aByte |=(version << 6); + aByte |=(padding << 5); + aByte |=(itemCount); + rawPkt[0] = aByte; + aByte = 0; + aByte |= packetType; + rawPkt[1] = aByte; + if(rawPkt.length % 4 != 0) + System.out.println("!!!! RtcpPkt.writeHeaders() rawPkt was not a multiple of 32 bits / 4 octets!"); + byte[] someBytes = StaticProcs.uIntIntToByteWord((rawPkt.length / 4) - 1); + rawPkt[2] = someBytes[0]; + rawPkt[3] = someBytes[1]; + } + + /** + * This is just a dummy to make Eclipse complain less. + */ + protected void encode() { + System.out.println("RtcpPkt.encode() should never be invoked!! " + this.packetType); + } + + /** + * Check whether this packet came from the source we expected. + * + * Not currently used! + * + * @param adr address that packet came from + * @param partDb the participant database for the session + * @return true if this packet came from the expected source + */ + protected boolean check(InetAddress adr, ParticipantDatabase partDb) { + //Multicast -> We have to be naive + if (partDb.rtpSession.mcSession && adr.equals(partDb.rtpSession.mcGroup)) + return true; + + //See whether this participant is known + Participant part = partDb.getParticipant(this.ssrc); + if(part != null && part.rtcpAddress.getAddress().equals(adr)) + return true; + + //If not, we should look for someone without SSRC with his ip-address? + return false; + } +}