/* | |
* 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.LinkedList; | |
import java.util.ListIterator; | |
import org.jboss.netty.buffer.ChannelBuffer; | |
import org.onosproject.pcepio.exceptions.PcepParseException; | |
import org.onosproject.pcepio.protocol.PcepVersion; | |
import com.google.common.base.MoreObjects; | |
/** | |
* Provides Pcep Rsvp User Error Spec. | |
*/ | |
public class PcepRsvpUserErrorSpec implements PcepRsvpErrorSpec { | |
/* | |
RSVP error spec object header. | |
0 1 2 3 | |
+-------------+-------------+-------------+-------------+ | |
| Length (bytes) | Class-Num | C-Type | | |
+-------------+-------------+-------------+-------------+ | |
| | | |
// (Object contents) // | |
| | | |
+-------------+-------------+-------------+-------------+ | |
Ref : USER_ERROR_SPEC @ RFC5284. | |
USER_ERROR_SPEC object: Class = 194, C-Type = 1 | |
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 | |
+---------------+---------------+---------------+---------------+ | |
| Enterprise Number | | |
+---------------+---------------+---------------+---------------+ | |
| Sub Org | Err Desc Len | User Error Value | | |
+---------------+---------------+---------------+---------------+ | |
| | | |
~ Error Description ~ | |
| | | |
+---------------+---------------+---------------+---------------+ | |
| | | |
~ User-Defined Subobjects ~ | |
| | | |
+---------------+---------------+---------------+---------------+ | |
*/ | |
public static final byte CLASS_NUM = (byte) 0xc2; | |
public static final byte CLASS_TYPE = 0x01; | |
private PcepRsvpSpecObjHeader objHeader; | |
private int enterpriseNum; | |
private byte subOrg; | |
private byte errDescLen; | |
private short userErrorValue; | |
private byte[] errDesc; | |
private LinkedList<PcepValueType> llRsvpUserSpecSubObj; | |
/** | |
* Default constructor. | |
* | |
* @param objHeader pcep rsvp spec object header | |
* @param enterpriseNum enterprise number | |
* @param subOrg organization identifier value | |
* @param errDescLen error description length | |
* @param userErrorValue user error value | |
* @param errDesc error description | |
* @param llRsvpUserSpecSubObj list of subobjects | |
*/ | |
public PcepRsvpUserErrorSpec(PcepRsvpSpecObjHeader objHeader, int enterpriseNum, byte subOrg, byte errDescLen, | |
short userErrorValue, byte[] errDesc, LinkedList<PcepValueType> llRsvpUserSpecSubObj) { | |
this.objHeader = objHeader; | |
this.enterpriseNum = enterpriseNum; | |
this.subOrg = subOrg; | |
this.errDescLen = errDescLen; | |
this.userErrorValue = userErrorValue; | |
this.errDesc = errDesc; | |
this.llRsvpUserSpecSubObj = llRsvpUserSpecSubObj; | |
} | |
@Override | |
public int write(ChannelBuffer cb) { | |
int objLenIndex = objHeader.write(cb); | |
cb.writeInt(enterpriseNum); | |
cb.writeByte(subOrg); | |
cb.writeByte(errDescLen); | |
cb.writeShort(userErrorValue); | |
cb.writeBytes(errDesc); | |
if (null != llRsvpUserSpecSubObj) { | |
ListIterator<PcepValueType> listIterator = llRsvpUserSpecSubObj.listIterator(); | |
while (listIterator.hasNext()) { | |
PcepValueType tlv = listIterator.next(); | |
if (null == tlv) { | |
continue; | |
} | |
tlv.write(cb); | |
// need to take care of padding | |
int pad = tlv.getLength() % 4; | |
if (0 != pad) { | |
pad = 4 - pad; | |
for (int i = 0; i < pad; ++i) { | |
cb.writeByte((byte) 0); | |
} | |
} | |
} | |
} | |
short objLen = (short) (cb.writerIndex() - objLenIndex); | |
cb.setShort(objLenIndex, objLen); | |
return objLen; | |
} | |
/** | |
* Reads the channel buffer and returns object of PcepRsvpErrorSpec. | |
* | |
* @param cb of type channel buffer | |
* @return object of PcepRsvpErrorSpec | |
* @throws PcepParseException when expected object is not received | |
*/ | |
public static PcepRsvpErrorSpec read(ChannelBuffer cb) throws PcepParseException { | |
PcepRsvpSpecObjHeader objHeader; | |
int enterpriseNum; | |
byte subOrg; | |
byte errDescLen; | |
short userErrorValue; | |
byte[] errDesc; | |
LinkedList<PcepValueType> llRsvpUserSpecSubObj = null; | |
objHeader = PcepRsvpSpecObjHeader.read(cb); | |
if (CLASS_NUM != objHeader.getObjClassNum() || CLASS_TYPE != objHeader.getObjClassType()) { | |
throw new PcepParseException("Expected PcepRsvpUserErrorSpec object."); | |
} | |
enterpriseNum = cb.readInt(); | |
subOrg = cb.readByte(); | |
errDescLen = cb.readByte(); | |
userErrorValue = cb.readShort(); | |
errDesc = new byte[errDescLen]; | |
cb.readBytes(errDesc, 0, errDescLen); | |
llRsvpUserSpecSubObj = parseErrSpecSubObj(cb); | |
return new PcepRsvpUserErrorSpec(objHeader, enterpriseNum, subOrg, errDescLen, userErrorValue, errDesc, | |
llRsvpUserSpecSubObj); | |
} | |
private static LinkedList<PcepValueType> parseErrSpecSubObj(ChannelBuffer cb) throws PcepParseException { | |
LinkedList<PcepValueType> llRsvpUserSpecSubObj = new LinkedList<PcepValueType>(); | |
while (0 < cb.readableBytes()) { | |
PcepValueType tlv = null; | |
short hType = cb.readShort(); | |
int iValue = 0; | |
//short hLength = cb.readShort(); | |
switch (hType) { | |
case AutonomousSystemTlv.TYPE: | |
iValue = cb.readInt(); | |
tlv = new AutonomousSystemTlv(iValue); | |
break; | |
default: | |
throw new PcepParseException("Unsupported Sub TLV type :" + hType); | |
} | |
llRsvpUserSpecSubObj.add(tlv); | |
} | |
return llRsvpUserSpecSubObj; | |
} | |
@Override | |
public PcepVersion getVersion() { | |
return PcepVersion.PCEP_1; | |
} | |
@Override | |
public short getType() { | |
return StatefulRsvpErrorSpecTlv.TYPE; | |
} | |
@Override | |
public short getLength() { | |
return objHeader.getObjLen(); | |
} | |
@Override | |
public byte getClassNum() { | |
return CLASS_NUM; | |
} | |
@Override | |
public byte getClassType() { | |
return CLASS_TYPE; | |
} | |
@Override | |
public String toString() { | |
return MoreObjects.toStringHelper(getClass()) | |
.add("enterpriseNumber:", enterpriseNum) | |
.add("subOrganization:", subOrg) | |
.add("errDescLength:", errDescLen) | |
.add("userErrorValue:", userErrorValue) | |
.add("errDesc:", errDesc) | |
.add("RsvpUserSpecSubObject:", llRsvpUserSpecSubObj) | |
.toString(); | |
} | |
} |