Bharat saraswal
Committed by Gerrit Code Review

[ONOS-2344]Implementation of PCEP report messages.

Change-Id: I9258a34ad7b09a583dcd0e56f90a36958c3acb34
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcepio.protocol.ver1;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepInterLayerObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/*
* 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |N|I|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
public class PcepInterLayerObjectVer1 implements PcepInterLayerObject {
protected static final Logger log = LoggerFactory.getLogger(PcepInterLayerObjectVer1.class);
public static final byte INTER_LAYER_OBJ_TYPE = 1;
public static final byte INTER_LAYER_OBJ_CLASS = 18;
public static final byte INTER_LAYER_OBJECT_VERSION = 1;
public static final short INTER_LAYER_OBJ_MINIMUM_LENGTH = 8;
public static final boolean DEFAULT_IFLAG = false;
public static final boolean DEFAULT_NFLAG = false;
public static final int OBJECT_HEADER_LENGTH = 4;
public static final int NFLAG_SHIFT_VALUE = 0x02;
public static final int IFLAG_SHIFT_VALUE = 0x01;
public static final int FLAGS_SET_VALUE = 1;
static final PcepObjectHeader DEFAULT_INTER_LAYER_OBJECT_HEADER = new PcepObjectHeader(INTER_LAYER_OBJ_CLASS,
INTER_LAYER_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
INTER_LAYER_OBJ_MINIMUM_LENGTH);
private PcepObjectHeader interLayerObjHeader;
private boolean bNFlag;
private boolean bIFlag;
/**
* Constructor to initialize all parameters for Pcep Inter Layer Object.
*
* @param interLayerObjHeader inter layer object header
* @param bNFlag N flag
* @param bIFlag I flag
*/
public PcepInterLayerObjectVer1(PcepObjectHeader interLayerObjHeader, boolean bNFlag, boolean bIFlag) {
this.interLayerObjHeader = interLayerObjHeader;
this.bNFlag = bNFlag;
this.bIFlag = bIFlag;
}
/**
* Sets Object Header.
*
* @param obj object header
*/
public void setInterLayerObjHeader(PcepObjectHeader obj) {
this.interLayerObjHeader = obj;
}
@Override
public void setbNFlag(boolean bNFlag) {
this.bNFlag = bNFlag;
}
@Override
public void setbIFlag(boolean bIFlag) {
this.bIFlag = bIFlag;
}
/**
* Returns object header.
*
* @return inter Layer Object Header
*/
public PcepObjectHeader getInterLayerObjHeader() {
return this.interLayerObjHeader;
}
@Override
public boolean getbNFlag() {
return this.bNFlag;
}
@Override
public boolean getbIFlag() {
return this.bIFlag;
}
/**
* Reads channel buffer and returns object of PcepInterLayerObject.
*
* @param cb of type channel buffer
* @return object of PcepInterLayerObject
* @throws PcepParseException when fails to read from channel buffer
*/
public static PcepInterLayerObject read(ChannelBuffer cb) throws PcepParseException {
PcepObjectHeader interLayerObjHeader;
boolean bNFlag;
boolean bIFlag;
interLayerObjHeader = PcepObjectHeader.read(cb);
//take only InterLayerObject buffer.
ChannelBuffer tempCb = cb.readBytes(interLayerObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
int iTemp = tempCb.readInt();
bIFlag = ((iTemp & (byte) IFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
bNFlag = ((iTemp & (byte) NFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
}
@Override
public int write(ChannelBuffer cb) throws PcepParseException {
//write Object header
int objStartIndex = cb.writerIndex();
int objLenIndex = interLayerObjHeader.write(cb);
if (objLenIndex <= 0) {
throw new PcepParseException(" ObjectLength Index is " + objLenIndex);
}
int iTemp = 0;
if (bIFlag) {
iTemp = iTemp | (byte) IFLAG_SHIFT_VALUE;
}
if (bNFlag) {
iTemp = iTemp | (byte) NFLAG_SHIFT_VALUE;
}
cb.writeInt(iTemp);
//Update object length now
int length = cb.writerIndex() - objStartIndex;
//will be helpful during print().
interLayerObjHeader.setObjLen((short) length);
cb.setShort(objLenIndex, (short) length);
objLenIndex = cb.writerIndex();
return objLenIndex;
}
/**
* Builder class for PCEP inter layer object.
*/
public static class Builder implements PcepInterLayerObject.Builder {
private boolean bIsHeaderSet = false;
private boolean bIsNFlagset = false;
private boolean bIsIFlagset = false;
private PcepObjectHeader interLayerObjHeader;
private boolean bNFlag;
private boolean bIFlag;
private boolean bIsPFlagSet = false;
private boolean bPFalg;
private boolean bIsIFlagSet = false;
private boolean iFlag;
@Override
public PcepInterLayerObject build() {
PcepObjectHeader interLayerObjHeader = this.bIsHeaderSet ? this.interLayerObjHeader
: DEFAULT_INTER_LAYER_OBJECT_HEADER;
boolean bNFlag = this.bIsNFlagset ? this.bNFlag : DEFAULT_NFLAG;
boolean bIFlag = this.bIsIFlagset ? this.bIFlag : DEFAULT_IFLAG;
if (bIsPFlagSet) {
interLayerObjHeader.setPFlag(bPFalg);
}
if (bIsIFlagSet) {
interLayerObjHeader.setIFlag(iFlag);
}
return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
}
@Override
public PcepObjectHeader getInterLayerObjHeader() {
return this.interLayerObjHeader;
}
@Override
public Builder setInterLayerObjHeader(PcepObjectHeader obj) {
this.interLayerObjHeader = obj;
this.bIsHeaderSet = true;
return this;
}
@Override
public boolean getbNFlag() {
return this.bNFlag;
}
@Override
public Builder setbNFlag(boolean value) {
this.bNFlag = value;
this.bIsNFlagset = true;
return this;
}
@Override
public boolean getbIFlag() {
return this.bIFlag;
}
@Override
public Builder setbIFlag(boolean value) {
this.bIFlag = value;
this.bIsIFlagset = true;
return this;
}
@Override
public Builder setPFlag(boolean value) {
this.bPFalg = value;
this.bIsPFlagSet = true;
return this;
}
@Override
public Builder setIFlag(boolean value) {
this.iFlag = value;
this.bIsIFlagSet = true;
return this;
}
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).add("IFlag", bIFlag).add("NFlag", bNFlag).toString();
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcepio.protocol.ver1;
import java.util.LinkedList;
import java.util.ListIterator;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.protocol.PcepMessageWriter;
import org.onosproject.pcepio.protocol.PcepReportMsg;
import org.onosproject.pcepio.protocol.PcepSrpObject;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepType;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
class PcepReportMsgVer1 implements PcepReportMsg {
// Pcep version: 1
/*
* The format of the PCRpt message is as follows:
* <PCRpt Message> ::= <Common Header>
* <state-report-list>
*Where:
* <state-report-list> ::= <state-report>[<state-report-list>]
* <state-report> ::= [<SRP>]
* <LSP>
* <path>
* Where:
* <path> ::= <ERO><attribute-list>[<RRO>]
* Where:
* <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
* where:
* <attribute-list> ::=[<LSPA>]
* [<BANDWIDTH>]
* [<metric-list>]
* [<IRO>]
* <metric-list> ::=<METRIC>[<metric-list>]
*/
protected static final Logger log = LoggerFactory.getLogger(PcepReportMsgVer1.class);
public static final byte PACKET_VERSION = 1;
//PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+LspObjMinLen(8)+EroObjMinLen(12)
public static final int PACKET_MINIMUM_LENGTH = 24;
public static final PcepType MSG_TYPE = PcepType.REPORT;
public static final byte REPORT_OBJ_TYPE = 1;
//Optional TLV
private LinkedList<PcepStateReport> llStateReportList;
public static final PcepReportMsgVer1.Reader READER = new Reader();
static class Reader implements PcepMessageReader<PcepReportMsg> {
LinkedList<PcepStateReport> llStateReportList;
@Override
public PcepReportMsg readFrom(ChannelBuffer cb) throws PcepParseException {
if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
throw new PcepParseException("Received packet size " + cb.readableBytes()
+ " is less than the expected size: " + PACKET_MINIMUM_LENGTH);
}
llStateReportList = new LinkedList<PcepStateReport>();
byte version = cb.readByte();
version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
if (version != PACKET_VERSION) {
throw new PcepParseException(" Invalid version: " + version);
}
byte type = cb.readByte();
if (type != MSG_TYPE.getType()) {
throw new PcepParseException("Unexpected type: " + type);
}
short length = cb.readShort();
if (length < PACKET_MINIMUM_LENGTH) {
throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: "
+ length);
}
// parse state report list
parseStateReportList(cb);
return new PcepReportMsgVer1(llStateReportList);
}
// Parse State Report list
public void parseStateReportList(ChannelBuffer cb) throws PcepParseException {
/*
<state-report-list>
Where:
<state-report-list> ::= <state-report>[<state-report-list>]
<state-report> ::= [<SRP>]
<LSP>
<path>
Where:
<path> ::= <ERO><attribute-list>[<RRO>]
Where:
<attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
*/
while (0 < cb.readableBytes()) {
PcepStateReport pcestateReq = new PcepStateReportVer1();
/*
* SRP is optional
* Check whether SRP Object is available, if yes store it.
* First read common object header and check the Object Class whether it is SRP or LSP
* If it is LSP then store only LSP. So, SRP is optional. then read path and store.
* If it is SRP then store SRP and then read LSP, path and store them.
*/
//mark the reader index to reset
cb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
byte yObjectClass = tempObjHeader.getObjClass();
byte yObjectType = tempObjHeader.getObjType();
//reset reader index
cb.resetReaderIndex();
//If SRP present then store it.
if ((PcepSrpObjectVer1.SRP_OBJ_CLASS == yObjectClass)
&& (PcepSrpObjectVer1.SRP_OBJ_TYPE == yObjectType)) {
PcepSrpObject srpObj;
srpObj = PcepSrpObjectVer1.read(cb);
pcestateReq.setSrpObject(srpObj);
}
//store LSP object
PcepLspObject lspObj;
lspObj = PcepLspObjectVer1.read(cb);
pcestateReq.setLspObject(lspObj);
//store path
PcepStateReport.PcepMsgPath msgPath = new PcepStateReportVer1().new PcepMsgPath().read(cb);
pcestateReq.setMsgPath(msgPath);
llStateReportList.add(pcestateReq);
}
}
}
/**
* Constructor to initialize State Report List.
*
* @param llStateReportList list of type Pcep state report
*/
PcepReportMsgVer1(LinkedList<PcepStateReport> llStateReportList) {
this.llStateReportList = llStateReportList;
}
/**
* Builder class for PCEP Report message.
*/
static class Builder implements PcepReportMsg.Builder {
// Pcep report message fields
LinkedList<PcepStateReport> llStateReportList;
@Override
public PcepVersion getVersion() {
return PcepVersion.PCEP_1;
}
@Override
public PcepType getType() {
return PcepType.REPORT;
}
@Override
public PcepReportMsg build() {
return new PcepReportMsgVer1(this.llStateReportList);
}
@Override
public LinkedList<PcepStateReport> getStateReportList() {
return this.llStateReportList;
}
@Override
public Builder setStateReportList(LinkedList<PcepStateReport> ll) {
this.llStateReportList = ll;
return this;
}
}
@Override
public void writeTo(ChannelBuffer cb) throws PcepParseException {
WRITER.write(cb, this);
}
static final Writer WRITER = new Writer();
static class Writer implements PcepMessageWriter<PcepReportMsgVer1> {
@Override
public void write(ChannelBuffer cb, PcepReportMsgVer1 message) throws PcepParseException {
int startIndex = cb.writerIndex();
// first 3 bits set to version
cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
// message type
cb.writeByte(MSG_TYPE.getType());
// length is length of variable message, will be updated at the end
// Store the position of message
// length in buffer
int msgLenIndex = cb.writerIndex();
cb.writeShort((short) 0);
ListIterator<PcepStateReport> listIterator = message.llStateReportList.listIterator();
while (listIterator.hasNext()) {
PcepStateReport stateRpt = listIterator.next();
PcepSrpObject srpObj = stateRpt.getSrpObject();
//SRP object is optional
if (null != srpObj) {
srpObj.write(cb);
}
//LSP object is mandatory
PcepLspObject lspObj = stateRpt.getLspObject();
if (lspObj == null) {
throw new PcepParseException("LSP Object is mandatory object for PcRpt message.");
} else {
lspObj.write(cb);
}
//path is mandatory
PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
if (msgPath == null) {
throw new PcepParseException("Message path is mandatory object for PcRpt message.");
} else {
msgPath.write(cb);
}
}
// update message length field
int length = cb.writerIndex() - startIndex;
cb.setShort(msgLenIndex, (short) length);
}
}
@Override
public PcepVersion getVersion() {
return PcepVersion.PCEP_1;
}
@Override
public PcepType getType() {
return MSG_TYPE;
}
@Override
public LinkedList<PcepStateReport> getStateReportList() {
return this.llStateReportList;
}
@Override
public void setStateReportList(LinkedList<PcepStateReport> ll) {
this.llStateReportList = ll;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).add("StateReportList", llStateReportList).toString();
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcepio.protocol.ver1;
import java.util.LinkedList;
import java.util.ListIterator;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepRroObject;
import org.onosproject.pcepio.types.IPv4SubObject;
import org.onosproject.pcepio.types.IPv6SubObject;
import org.onosproject.pcepio.types.LabelSubObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.onosproject.pcepio.types.PcepValueType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/*
* rfc3209
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Object-Class | OT |Res|P|I| Object Length (bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
// (Subobjects) //
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Each subobject has its own Length
field. The length contains the total length of the subobject in
bytes, including the Type and Length fields. The length MUST always
be a multiple of 4, and at least 4.
An empty RRO with no subobjects is considered illegal.
Three kinds of subobjects are currently defined.
Subobject 1: IPv4 address
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | IPv4 address (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IPv4 address (continued) | Prefix Length | Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Subobject 2: IPv6 address
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | IPv6 address (16 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IPv6 address (continued) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IPv6 address (continued) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IPv6 address (continued) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IPv6 address (continued) | Prefix Length | Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Subobject 3, Label
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Flags | C-Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Contents of Label Object |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
public class PcepRroObjectVer1 implements PcepRroObject {
protected static final Logger log = LoggerFactory.getLogger(PcepRroObjectVer1.class);
public static final byte RRO_OBJ_TYPE = 1;
public static final byte RRO_OBJ_CLASS = 8;
public static final byte RRO_OBJECT_VERSION = 1;
public static final short RRO_OBJ_MINIMUM_LENGTH = 12;
public static final int OBJECT_HEADER_LENGTH = 4;
public static final int YTYPE_SHIFT_VALUE = 0x7F;
static final PcepObjectHeader DEFAULT_RRO_OBJECT_HEADER = new PcepObjectHeader(RRO_OBJ_CLASS, RRO_OBJ_TYPE,
PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RRO_OBJ_MINIMUM_LENGTH);
private short rroObjType = 0;
private byte length;
private byte prefixLength;
private byte resvd;
PcepObjectHeader rroObjHeader;
private LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
/**
* Reset variables.
*/
public PcepRroObjectVer1() {
this.rroObjHeader = null;
this.rroObjType = 0;
this.length = 0;
}
/**
* constructor to initialize parameters for RRO object.
*
* @param rroObjHeader RRO object header
* @param llSubObjects list of sub objects
*/
public PcepRroObjectVer1(PcepObjectHeader rroObjHeader, LinkedList<PcepValueType> llSubObjects) {
this.rroObjHeader = rroObjHeader;
this.llSubObjects = llSubObjects;
}
/**
* Returns PCEP RRO Object Header.
*
* @return rroObjHeader RRO Object header
*/
public PcepObjectHeader getRroObjHeader() {
return this.rroObjHeader;
}
/**
* Sets PCEP RRO Object Header.
*
* @param obj Object header
*/
public void setRroObjHeader(PcepObjectHeader obj) {
this.rroObjHeader = obj;
}
@Override
public LinkedList<PcepValueType> getSubObjects() {
return this.llSubObjects;
}
@Override
public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
this.llSubObjects = llSubObjects;
}
/**
* Reads the channel buffer and returns object of PcepRroObject.
*
* @param cb of type channel buffer
* @return object of PcepRroObject
* @throws PcepParseException when fails to read from channel buffer
*/
public static PcepRroObject read(ChannelBuffer cb) throws PcepParseException {
PcepObjectHeader rroObjHeader;
LinkedList<PcepValueType> llSubObjects;
rroObjHeader = PcepObjectHeader.read(cb);
//take only RroObject buffer.
ChannelBuffer tempCb = cb.readBytes(rroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
llSubObjects = parseSubObjects(tempCb);
return new PcepRroObjectVer1(rroObjHeader, llSubObjects);
}
/**
* Returns list of sub objects.
*
* @param cb of type channel buffer
* @return list of sub objects
* @throws PcepParseException when fails to parse list of sub objects
*/
protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {
LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
while (0 < cb.readableBytes()) {
//check the Type of the Sub objects
byte yType = cb.readByte();
yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
byte hLength = cb.readByte();
PcepValueType subObj;
switch (yType) {
case IPv4SubObject.TYPE:
subObj = IPv4SubObject.read(cb);
break;
case IPv6SubObject.TYPE:
byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
subObj = new IPv6SubObject(ipv6Value);
break;
case LabelSubObject.TYPE:
subObj = LabelSubObject.read(cb);
break;
default:
throw new PcepParseException(" Unexpected sub object. Type: " + (int) yType);
}
// Check for the padding
int pad = hLength % 4;
if (0 < pad) {
pad = 4 - pad;
if (pad <= cb.readableBytes()) {
cb.skipBytes(pad);
}
}
llSubObjects.add(subObj);
}
return llSubObjects;
}
@Override
public int write(ChannelBuffer cb) throws PcepParseException {
//write Object header
int objStartIndex = cb.writerIndex();
int objLenIndex = rroObjHeader.write(cb);
if (objLenIndex <= 0) {
throw new PcepParseException(" object Length Index" + objLenIndex);
}
ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();
while (listIterator.hasNext()) {
listIterator.next().write(cb);
}
//Update object length now
int length = cb.writerIndex() - objStartIndex;
cb.setShort(objLenIndex, (short) length);
//will be helpful during print().
rroObjHeader.setObjLen((short) length);
//As per RFC the length of object should be multiples of 4
int pad = length % 4;
if (0 != pad) {
pad = 4 - pad;
for (int i = 0; i < pad; i++) {
cb.writeByte((byte) 0);
}
length = length + pad;
}
objLenIndex = cb.writerIndex();
return objLenIndex;
}
/**
* Builder class for PCEP RRO object.
*/
public static class Builder implements PcepRroObject.Builder {
private boolean bIsHeaderSet = false;
private PcepObjectHeader rroObjHeader;
LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
private boolean bIsPFlagSet = false;
private boolean bPFlag;
private boolean bIsIFlagSet = false;
private boolean bIFlag;
@Override
public PcepRroObject build() {
PcepObjectHeader rroObjHeader = this.bIsHeaderSet ? this.rroObjHeader : DEFAULT_RRO_OBJECT_HEADER;
if (bIsPFlagSet) {
rroObjHeader.setPFlag(bPFlag);
}
if (bIsIFlagSet) {
rroObjHeader.setIFlag(bIFlag);
}
return new PcepRroObjectVer1(rroObjHeader, this.llSubObjects);
}
@Override
public PcepObjectHeader getRroObjHeader() {
return this.rroObjHeader;
}
@Override
public Builder setRroObjHeader(PcepObjectHeader obj) {
this.rroObjHeader = obj;
this.bIsHeaderSet = true;
return this;
}
@Override
public LinkedList<PcepValueType> getSubObjects() {
return this.llSubObjects;
}
@Override
public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
this.llSubObjects = llSubObjects;
return this;
}
@Override
public Builder setPFlag(boolean value) {
this.bPFlag = value;
this.bIsPFlagSet = true;
return this;
}
@Override
public Builder setIFlag(boolean value) {
this.bIFlag = value;
this.bIsIFlagSet = true;
return this;
}
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).add("SubObjects", llSubObjects).toString();
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcepio.protocol.ver1;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepAttribute;
import org.onosproject.pcepio.protocol.PcepBandwidthObject;
import org.onosproject.pcepio.protocol.PcepEroObject;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepRroObject;
import org.onosproject.pcepio.protocol.PcepSrpObject;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
/**
* Provide the State Report for the Pcep Report Message.
* Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
*/
public class PcepStateReportVer1 implements PcepStateReport {
/*
* <state-report> ::= [<SRP>]
<LSP>
<path>
Where:
<path> ::= <ERO><attribute-list>[<RRO>]
*/
protected static final Logger log = LoggerFactory.getLogger(PcepStateReport.class);
public static final int OBJECT_HEADER_LENGTH = 4;
/**
* Provides PCEP Message path for report message.
*/
public class PcepMsgPath implements PcepStateReport.PcepMsgPath {
/*
* <path> ::= <ERO><attribute-list>[<RRO>]
*/
//PcepEroObject
private PcepEroObject eroObj;
private boolean isEroObjectSet;
//PcepAttribute List
private PcepAttribute attrList;
private boolean isAttributeListSet;
//PcepRroObject
private PcepRroObject rroObj;
private boolean isRroObjectSet;
private PcepBandwidthObject bandwidth;
private boolean isBandwidthObjectSet;
/**
* Constructor to reset the parameters.
*/
public PcepMsgPath() {
eroObj = null;
attrList = null;
rroObj = null;
this.isEroObjectSet = false;
this.isAttributeListSet = false;
this.isRroObjectSet = false;
this.isBandwidthObjectSet = false;
}
/**
* Constructor to initialize the parameters from PCEP Message path.
*
* @param eroObj PCEP ERO Object
* @param attrList PCEP Attribute
* @param rroObj PCEP Rro Object
*/
public PcepMsgPath(PcepEroObject eroObj, PcepAttribute attrList, PcepRroObject rroObj,
PcepBandwidthObject bandwidth) {
this.eroObj = eroObj;
this.attrList = attrList;
this.rroObj = rroObj;
this.bandwidth = bandwidth;
if (null == rroObj) {
this.isRroObjectSet = false;
} else {
this.isRroObjectSet = true;
}
if (null == eroObj) {
this.isEroObjectSet = false;
} else {
this.isEroObjectSet = true;
}
if (null == attrList) {
this.isAttributeListSet = false;
} else {
this.isAttributeListSet = true;
}
if (null == bandwidth) {
this.isBandwidthObjectSet = false;
} else {
this.isBandwidthObjectSet = true;
}
}
/**
* Returns PcepEroObject.
*
* @return eroObj PCEP ERO Object
*/
@Override
public PcepEroObject getEroObject() {
return this.eroObj;
}
/**
* Returns PCEP Attribute.
*
* @return attrList Attribute list
*/
@Override
public PcepAttribute getPcepAttribute() {
return this.attrList;
}
/**
* Returns PcepRroObject.
*
* @return rroObj PCEP RRO Object
*/
@Override
public PcepRroObject getRroObject() {
return this.rroObj;
}
@Override
public PcepBandwidthObject getBandwidthObject() {
return this.bandwidth;
}
@Override
public void setEroObject(PcepEroObject eroObj) {
this.eroObj = eroObj;
}
@Override
public void setPcepAttribute(PcepAttribute attrList) {
this.attrList = attrList;
}
@Override
public void setRroObject(PcepRroObject rroObj) {
this.rroObj = rroObj;
}
@Override
public void setBandwidthObject(PcepBandwidthObject bandwidth) {
this.bandwidth = bandwidth;
}
/**
* Reads all the Objects for PCEP Message Path.
*
* @param bb of type channel buffer
* @return PCEP Message path
* @throws PcepParseException when fails to read pcep message path
*/
@Override
public PcepMsgPath read(ChannelBuffer bb) throws PcepParseException {
PcepEroObject eroObj;
PcepAttribute attrList;
PcepRroObject rroObj = null;
PcepBandwidthObject bandwidth = null;
eroObj = PcepEroObjectVer1.read(bb);
attrList = PcepAttributeVer1.read(bb);
boolean bBreakWhile = false;
while (0 < bb.readableBytes()) {
if (bb.readableBytes() < OBJECT_HEADER_LENGTH) {
break;
}
bb.markReaderIndex();
PcepObjectHeader tempObjHeader = PcepObjectHeader.read(bb);
bb.resetReaderIndex();
byte yObjClass = tempObjHeader.getObjClass();
switch (yObjClass) {
case PcepRroObjectVer1.RRO_OBJ_CLASS:
rroObj = PcepRroObjectVer1.read(bb);
break;
case PcepInterLayerObjectVer1.INTER_LAYER_OBJ_CLASS:
bb.skipBytes(tempObjHeader.getObjLen());
break;
case PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS:
bandwidth = PcepBandwidthObjectVer1.read(bb);
break;
default:
//Otherthan above objects handle those objects in caller.
bBreakWhile = true;
break;
}
if (bBreakWhile) {
break;
}
}
return new PcepMsgPath(eroObj, attrList, rroObj, bandwidth);
}
/**
* Writes all the objects for PCEP message path.
*
* @param bb of type channel buffer.
* @return object length index
* @throws PcepParseException when fails to write to channel buffer
*/
@Override
public int write(ChannelBuffer bb) throws PcepParseException {
int iLenStartIndex = bb.writerIndex();
//write Object header
if (this.isEroObjectSet) {
this.eroObj.write(bb);
} else {
throw new PcepParseException("Ero object is not set in path");
}
if (this.isAttributeListSet) {
this.attrList.write(bb);
}
// RRO is optional check and read
if (this.isRroObjectSet) {
this.rroObj.write(bb);
// bandwidth should come along with RRO.
if (this.isBandwidthObjectSet) {
this.bandwidth.write(bb);
}
}
return bb.writerIndex() - iLenStartIndex;
}
@Override
public String toString() {
ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
if (attrList instanceof PcepAttribute) {
toStrHelper.add("AttributeList", attrList);
}
if (rroObj instanceof PcepRroObjectVer1) {
toStrHelper.add("RroObject", rroObj);
}
if (bandwidth instanceof PcepBandwidthObjectVer1) {
toStrHelper.add("bandwidthObject", bandwidth);
}
return toStrHelper.toString();
}
}
//SRP Object
private PcepSrpObject srpObject;
//LSP Object
private PcepLspObject lspObject;
//PcepMsgPath
private PcepStateReport.PcepMsgPath msgPath;
/**
* Constructor to reset objects.
*/
public PcepStateReportVer1() {
this.srpObject = null;
this.lspObject = null;
this.msgPath = null;
}
public PcepStateReportVer1(PcepSrpObject srpObject, PcepLspObject lspObject, PcepStateReport.PcepMsgPath msgPath) {
this.srpObject = srpObject;
this.lspObject = lspObject;
this.msgPath = msgPath;
}
@Override
public PcepSrpObject getSrpObject() {
return srpObject;
}
@Override
public PcepLspObject getLspObject() {
return lspObject;
}
@Override
public PcepStateReport.PcepMsgPath getMsgPath() {
return msgPath;
}
@Override
public void setSrpObject(PcepSrpObject srpObj) {
this.srpObject = srpObj;
}
@Override
public void setLspObject(PcepLspObject lspObject) {
this.lspObject = lspObject;
}
@Override
public void setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
this.msgPath = msgPath;
}
/**
* Builder class for PCEP state report.
*/
public static class Builder implements PcepStateReport.Builder {
private boolean bIsSRPObjectSet = false;
private boolean bIsLSPObjectSet = false;
private boolean bIsPcepMsgPathSet = false;
//PCEP SRP Object
private PcepSrpObject srpObject;
//PCEP LSP Object
private PcepLspObject lspObject;
//PCEP Attribute list
private PcepStateReport.PcepMsgPath msgPath;
@Override
public PcepStateReport build() throws PcepParseException {
//PCEP SRP Object
PcepSrpObject srpObject = null;
//PCEP LSP Object
PcepLspObject lspObject = null;
//PCEP Attribute list
PcepStateReport.PcepMsgPath msgPath = null;
if (this.bIsSRPObjectSet) {
srpObject = this.srpObject;
}
if (!this.bIsLSPObjectSet) {
throw new PcepParseException(" LSP Object NOT Set while building PcepStateReport.");
} else {
lspObject = this.lspObject;
}
if (!this.bIsPcepMsgPathSet) {
throw new PcepParseException(" Message Path NOT Set while building PcepStateReport.");
} else {
msgPath = this.msgPath;
}
return new PcepStateReportVer1(srpObject, lspObject, msgPath);
}
@Override
public PcepSrpObject getSrpObject() {
return this.srpObject;
}
@Override
public PcepLspObject getLspObject() {
return this.lspObject;
}
@Override
public PcepStateReport.PcepMsgPath getMsgPath() {
return this.msgPath;
}
@Override
public Builder setSrpObject(PcepSrpObject srpobj) {
this.srpObject = srpobj;
this.bIsSRPObjectSet = true;
return this;
}
@Override
public Builder setLspObject(PcepLspObject lspObject) {
this.lspObject = lspObject;
this.bIsLSPObjectSet = true;
return this;
}
@Override
public Builder setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
this.msgPath = msgPath;
this.bIsPcepMsgPathSet = true;
return this;
}
}
@Override
public String toString() {
ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
if (this.srpObject instanceof PcepSrpObject) {
toStrHelper.add("SrpObject", srpObject);
}
if (this.lspObject instanceof PcepLspObject) {
toStrHelper.add("LspObject", lspObject);
}
if (this.msgPath instanceof PcepStateReport.PcepMsgPath) {
toStrHelper.add("MsgPath", msgPath);
}
return toStrHelper.toString();
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcepio.types;
import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/**
* LabelSubObject: Provides a LabelSubObject.
*/
public class LabelSubObject implements PcepValueType {
/* Reference : RFC 3209
* LABEL Sub Object
*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Flags | C-Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Contents of Label Object |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
protected static final Logger log = LoggerFactory.getLogger(LabelSubObject.class);
public static final short TYPE = 0x03;
public static final short LENGTH = 8;
private final byte flags;
private final byte cType;
private final int contents;
/**
* constructor to initialize parameters for LabelSubObject.
*
* @param flags flags
* @param cType C-Type
* @param contents Contents of label object
*/
public LabelSubObject(byte flags, byte cType, int contents) {
this.flags = flags;
this.cType = cType;
this.contents = contents;
}
/**
* Return an object of LabelSubObject.
*
* @param flags flags
* @param cType C-type
* @param contents contents of label objects
* @return object of LabelSubObject
*/
public static LabelSubObject of(byte flags, byte cType, int contents) {
return new LabelSubObject(flags, cType, contents);
}
/**
* Returns Flags.
*
* @return flags
*/
public byte getFlags() {
return flags;
}
/**
* Returns cType.
*
* @return cType
*/
public byte getCtype() {
return cType;
}
/**
* Returns contents.
*
* @return contents
*/
public int getContents() {
return contents;
}
@Override
public PcepVersion getVersion() {
return PcepVersion.PCEP_1;
}
@Override
public short getType() {
return TYPE;
}
@Override
public short getLength() {
return LENGTH;
}
@Override
public int hashCode() {
return Objects.hash(flags, cType, contents);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof LabelSubObject) {
LabelSubObject other = (LabelSubObject) obj;
return Objects.equals(this.flags, other.flags) && Objects.equals(this.cType, other.cType)
&& Objects.equals(this.contents, other.contents);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iStartIndex = c.writerIndex();
c.writeShort(TYPE);
c.writeShort(LENGTH);
c.writeByte(flags);
c.writeByte(cType);
c.writeByte(contents);
return c.writerIndex() - iStartIndex;
}
/**
* Reads the channel buffer and returns object of LabelSubObject.
*
* @param c type of channel buffer
* @return object of LabelSubObject
*/
public static PcepValueType read(ChannelBuffer c) {
byte flags = c.readByte();
byte cType = c.readByte();
int contents = c.readInt();
return new LabelSubObject(flags, cType, contents);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).add("type", TYPE).add("Length", LENGTH).add("flags", flags)
.add("C-type", cType).add("contents", contents).toString();
}
}