/** * @copyright 2013 Computer Science Department, Recursive InterNetworking Architecture (RINA) laboratory, Boston University. * All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation * for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all * copies and that both the copyright notice and this permission notice appear in supporting documentation. * The RINA laboratory of the Computer Science Department at Boston University makes no * representations about the suitability of this software for any purpose. */ package rina.message; import java.nio.ByteBuffer; import java.nio.ByteOrder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** //PDU types #define PDU_TYPE_EFCP 0x80 //DATA - DTP + user data - SDU #define PDU_TYPE_DATA 0x81 //CONTROL - DTCP - PDUs go from 0x82 to 0x8F #define PDU_TYPE_CONTROL 0x82 #define PDU_TYPE_SELECTIVE_ACK 0x84 #define PDU_TYPE_NACK 0x86 #define PDU_TYPE_FLOW_ONLY 0x89 #define PDU_TYPE_ACK_ONLY 0x8C #define PDU_TYPE_FLOW_ACK 0x8D //MANAGEMENT PDUs contain CDAP #define PDU_TYPE_MANAGEMENT 0xC0 #define PDU_TYPE_IDENTIFYSENDER 0xC1 // used for PDU to send over TCP connection to identify sender **/ /** * This is an implementation of DTP message, which defines the header format * @author Yuefeng Wang and Flavio Esposito. Computer Science Department, Boston University * */ public class DTP { private Log log = LogFactory.getLog(DTP.class); private short destAddr; //2 bytes private short srcAddr; //2 bytes private short destCEPid;//2 bytes private short srcCEPid; //2 bytes private byte qosid; // 1 byte private byte pdu_type; //1 bytes private byte flags; //1 bytes private int seqNum; //4 private byte[] payload; private int length; public DTP (short destAddr, short srcAddr, short destCEPid, short srcCEPid, byte qosid, byte pdu_type, byte flags, int seqNum, byte[] payload) { this.destAddr = destAddr; this.srcAddr = srcAddr; this.destCEPid = destCEPid; this.srcCEPid = srcCEPid; this.qosid = qosid; this.pdu_type = pdu_type; this.flags = flags; this.seqNum = seqNum; this.payload = payload; this.length = 15 + this.payload.length; } public DTP ( short destAddr, short srcAddr, short destCEPid, short srcCEPid, byte pdu_type, byte[] payload) { this.destAddr = destAddr; this.srcAddr = srcAddr; this.destCEPid = destCEPid; this.srcCEPid = srcCEPid; this.qosid = 1; this.pdu_type = pdu_type; this.flags = 0; this.seqNum = 0; this.payload = payload; this.length = 15 + this.payload.length; } public DTP ( short destAddr, short srcAddr, short destCEPid, short srcCEPid, byte[] payload) { this.destAddr = destAddr; this.srcAddr = srcAddr; this.destCEPid = destCEPid; this.srcCEPid = srcCEPid; this.qosid = 1; this.flags = 0; this.seqNum = 0; this.payload = payload; this.length = 15 + this.payload.length; } public DTP ( short destAddr, short srcAddr, short destCEPid, short srcCEPid, byte pdu_type) { this.destAddr = destAddr; this.srcAddr = srcAddr; this.destCEPid = destCEPid; this.srcCEPid = srcCEPid; this.qosid = 1; this.pdu_type = pdu_type; this.flags = 0; this.seqNum = 0; this.length = 15; } /** * Construct a DTP message from bytes received, this will be used on the receiving side * @param bytes */ public DTP(byte[] bytes) { ByteBuffer buf = ByteBuffer.wrap(bytes, 0, 15); buf.order(ByteOrder.LITTLE_ENDIAN); this.destAddr = buf.getShort(0); //2 bytes this.srcAddr = buf.getShort(2); //2 bytes this.destCEPid = buf.getShort(4);//2 bytes this.srcCEPid = buf.getShort(6); //2 bytes this.qosid = buf.get(8); // 1 byte this.pdu_type = buf.get(9); //1 bytes // this.pdu_type = (byte) (this.pdu_type & 0xFF); // converted to 0x this.flags = buf.get(10); //1 bytes this.seqNum = buf.getInt(11); //4 this.payload = this.getPayloadFromBytes(bytes); this.length = bytes.length; } /** * Construct a DTP message from a CDAP message * @param cdapMessage */ public DTP(CDAP.CDAPMessage cdapMessage) { this.destAddr = 0; this.srcAddr = 0; this.destCEPid = 0; this.srcCEPid = 0; this.qosid = 0; this.pdu_type = (byte)0xC0;//CDAP this.flags = 0; this.seqNum = 0; this.payload = cdapMessage.toByteArray(); this.length = 15 + this.payload.length; } /** * This one is used for BU DIF0 case * In this case, address is not used, only portID(or CEPid) * @param srcCEPid * @param destCEPid * @param msg */ public DTP(short srcCEPid, short destCEPid, byte[] msg) { this.destAddr = 0; this.srcAddr = 0; this.destCEPid = destCEPid; this.srcCEPid = srcCEPid; this.qosid = 0; this.flags = 0; this.seqNum = 0; this.payload = msg; this.length = 15 + this.payload.length; } public byte[] toBytes() { byte[] result = null; ByteBuffer bbuf = ByteBuffer.allocate(length); bbuf.order(ByteOrder.LITTLE_ENDIAN); bbuf.putShort(this.destAddr); bbuf.putShort(this.srcAddr); bbuf.putShort(this.destCEPid); bbuf.putShort(this.srcCEPid); bbuf.put(this.qosid); bbuf.put(this.pdu_type); bbuf.put(this.flags); bbuf.putInt(this.seqNum); if(this.payload !=null) { bbuf.put(this.payload); } result = bbuf.array(); return result; } private byte[] getPayloadFromBytes (byte[] msg) { int length = msg.length; byte[] payload = new byte[length-15]; for(int i =0; i<length -15; i++) { payload[i] = msg[15+i]; } return payload; } public void printDTPHeader() { log.debug("DTP Header: destAddr:" + destAddr + ", srcAddr: " + srcAddr + ", destCEPid: " + destCEPid + ", srcCEPid: " + srcCEPid + ",qosid: " + qosid + ", pdu_type: " + Integer.toHexString( (byte) pdu_type & 0xFF ) + ", seqNum is " + seqNum); } public synchronized Log getLog() { return log; } public synchronized void setLog(Log log) { this.log = log; } public synchronized short getDestAddr() { return destAddr; } public synchronized void setDestAddr(short destAddr) { this.destAddr = destAddr; } public synchronized short getSrcAddr() { return srcAddr; } public synchronized void setSrcAddr(short srcAddr) { this.srcAddr = srcAddr; } public synchronized short getDestCEPid() { return destCEPid; } public synchronized void setDestCEPid(short destCEPid) { this.destCEPid = destCEPid; } public synchronized short getSrcCEPid() { return srcCEPid; } public synchronized void setSrcCEPid(short srcCEPid) { this.srcCEPid = srcCEPid; } public synchronized byte getQosid() { return qosid; } public synchronized void setQosid(byte qosid) { this.qosid = qosid; } public synchronized byte getPdu_type() { return pdu_type; } public synchronized void setPdu_type(byte pdu_type) { this.pdu_type = pdu_type; } public synchronized byte getFlags() { return flags; } public synchronized void setFlags(byte flags) { this.flags = flags; } public synchronized int getSeqNum() { return seqNum; } public synchronized void setSeqNum(int seqNum) { this.seqNum = seqNum; } public synchronized byte[] getPayload() { return payload; } public synchronized void setPayload(byte[] payload) { this.payload = payload; } public synchronized int getLength() { return length; } public synchronized void setLength(int length) { this.length = length; } }