blob: dc0ab7c66daf5b14d1ce9ec9e42a1bf658865be4 [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.pcepio.types;
17
18import java.util.Iterator;
19import java.util.LinkedList;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053020import java.util.List;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070021import java.util.ListIterator;
22import java.util.Objects;
23
24import org.jboss.netty.buffer.ChannelBuffer;
25import org.onosproject.pcepio.exceptions.PcepParseException;
26import org.onosproject.pcepio.protocol.PcepVersion;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import com.google.common.base.MoreObjects;
31
32/**
33 * Provides TE Node Attributes Tlv.
34 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053035public class NodeAttributesTlv implements PcepValueType {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070036 /*
37 * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
38 *
39 0 1 2 3
40 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
41 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 | Type=[TBD20] | Length |
43 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 | |
45 // Node Attributes Sub-TLVs (variable) //
46 | |
47 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48
49
50 */
51
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053052 protected static final Logger log = LoggerFactory.getLogger(NodeAttributesTlv.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070053
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053054 public static final short TYPE = (short) 65285;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070055 public short hLength;
56
57 public static final int TLV_HEADER_LENGTH = 4;
58 // LinkDescriptors Sub-TLVs (variable)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053059 private List<PcepValueType> llNodeAttributesSubTLVs;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070060
61 /**
62 * Constructor to initialize llNodeAttributesSubTLVs.
63 *
64 * @param llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
65 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053066 public NodeAttributesTlv(List<PcepValueType> llNodeAttributesSubTLVs) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070067 this.llNodeAttributesSubTLVs = llNodeAttributesSubTLVs;
68 }
69
70 /**
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053071 * Returns object of NodeAttributesTlv.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070072 *
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053073 * @param llNodeAttributesSubTLVs List of PcepValueType
74 * @return object of NodeAttributesTlv
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070075 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053076 public static NodeAttributesTlv of(List<PcepValueType> llNodeAttributesSubTLVs) {
77 return new NodeAttributesTlv(llNodeAttributesSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070078 }
79
80 /**
81 * Returns Node Attributes Sub-TLVs.
82 *
83 * @return llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
84 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053085 public List<PcepValueType> getllNodeAttributesSubTLVs() {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070086 return llNodeAttributesSubTLVs;
87 }
88
89 @Override
90 public PcepVersion getVersion() {
91 return PcepVersion.PCEP_1;
92 }
93
94 @Override
95 public short getType() {
96 return TYPE;
97 }
98
99 @Override
100 public short getLength() {
101 return hLength;
102 }
103
104 @Override
105 public int hashCode() {
106 return Objects.hash(llNodeAttributesSubTLVs.hashCode());
107 }
108
109 @Override
110 public boolean equals(Object obj) {
111 if (this == obj) {
112 return true;
113 }
114 /*
115 * Here we have a list of Tlv so to compare each sub tlv between the object
116 * we have to take a list iterator so one by one we can get each sub tlv object
117 * and can compare them.
118 * it may be possible that the size of 2 lists is not equal so we have to first check
119 * the size, if both are same then we should check for the subtlv objects otherwise
120 * we should return false.
121 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530122 if (obj instanceof NodeAttributesTlv) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700123 int countObjSubTlv = 0;
124 int countOtherSubTlv = 0;
125 boolean isCommonSubTlv = true;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530126 NodeAttributesTlv other = (NodeAttributesTlv) obj;
127 Iterator<PcepValueType> objListIterator = ((NodeAttributesTlv) obj).llNodeAttributesSubTLVs.iterator();
128 countObjSubTlv = ((NodeAttributesTlv) obj).llNodeAttributesSubTLVs.size();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700129 countOtherSubTlv = other.llNodeAttributesSubTLVs.size();
130 if (countObjSubTlv != countOtherSubTlv) {
131 return false;
132 } else {
133 while (objListIterator.hasNext() && isCommonSubTlv) {
134 PcepValueType subTlv = objListIterator.next();
135 isCommonSubTlv = Objects.equals(llNodeAttributesSubTLVs.contains(subTlv),
136 other.llNodeAttributesSubTLVs.contains(subTlv));
137 }
138 return isCommonSubTlv;
139 }
140 }
141 return false;
142 }
143
144 @Override
145 public int write(ChannelBuffer c) {
146 int tlvStartIndex = c.writerIndex();
147 c.writeShort(TYPE);
148 int tlvLenIndex = c.writerIndex();
149 hLength = 0;
150 c.writeShort(hLength);
151
152 ListIterator<PcepValueType> listIterator = llNodeAttributesSubTLVs.listIterator();
153
154 while (listIterator.hasNext()) {
155 PcepValueType tlv = listIterator.next();
156
157 tlv.write(c);
158
159 // need to take care of padding
160 int pad = tlv.getLength() % 4;
161
162 if (0 != pad) {
163 pad = 4 - pad;
164 for (int i = 0; i < pad; ++i) {
165 c.writeByte((byte) 0);
166 }
167 }
168 }
169
170 hLength = (short) (c.writerIndex() - tlvStartIndex);
171 c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
172
173 return c.writerIndex() - tlvStartIndex;
174 }
175
176 /**
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530177 * Reads the channel buffer and returns object of NodeAttributesTlv.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700178 *
179 * @param c input channel buffer
180 * @param hLength length
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530181 * @return object of NodeAttributesTlv
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700182 * @throws PcepParseException if mandatory fields are missing
183 */
184 public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
185
186 // Node Descriptor Sub-TLVs (variable)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530187 List<PcepValueType> llNodeAttributesSubTLVs = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700188
189 ChannelBuffer tempCb = c.readBytes(hLength);
190
191 while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
192 PcepValueType tlv;
193 short hType = tempCb.readShort();
194 int iValue = 0;
195 short length = tempCb.readShort();
196 switch (hType) {
197
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530198 case NodeFlagBitsSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700199 byte cValue = tempCb.readByte();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530200 tlv = new NodeFlagBitsSubTlv(cValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700201 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530202 case OpaqueNodePropertiesSubTlv.TYPE:
203 tlv = OpaqueNodePropertiesSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700204 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530205 case NodeNameSubTlv.TYPE:
206 tlv = NodeNameSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700207 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530208 case IsisAreaIdentifierSubTlv.TYPE:
209 tlv = IsisAreaIdentifierSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700210 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530211 case IPv4RouterIdOfLocalNodeSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700212 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530213 tlv = new IPv4RouterIdOfLocalNodeSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700214 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530215 case IPv6RouterIdofLocalNodeSubTlv.TYPE:
216 byte[] ipv6Value = new byte[IPv6RouterIdofLocalNodeSubTlv.VALUE_LENGTH];
217 tempCb.readBytes(ipv6Value, 0, IPv6RouterIdofLocalNodeSubTlv.VALUE_LENGTH);
218 tlv = new IPv6RouterIdofLocalNodeSubTlv(ipv6Value);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700219 break;
220 default:
221 throw new PcepParseException("Unsupported Sub TLV type :" + hType);
222 }
223
224 // Check for the padding
225 int pad = length % 4;
226 if (0 < pad) {
227 pad = 4 - pad;
228 if (pad <= tempCb.readableBytes()) {
229 tempCb.skipBytes(pad);
230 }
231 }
232
233 llNodeAttributesSubTLVs.add(tlv);
234 }
235
236 if (0 < tempCb.readableBytes()) {
237
238 throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
239 }
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530240 return new NodeAttributesTlv(llNodeAttributesSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700241 }
242
243 @Override
244 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700245 return MoreObjects.toStringHelper(getClass())
246 .add("Type", TYPE)
247 .add("Length", hLength)
248 .add("NodeAttributesSubTLVs", llNodeAttributesSubTLVs)
249 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700250 }
251}