src/jlibrtp/RtcpPktSDES.java
changeset 823 2036ebfaccda
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jlibrtp/RtcpPktSDES.java	Fri Nov 20 19:29:42 2009 +0100
@@ -0,0 +1,308 @@
+/**
+ * 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.InetSocketAddress;
+
+/**
+ * RTCP packets for Source Descriptions
+ * 
+ * @author Arne Kepp
+ */
+public class RtcpPktSDES extends RtcpPkt {
+	/** Whether the RTP Session object should be inclduded */
+	boolean reportSelf = true;
+	/** The parent RTP Session object, holds participant database */
+	RTPSession rtpSession = null;
+	/** The participants to create SDES packets for */
+	protected Participant[] participants = null;
+
+	/**
+	 * Constructor to create a new SDES packet
+	 * 
+	 * TODO: Currently the added participants are not actually encoded because
+	 * the library lacks some support for acting as mixer or relay in other
+	 * areas.
+	 * 
+	 * @param reportThisSession
+	 *            include information from RTPSession as a participant
+	 * @param rtpSession
+	 *            the session itself
+	 * @param additionalParticipants
+	 *            additional participants to include
+	 */
+	protected RtcpPktSDES(boolean reportThisSession, RTPSession rtpSession,
+			Participant[] additionalParticipants) {
+		super.packetType = 202;
+		// Fetch all the right stuff from the database
+		reportSelf = reportThisSession;
+		participants = additionalParticipants;
+		this.rtpSession = rtpSession;
+	}
+
+	/**
+	 * Constructor that parses a received packet
+	 * 
+	 * @param aRawPkt
+	 *            the byte[] containing the packet
+	 * @param start
+	 *            where in the byte[] this packet starts
+	 * @param socket
+	 *            the address from which the packet was received
+	 * @param partDb
+	 *            the participant database
+	 */
+	protected RtcpPktSDES(byte[] aRawPkt, int start, InetSocketAddress socket,
+			ParticipantDatabase partDb) {
+		if (RTPSession.rtcpDebugLevel > 8) {
+			System.out.println("  -> RtcpPktSDES(byte[], ParticipantDabase)");
+		}
+		rawPkt = aRawPkt;
+
+		if (!super.parseHeaders(start) || packetType != 202) {
+			if (RTPSession.rtpDebugLevel > 2) {
+				System.out
+						.println(" <-> RtcpPktSDES.parseHeaders() etc. problem");
+			}
+			super.problem = -202;
+		} else {
+			// System.out.println(" DECODE SIZE: " + super.length +
+			// " itemcount " + itemCount );
+
+			int curPos = 4 + start;
+			int curLength;
+			int curType;
+			long ssrc;
+			boolean endReached = false;
+			boolean newPart;
+			this.participants = new Participant[itemCount];
+
+			// Loop over SSRC SDES chunks
+			for (int i = 0; i < itemCount; i++) {
+				ssrc = StaticProcs.bytesToUIntLong(aRawPkt, curPos);
+				Participant part = partDb.getParticipant(ssrc);
+				if (part == null) {
+					if (RTPSession.rtcpDebugLevel > 1) {
+						System.out
+								.println("RtcpPktSDES(byte[], ParticipantDabase) adding new participant, ssrc:"
+										+ ssrc + " " + socket);
+					}
+
+					part = new Participant(socket, socket, ssrc);
+					newPart = true;
+				} else {
+					newPart = false;
+				}
+
+				curPos += 4;
+
+				// System.out.println("PRE endReached " + endReached +
+				// " curPos: " + curPos + " length:" + this.length +
+				// (!endReached && (curPos/4) < this.length));
+
+				while (!endReached && (curPos / 4) <= this.length) {
+					// System.out.println("endReached " + endReached +
+					// " curPos: " + curPos + " length:" + this.length);
+					curType = (int) aRawPkt[curPos];
+
+					if (curType == 0) {
+						curPos += 4 - (curPos % 4);
+						endReached = true;
+					} else {
+						curLength = (int) aRawPkt[curPos + 1];
+						// System.out.println("curPos:"+curPos+" curType:"+curType+" curLength:"+curLength+" read from:"+(curPos
+						// + 1));
+
+						if (curLength > 0) {
+							byte[] item = new byte[curLength];
+							// System.out.println("curPos:"+curPos+" arawPkt.length:"+aRawPkt.length+" curLength:"+curLength);
+							System.arraycopy(aRawPkt, curPos + 2, item, 0,
+									curLength);
+
+							switch (curType) {
+							case 1:
+								part.cname = new String(item);
+								break;
+							case 2:
+								part.name = new String(item);
+								break;
+							case 3:
+								part.email = new String(item);
+								break;
+							case 4:
+								part.phone = new String(item);
+								break;
+							case 5:
+								part.loc = new String(item);
+								break;
+							case 6:
+								part.tool = new String(item);
+								break;
+							case 7:
+								part.note = new String(item);
+								break;
+							case 8:
+								part.priv = new String(item);
+								break;
+							}
+							// System.out.println("TYPE " + curType + " value:"
+							// + new String(item) );
+
+						} else {
+							switch (curType) {
+							case 1:
+								part.cname = null;
+								break;
+							case 2:
+								part.name = null;
+								break;
+							case 3:
+								part.email = null;
+								break;
+							case 4:
+								part.phone = null;
+								break;
+							case 5:
+								part.loc = null;
+								break;
+							case 6:
+								part.tool = null;
+								break;
+							case 7:
+								part.note = null;
+								break;
+							case 8:
+								part.priv = null;
+								break;
+							}
+
+						}
+						curPos = curPos + curLength + 2;
+					}
+				}
+
+				// Save the participant
+				this.participants[i] = part;
+				if (newPart)
+					partDb.addParticipant(2, part);
+
+				// System.out.println("HEPPPPPP " + participants[i].cname );
+			}
+		}
+		if (RTPSession.rtcpDebugLevel > 8) {
+			System.out.println("  <- RtcpPktSDES()");
+		}
+	}
+
+	/**
+	 * Encode the packet into a byte[], saved in .rawPkt
+	 * 
+	 * CompRtcpPkt will call this automatically
+	 */
+	protected void encode() {
+		byte[] temp = new byte[1450];
+		byte[] someBytes = StaticProcs.uIntLongToByteWord(this.rtpSession.ssrc);
+		System.arraycopy(someBytes, 0, temp, 4, 4);
+		int pos = 8;
+
+		String tmpString = null;
+		for (int i = 1; i < 9; i++) {
+			switch (i) {
+			case 1:
+				tmpString = this.rtpSession.cname;
+				break;
+			case 2:
+				tmpString = this.rtpSession.name;
+				break;
+			case 3:
+				tmpString = this.rtpSession.email;
+				break;
+			case 4:
+				tmpString = this.rtpSession.phone;
+				break;
+			case 5:
+				tmpString = this.rtpSession.loc;
+				break;
+			case 6:
+				tmpString = this.rtpSession.tool;
+				break;
+			case 7:
+				tmpString = this.rtpSession.note;
+				break;
+			case 8:
+				tmpString = this.rtpSession.priv;
+				break;
+			}
+
+			if (tmpString != null) {
+				someBytes = tmpString.getBytes();
+				temp[pos] = (byte) i;
+				temp[pos + 1] = (byte) someBytes.length;
+				System.arraycopy(someBytes, 0, temp, pos + 2, someBytes.length);
+				// System.out.println("i: "+i+" pos:"+pos+" someBytes.length:"+someBytes.length);
+				pos = pos + someBytes.length + 2;
+				// if(i == 1 ) {
+				// System.out.println("trueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" +
+				// tmpString);
+				// }
+			}
+		}
+		int leftover = pos % 4;
+		if (leftover == 1) {
+			temp[pos] = (byte) 0;
+			temp[pos + 1] = (byte) 1;
+			pos += 3;
+		} else if (leftover == 2) {
+			temp[pos] = (byte) 0;
+			temp[pos + 1] = (byte) 0;
+			pos += 2;
+		} else if (leftover == 3) {
+			temp[pos] = (byte) 0;
+			temp[pos + 1] = (byte) 3;
+			pos += 5;
+		}
+
+		// TODO Here we ought to loop over participants, if we're doing SDES for
+		// other participants.
+
+		super.rawPkt = new byte[pos];
+		itemCount = 1;
+		// This looks wrong, but appears to be fine..
+		System.arraycopy(temp, 0, super.rawPkt, 0, pos);
+		writeHeaders();
+	}
+
+	/**
+	 * Debug purposes only
+	 */
+	public void debugPrint() {
+		System.out.println("RtcpPktSDES.debugPrint() ");
+		if (participants != null) {
+			for (int i = 0; i < participants.length; i++) {
+				Participant part = participants[i];
+				System.out.println("     part.ssrc: " + part.ssrc
+						+ "  part.cname: " + part.cname + " part.loc: "
+						+ part.loc);
+			}
+		} else {
+			System.out
+					.println("     nothing to report (only valid for received packets)");
+		}
+	}
+}