blob: 9e1a074a9c97ce1356df92b9bfdd0885f759cbf1 [file] [log] [blame]
/*
* 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.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/**
* Provides StatefulRsvpErrorSpecTlv.
*/
public class StatefulRsvpErrorSpecTlv implements PcepValueType {
protected static final Logger log = LoggerFactory.getLogger(StatefulRsvpErrorSpecTlv.class);
/* RSVP-ERROR-SPEC TLV format
* Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
*
*
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=21 | Length (variable) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ RSVP ERROR_SPEC or USER_ERROR_SPEC Object +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1 2 3
+-------------+-------------+-------------+-------------+
| Length (bytes) | Class-Num | C-Type |
+-------------+-------------+-------------+-------------+
| |
// (Object contents) //
| |
+-------------+-------------+-------------+-------------+
Ref : ERROR_SPEC @ RFC2205
IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
+-------------+-------------+-------------+-------------+
| IPv4 Error Node Address (4 bytes) |
+-------------+-------------+-------------+-------------+
| Flags | Error Code | Error Value |
+-------------+-------------+-------------+-------------+
IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
+-------------+-------------+-------------+-------------+
| |
+ +
| |
+ IPv6 Error Node Address (16 bytes) +
| |
+ +
| |
+-------------+-------------+-------------+-------------+
| Flags | Error Code | Error Value |
+-------------+-------------+-------------+-------------+
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 short TYPE = 21;
public static final int OBJECT_HEADER_LENGTH = 4;
private short hLength;
private final PcepRsvpErrorSpec rsvpErrSpecObj;
private final boolean isErrSpceObjSet;
/**
* Constructor to initialize errSpecObj.
*
* @param rsvpErrSpecObj Rsvp error spec object
*/
public StatefulRsvpErrorSpecTlv(PcepRsvpErrorSpec rsvpErrSpecObj) {
this.rsvpErrSpecObj = rsvpErrSpecObj;
this.isErrSpceObjSet = true;
}
/**
* Returns PcepRsvpErrorSpecObject.
*
* @return rsvpErrSpecObj
*/
public PcepRsvpErrorSpec getPcepRsvpErrorSpec() {
return this.rsvpErrSpecObj;
}
@Override
public PcepVersion getVersion() {
return PcepVersion.PCEP_1;
}
@Override
public short getType() {
return TYPE;
}
@Override
public short getLength() {
return hLength;
}
/**
* Reads channel buffer and returns object of StatefulRsvpErrorSpecTlv.
*
* @param cb of type channel buffer
* @return object of StatefulRsvpErrorSpecTlv
* @throws PcepParseException while parsing this tlv from channel buffer
*/
public static PcepValueType read(ChannelBuffer cb) throws PcepParseException {
PcepRsvpErrorSpec rsvpErrSpecObj = null;
PcepRsvpSpecObjHeader rsvpErrSpecObjHeader;
cb.markReaderIndex();
rsvpErrSpecObjHeader = PcepRsvpSpecObjHeader.read(cb);
cb.resetReaderIndex();
if (PcepRsvpIpv4ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
&& PcepRsvpIpv4ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
rsvpErrSpecObj = PcepRsvpIpv4ErrorSpec.read(cb);
} else if (PcepRsvpIpv6ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
&& PcepRsvpIpv6ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
rsvpErrSpecObj = PcepRsvpIpv6ErrorSpec.read(cb);
} else if (PcepRsvpUserErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
&& PcepRsvpUserErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
rsvpErrSpecObj = PcepRsvpUserErrorSpec.read(cb);
}
return new StatefulRsvpErrorSpecTlv(rsvpErrSpecObj);
}
@Override
public int hashCode() {
return Objects.hash(rsvpErrSpecObj.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof StatefulRsvpErrorSpecTlv) {
StatefulRsvpErrorSpecTlv other = (StatefulRsvpErrorSpecTlv) obj;
return Objects.equals(this.rsvpErrSpecObj, other.rsvpErrSpecObj);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iStartIndex = c.writerIndex();
c.writeShort(TYPE);
int tlvLenIndex = c.writerIndex();
hLength = 0;
c.writeShort(hLength);
if (isErrSpceObjSet) {
rsvpErrSpecObj.write(c);
}
hLength = (short) (c.writerIndex() - iStartIndex);
c.setShort(tlvLenIndex, (hLength - OBJECT_HEADER_LENGTH));
return c.writerIndex() - iStartIndex;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("Type", TYPE)
.add("Length", hLength)
.add("RSVPErrorSpecObject", rsvpErrSpecObj)
.toString();
}
}