Package rtpi.packets

Source Code of rtpi.packets.RtcpiSourceDescriptionPacket

/* The Java RTP/I library, Version 0.1 alpha.
* This library provides the functionality of RTP/I as it is specified in
* Internet Draft draft-mauve-rtpi-00.txt.
*
* Copyright (C) 2000 Martin Mauve
* University of Mannheim / Germany
*
* 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Martin Mauve
*
* e-mail:
* mauve@informatik.uni-mannheim.de
*
* paper mail:
* Martin Mauve
* University of Mannheim
* Lehrstuhl Praktische Informatik IV
* L15, 16
* 68131 Mannheim
* Germany
*/

package rtpi.packets;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import java.util.LinkedList;
import java.util.ListIterator;

import rtpi.IllegalValueException;

/**
* This implements the RTCP/I source description packet.
*/

public class RtcpiSourceDescriptionPacket extends RtcpiPacket {
   
    /**
     * The payload type for source description packets.
     */

    public static final int SDES   = 72;
    private LinkedList items=null;

    /**
     * This creates a new source description packet that is to be transmitted over
     * the network.
     *
     * @param pid The id of the participant transmitting the packet.
     * @param sdi The list of source description items. All objects in this list
     *            must be of the type SourceDescriptionItems (package rtpi.packets).
     *            The first item MUST be a CNAME item.
     */

    public RtcpiSourceDescriptionPacket(int pid, LinkedList sdi) throws IllegalValueException {
  super(pid);
  payloadType=SDES;
  setSourceDescriptionItems(sdi);
    }

    /**
     * This creates an RTCP/I source description packet from a transport packet
     * that has been received.
     *
     * @param d The transport packet.
     * @param s The start of the RTCP/I packet in the transport packet
     *          (position of the first byte of the RTCP/I header.
     */

    public RtcpiSourceDescriptionPacket(byte[] d, int s) {
  super(d, s);
    }

    /**
     * This flushes an outgoing packet.
     */

    public void flush() throws RtpiFlushException {
  if (items==null || items.size()==0) {
      throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Can't flush report with no entires");
  }
 
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  DataOutputStream dos = new DataOutputStream(bos);
 
  flushHeader(dos);

  SourceDescriptionItem item;
  int writtenBytes=0;
  int itemLength=0;

  for(ListIterator iter=items.listIterator();iter.hasNext();) {
      item = (SourceDescriptionItem) iter.next();
      int type = item.getType();
      byte[] data = item.getData();
      try {
    dos.writeByte((byte) type);
      } catch (Exception ex) {
    throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't write SDES type");
      }
      if (item.getType()==SourceDescriptionItem.PRIV) {
    try {
        byte[] prefix=item.getPrefix();
        itemLength=prefix.length+data.length+1;
        dos.writeByte((byte) itemLength);
        dos.writeByte((byte) prefix.length);
        dos.write(prefix);
    } catch (Exception ex) {
        throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't write prefix to SDES item");
    }
      } else {
    try {
        itemLength=data.length;
        dos.writeByte((byte) itemLength);
    } catch (Exception ex) {
        throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't write length of SDES item");
    }
      }
      try {
    dos.write(data);
      } catch (Exception ex) {
    throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't write SDES data");
      }
      writtenBytes+=itemLength+2;
  }
 
  try {
      for(int c = 0; c < (4-writtenBytes%4)%4; c++) {
    dos.writeByte((byte)0);        // padding bytes
      }
  } catch (Exception ex) {
      throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't write padding bytes");
  }
 
  try {
      dos.flush();
      bos.flush();
  } catch (Exception ex) {
      throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't flush output streams");
  }
 
  packetData = bos.toByteArray();
  if (packetData.length!=(length+2)*4) {
      throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Illegal packet length after flushing packet");
  }
  try {
      dos.close();
      bos.close();
  } catch (Exception ex) {
      throw new RtpiFlushException("RtcpiSourceDescriptionPacket: Couldn't close output streams");
  }
    }
   
    /**
     * This parses an incoming packet.
     */

    public void parse() throws RtpiParseException {
  ByteArrayInputStream bis = new ByteArrayInputStream(packetData, packetStart, packetData.length-packetStart);
  DataInputStream dis = new DataInputStream(bis);
 
  parseHeader(dis);

  if (payloadType!=SDES) {
      throw new RtpiParseException("RtcpiSourceDescriptionPacket: Wrong payload type "+payloadType+" should be "+SDES);
  }
 
  int itemLength;
  byte[] data;
  int prefixLength;
  byte[] prefix;
  int type;
  int readBytes;
  items=new LinkedList();
  SourceDescriptionItem item;

  for(int i=0;i<count;i++) {
      try {
    type=dis.readUnsignedByte();
      } catch (Exception ex) {
    throw new RtpiParseException("RtcpiSourceDescriptionPacket: Couldn't read SDES type");
      }

      if (type<1 || type>8) {
    throw new RtpiParseException("RtcpiSourceDescriptionPacket: received illegal SDES item type");
      }

      try {
    itemLength=dis.readUnsignedByte();
      } catch (Exception ex) {
    throw new RtpiParseException("RtcpiSourceDescriptionPacket: Couldn't read SDES length");
      }

      if (type==SourceDescriptionItem.PRIV) {
    try {
        prefixLength=dis.readUnsignedByte();
        itemLength=itemLength-prefixLength-1;
        prefix = new byte[prefixLength];
        data = new byte[itemLength];
        dis.readFully(prefix);
        dis.readFully(data);
        item=new SourceDescriptionItem(data,prefix);
        items.add(item);
    } catch (Exception ex) {
        throw new RtpiParseException("RtcpiSourceDescriptionPacket: Couldn't read SDES entry "+ex);
    }
      } else {
    try {
        data = new byte[itemLength];
        dis.readFully(data);
        item=new SourceDescriptionItem(type,data);
        items.add(item);
    } catch (Exception ex) {
        throw new RtpiParseException("RtcpiSourceDescriptionPacket: Couldn't read SDES entry "+ex);
    }
      }
  }   
  try {
      dis.close();
      bis.close();
  } catch (Exception exe) {
      throw new RtpiParseException("RtcpiSourceDescriptionPacket: Could not close input stream for packet");
  }
    }

    private void setSourceDescriptionItems(LinkedList its) throws IllegalValueException {
  items=its;
  if (items==null || items.size()==0 || items.size()>31) {
      throw new IllegalValueException("RtcpiSourceDescriptionPacket: Can't set empty entries list");
  }

  count = items.size();

  SourceDescriptionItem item = (SourceDescriptionItem) items.getFirst();
  if (item.getType()!=SourceDescriptionItem.CNAME) {
      throw new IllegalValueException("RtcpiSourceDescriptionPacket: First element in entries list is not a CNAME entry");
  }

  length = 0; // first calculate them on a byte basis, then devide it by 4!
   
  for(ListIterator iter=items.listIterator();iter.hasNext();) {
      item = (SourceDescriptionItem) iter.next();

      if (item.getType()==SourceDescriptionItem.PRIV) {
    length+=item.getPrefix().length+item.getData().length+3;
      } else {
    length+=item.getData().length+2;
      }
  }
  length += (4-length%4)%4; // with padding
  length /= 4;
    }


    /**
     * This returns the list of SourceDescriptionItems that are contained in
     * this packet.
     *
     * @return The list of SDES items.
     */

    public LinkedList getSourceDescriptionItems() {
  return items;
    }

    /**
     * Convert this object to a string.
     *
     * @return This object as a string.
     */
   
    public String toString() {
  String returnValue;
  returnValue ="RtcpiSourceDescriptionPacket: {\n";
  returnValue+=toStringDetails();
  returnValue+="}\n";
  return returnValue;
    }


    String toStringDetails() {
  String returnValue;
  returnValue=super.toStringDetails();
  SourceDescriptionItem item = null;
  for(ListIterator iter=items.listIterator();iter.hasNext();) {
      item = (SourceDescriptionItem) iter.next();
      returnValue+=item;
  }
  return returnValue;
    }
}

TOP

Related Classes of rtpi.packets.RtcpiSourceDescriptionPacket

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.