Package rtpi

Source Code of rtpi.RtpiData

/* 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;

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.IOException;

import java.net.InetAddress;

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

import rtpi.packets.RtpiDataPacket;

/**
* This is the base class for RTPI ADUs.
* In order to put data into an ADU please use the getOutputStream
* method. After the data has been written from the returned output
* stream call the outputComplete method.
* In order to read data from an ADU please use the getInputStream
* method. The data can then be read from the input stream.
*
* @author Martin Mauve
*/

public abstract class RtpiData {

    // RTPI information:
    int    type=RtpiDataPacket.ILLEGAL_TYPE;
    int    payloadType=RtpiDataPacket.ILLEGAL_PAYLOAD_TYPE;
    int    priority=0;
    byte   profileInformation=0x0;
    int    participantID=0;
    long   subcomponentID=0;
    int    sequenceNumber=0;
    long   timestamp=0;

    // Constants

    static final int MAX_SEQU_NO = 0xFFFF;
    static final long MAX_TIMESTAMP = 0x00000000FFFFFFFFl;
    static final int MAX_PRIORITY = 3;
    static final int MAX_TYPE = 31;
    static final int MAX_PAYLOAD_TYPE = 0xFF;

    byte[] payload;
    int payloadStart;
    int payloadLength;

    ByteArrayOutputStream outStream=null;
    ByteArrayInputStream inStream=null;

    float redundancy=0;
    int redundancyTransmissionInterval=0;

    /**
     * Create a new ADU for the transmission over the
     * network.
     *
     * @param pID The ID of the local participant.
     * @param subID The ID of the affected subcomponent.
     * @param t The type of the ADU (e.g. EVENT, STATE, etc.).
     * @param seqNo The sequence number of the ADU.
     * @param pType The payload type of the ADU.
     * @param pri The priority of the ADU.
     * @param ts The timestamp of the ADU. The value will be
     *           automatically clipped to a 32 bit value;
     * @param pls The amount of bytes required for the combined RTP/I
     *            packet header (rtpi.packets.RtpiDataPacket.HEADER_SIZE)
     *            and the reliability header (depending on the reliability
     *            mechanism) used. If this value is not caluclated correctly
     *            then the packet will have to be copied one additional time
     *            before it can be sent. This decreases efficiency but should
     *            still work. There is a utility function Rtpi.getCombinedHeaderSize
     *            which returns this value.
     */

    RtpiData(int pID,
       long subID,
       int t,
       int seqNo,
       int pType,
       int pri,
       long ts,
       int pls
       ) throws IllegalValueException {

  participantID=pID;

  subcomponentID=subID;

  if (t<0 || t> MAX_TYPE) {
      throw new IllegalValueException("RtpiData: type not in valid range!");
  }
  type=t;

  if (seqNo < 0 || seqNo> MAX_SEQU_NO) {
      throw new IllegalValueException("RtpiData: sequence number not in valid range!");
  }
  sequenceNumber=seqNo;

  if (pType < 0 || pType> MAX_PAYLOAD_TYPE) {
      throw new IllegalValueException("RtpiData: payload type not in valid range!");
  }
  payloadType=pType;

  if (pri < 0 || pri > MAX_PRIORITY) {
      throw new IllegalValueException("RtpiData: priority not in valid range!");
  }
  priority=pri;

  timestamp=ts&MAX_TIMESTAMP;

  payloadStart=pls;
    }

    /**
     * Create a new ADU from a single received packet.
     */

    RtpiData(RtpiDataPacket packet) {
  extractInfoFromPacket(packet);
  payload=packet.getPacketData();
  payloadStart=packet.getPayloadStart();
  payloadLength=packet.getPayloadLength();
    }

    /**
     * Create a new ADU from a list of  received packets.
     */

    RtpiData(LinkedList list) {
  ListIterator it = list.listIterator();
  int totalLength=0;
  while(it.hasNext()) {
      totalLength += ((RtpiDataPacket) it.next()).getPayloadLength();
  }

  payload = new byte[totalLength];
 
  it = list.listIterator();
   
  RtpiDataPacket packet=(RtpiDataPacket)it.next();
  extractInfoFromPacket(packet);

  byte[] tmpData = packet.getPacketData();
  int curSize = packet.getPayloadLength();

  System.arraycopy(tmpData,packet.getPayloadStart(), payload, 0, curSize);
  int position=curSize;

  while(it.hasNext()) {
      packet=(RtpiDataPacket)it.next();
      tmpData = packet.getPacketData();
      curSize = packet.getPayloadLength();
      System.arraycopy(tmpData, packet.getPayloadStart(), payload, position, curSize);     
      position += curSize;
  }

  payloadLength=position;
  payloadStart=0;
    }

    void extractInfoFromPacket(RtpiDataPacket packet) {
  type=packet.getType();
  payloadType=packet.getPayloadType();
  priority=packet.getPriority();
  profileInformation=packet.getProfileInformation();
  participantID=packet.getParticipantID();
  subcomponentID=packet.getSubcomponentID();
  sequenceNumber=packet.getSequenceNumber();
  timestamp=packet.getTimestamp();
    }

    /**
     * This sets the amount of redundancy for the transmission
     * of the ADU. The reliability service used must support
     * this amount of reliability.
     *
     * @param r The amount of redundancy.
     */

    public void setRedundancy(float r) {
  redundancy=r;
    }

    float getRedundancy() {
  return redundancy;
    }

    /**
     * This sets the interval during which redundancy information
     * may be transmitted for this ADU.
     */

    public void setRedundancyTransmissionInterval(int t) {
  redundancyTransmissionInterval=t;
    }

    int getRedundancyTransmissionInterval() {
  return redundancyTransmissionInterval;
    }

    /**
     * This returns the payload type of the ADU.
     *
     * @return The payload type.
     */

    public int getPayloadType() {
  return payloadType;
    }

    /**
     * This returns the priority of the ADU.
     *
     * @return The priority.
     */

    public int getPriority() {
  return priority;
    }

    /**
     * This returns the profile specific information
     * contained ADU.
     *
     * @return The profile information.
     */

     public byte getProfileInformation() {
  return profileInformation;
    }

    /**
     * This sets the profile specific information for
     * the ADU.
     *
     * @param pi The profile specific information.
     */

    public void setProfileInformation(byte pi) {
  profileInformation=pi;
    }

    /**
     * This returns the participant ID of this ADU's
     * sender.
     *
     * @return The sender's ID.
     */
   
    public int getParticipantID() {
  return participantID;
    }

    /**
     * This returns the ID of the affected subcomponent.
     *
     * @return The subcomponent ID.
     */
    public long getSubcomponentID() {
  return subcomponentID;
    }

    /**
     * This gets the sequence number of the ADU.
     *
     * @return This ADU's sequence number.
     */

    public int getSequenceNumber() {
  return sequenceNumber;
    }

    /**
     * This returns the timestamp of the ADU.
     *
     * @return The timestamp.
     */

    public long getTimestamp() {
  return timestamp;
    }

    /**
     * This returns an output stream to this RtpiData object. This stream should be used
     * to put the data in the ADU. After finishing writing to the RtpiData object,
     * outputComplete MUST be called on this object.
     *
     * @return The OutputStream.
     */

    public OutputStream getOutputStream() throws IOException {
  outStream = new ByteArrayOutputStream();
  byte[] dummyHeader = new byte[payloadStart];
  outStream.write(dummyHeader,0,dummyHeader.length);
  return outStream;
    }
   
    /**
     * This MUST be called when the output to the RtpiData object is finished.
     */

    public void outputComplete() {
  try {
      outStream.flush();
      payload = outStream.toByteArray();
      outStream.close();
  } catch (IOException exception) {
      System.err.println("RTPIMessage: "+exception);
  }
  payloadLength=payload.length-payloadStart;
    }


    /**
     * This returns an input stream to this RtpiData object. This stream should be used
     * to read data from a received ADU.
     *
     * @return The InputStream.
     */

    public ByteArrayInputStream getInputStream() {
  ByteArrayInputStream bin = new ByteArrayInputStream(payload,payloadStart, payloadLength);
  return bin;
    }

    LinkedList packetize(int transportPayloadSize) {
  LinkedList packets=new LinkedList();
  int bytesWritten=0;
  RtpiDataPacket packet=null;

  if (payloadLength+payloadStart<transportPayloadSize) {
      packet=new RtpiDataPacket(payload, payloadStart, payloadLength);
      setPacketFields(packet, 0, 1);
      packets.add(packet);
      return packets;
  }     

  int bytesInThisPacket=0;
  byte[] packetData=null;
  int fragmentCount=0;

  while (bytesWritten<payloadLength) {
      if (payloadLength-bytesWritten+payloadStart<transportPayloadSize) {
    bytesInThisPacket=payloadLength-bytesWritten+payloadStart;
      } else {
    bytesInThisPacket=transportPayloadSize;
      }

      packetData=new byte[bytesInThisPacket];
      System.arraycopy(payload, bytesWritten+payloadStart, packetData, payloadStart, bytesInThisPacket-payloadStart);
      packet = new RtpiDataPacket(packetData,payloadStart, bytesInThisPacket-payloadStart);
      setPacketFields(packet, fragmentCount, 0);
      fragmentCount++;
      packets.add(packet);
      bytesWritten+=bytesInThisPacket-payloadStart;
  }
  packet.setEnd(1);
  return packets;
    }

    void setPacketFields(RtpiDataPacket packet, int fragmentCount, int end) {
  packet.setFragmentCount(fragmentCount);
  packet.setEnd(end);
  packet.setType(type);
  packet.setPayloadType(payloadType);
  packet.setPriority(priority);
  packet.setProfileInformation(profileInformation);
  packet.setParticipantID(participantID);
  packet.setSubcomponentID(subcomponentID);
  packet.setSequenceNumber(sequenceNumber);
  packet.setTimestamp(timestamp);
    }

}


TOP

Related Classes of rtpi.RtpiData

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.