diff -r 537ddd8aa407 -r 2036ebfaccda src/jlibrtp/RtcpPkt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jlibrtp/RtcpPkt.java Fri Nov 20 19:29:42 2009 +0100 @@ -0,0 +1,143 @@ +/** + * 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!"); + StaticProcs.uIntIntToByteWord((rawPkt.length / 4) - 1, rawPkt, 2); + } + + /** + * 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; + } +}