/* | |
* 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; | |
import com.google.common.base.MoreObjects.ToStringHelper; | |
/** | |
* 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() { | |
ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass()); | |
if (!isErrSpceObjSet) { | |
toStrHelper.add("Type", TYPE).add("Length", hLength); | |
} else { | |
toStrHelper.add("Type", TYPE).add("Length", hLength).add("RSVPErrorSpecObject", rsvpErrSpecObj); | |
} | |
return toStrHelper.toString(); | |
} | |
} |