Package rtpi.packets

Source Code of rtpi.packets.RtcpiSubcomponentReportPacket

/* 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 subcomponent report packet.
*/

public class RtcpiSubcomponentReportPacket extends RtcpiPacket {
   
    /**
     * The payload type for subcomponent report packets.
     */

    public static final int SUBREP = 70;

    private LinkedList subcomponents=null;

    private static int ACTIVE_BITMASK=0x00000001;

    /**
     * This creates a new subcomponent report packet that is to be transmitted over
     * the network.
     *
     * @param pid The id of the participant transmitting the packet.
     * @param applicationLevelNames This must be set to 1 if application level names are used, otherwhise
     *                              it must be set to 0 if no application level names are used
     * @param subs The list of subcomponent report items. All objects in this list
     *             must be of the type SubcomponentReportInfo (package rtpi.packets). If
     *             applicationLevelNames is 1 then application level names must be present
     *             for each subcomponent. If applicationLevelNames is 0 then no application
     *             level names may be given.
     */

    public RtcpiSubcomponentReportPacket(int pid, int applicationLevelNames, LinkedList subs) throws IllegalValueException {
  super(pid);
  payloadType=SUBREP;
  setSubcomponentReportInfo(applicationLevelNames, subs);
    }

    /**
     * This creates an RTCP/I subcomponent report 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 RtcpiSubcomponentReportPacket(byte[] d, int l) {
  super(d, l);
    }

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

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

  int activeBits=0;

  SubcomponentReportInfo info = null;
  int i=0;

  for(ListIterator iter=subcomponents.listIterator();iter.hasNext();) {
      info = (SubcomponentReportInfo) iter.next();
      i++;
      if (info.getActive()==1) {
    activeBits |= 1 ;
      }
      if (i!=32) {
    activeBits <<= 1;
      }
  }
 
  if (i<31) {
      activeBits <<= (31-i);
  }

  try {
      dos.writeInt(activeBits);
  } catch (Exception ex) {
      throw new RtpiFlushException("RtcpiSubcomponentReportPacket: Couldn't write active list");
  }
 
  for(ListIterator iter=subcomponents.listIterator();iter.hasNext();) {
      info = (SubcomponentReportInfo) iter.next();
      try {
    dos.writeLong(info.getSubcomponentID());
      } catch (Exception ex) {
    throw new RtpiFlushException("RtcpiSubcomponentReportPacket: Couldn't write subcomponent ID");
      }
      if (reserved==1) {
    try {
        byte[] name = info.getApplicationLevelName();
        dos.writeByte((byte) name.length); // the length in bytes
        dos.write(name);                   // the name
        for(int c = 0; c < (4-(name.length+1)%4)%4; c++) {
      dos.writeByte((byte)0);        // padding bytes
        }
    } catch (Exception ex) {
        throw new RtpiFlushException("RtcpiSubcomponentReportPacket: Couldn't write application level name");
    }
      }
     
  }
 
  try {
      dos.flush();
      bos.flush();
  } catch (Exception ex) {
      throw new RtpiFlushException("RtcpiSubcomponentReportPacket: Couldn't flush output streams");
  }
 
  packetData = bos.toByteArray();
  if (packetData.length!=(length+2)*4) {
      throw new RtpiFlushException("RtcpiSubcomponentReportPacket: Illegal packet length after flushing packet");
  }
  try {
      dos.close();
      bos.close();
  } catch (Exception ex) {
      throw new RtpiFlushException("RtCpiSubcomponentReportPacket: 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!=SUBREP) {
      throw new RtpiParseException("RtCpiSubcomponentReportPacket: Wrong payload type "+payloadType+" should be "+SUBREP);
  }
 
  int activeBits=0;

  try {
      activeBits=dis.readInt();
  } catch (Exception ex) {
      throw new RtpiParseException("RtcpiSubcomponentReportPacket: Couldn't read active list");
 

  int active=0;
  long sID=0;
  int nameLength=0;
  byte[] name=null;
  SubcomponentReportInfo info=null;
  subcomponents=new LinkedList();

  for(int i=0;i<count;i++) {
      try {
    sID=dis.readLong();
      } catch (Exception ex) {
    throw new RtpiParseException("RtcpiSubcomponentReportPacket: Couldn't read subcomponent ID");
      }
      if (reserved==1) {
    try {
        nameLength=dis.readUnsignedByte();
    } catch (Exception ex) {
        throw new RtpiParseException("RtcpiSubcomponentReportPacket: Couldn't read subcomponent ID");
   
    name=new byte[nameLength];
    try {
        dis.readFully(name);
    } catch (Exception ex) {
        throw new RtpiParseException("RtcpiSubcomponentReportPacket: Couldn't read subcomponent name");
   
    for(int c = 0; c < (4-(nameLength+1)%4)%4; c++) {
        try {
      dis.readByte();        // padding bytes
        } catch (Exception ex) {
      throw new RtpiParseException("RtcpiSubcomponentReportPacket: Couldn't read padding bytes");
       
    }
      }
     
      active=(activeBits>>>(31-i))&ACTIVE_BITMASK;
      info=new SubcomponentReportInfo(sID,active,name);
      subcomponents.add(info);
  }

  try {
      dis.close();
      bis.close();
  } catch (Exception exe) {
      throw new RtpiParseException("RtCpiSubcomponentReportPacket: Could not close input stream for packet");
  }
    }

    void setSubcomponentReportInfo(int applicationLevelNames, LinkedList subs) throws IllegalValueException {
  subcomponents=subs;
  if (subcomponents==null || subcomponents.size()==0 || subcomponents.size()>31) {
      throw new IllegalValueException("RtcpiSubcomponentReportPacket: Can't set empty entries list");
  }

  reserved=applicationLevelNames;

  count = subcomponents.size();

  length = 1+subcomponents.size()*2; // 1 is for active list, header does not count towards length!

  if (reserved!=1) { // no application level names
      return;
  }
 
  SubcomponentReportInfo info = null;

  for(ListIterator iter=subcomponents.listIterator();iter.hasNext();) {
      info = (SubcomponentReportInfo) iter.next();
      byte[] name=info.getApplicationLevelName();
      if (name==null || name.length>255)
    throw new IllegalValueException("RtcpiSubcomponentReportPacket: no application level name present");
      int entryLength=name.length + 1; // without padding
      length += (entryLength+(4-entryLength%4)%4)/4; // with padding
  }
    }

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

    public LinkedList getSubcomponentReportInfo() {
  return subcomponents;
    }

    /**
     * This returns the application level names flag.
     *
     * @return The value of the application level names flag.
     */

    public int getApplicationLevelNames() {
  return reserved;
    }

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


    String toStringDetails() {
  String returnValue;
  returnValue=super.toStringDetails();
  SubcomponentReportInfo info = null;
  for(ListIterator iter=subcomponents.listIterator();iter.hasNext();) {
      info = (SubcomponentReportInfo) iter.next();
      returnValue+=info;
  }
  return returnValue;
    }
}

TOP

Related Classes of rtpi.packets.RtcpiSubcomponentReportPacket

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.