blob: f18b75b26ebe5a891c8784bae6d4927b31ed2f51 [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;
20import java.util.ListIterator;
21import java.util.Objects;
22
23import org.jboss.netty.buffer.ChannelBuffer;
24import org.onosproject.pcepio.exceptions.PcepParseException;
25import org.onosproject.pcepio.protocol.PcepVersion;
26import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28
29import com.google.common.base.MoreObjects;
30
31/**
32 * Provides TE Node Attributes Tlv.
33 */
34public class TENodeAttributesTlv implements PcepValueType {
35 /*
36 * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
37 *
38 0 1 2 3
39 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
40 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 | Type=[TBD20] | Length |
42 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 | |
44 // Node Attributes Sub-TLVs (variable) //
45 | |
46 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
48
49 */
50
51 protected static final Logger log = LoggerFactory.getLogger(TENodeAttributesTlv.class);
52
53 public static final short TYPE = 1267; //TODD:change this TBD20
54 public short hLength;
55
56 public static final int TLV_HEADER_LENGTH = 4;
57 // LinkDescriptors Sub-TLVs (variable)
58 private LinkedList<PcepValueType> llNodeAttributesSubTLVs;
59
60 /**
61 * Constructor to initialize llNodeAttributesSubTLVs.
62 *
63 * @param llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
64 */
65 public TENodeAttributesTlv(LinkedList<PcepValueType> llNodeAttributesSubTLVs) {
66 this.llNodeAttributesSubTLVs = llNodeAttributesSubTLVs;
67 }
68
69 /**
70 * Returns object of TENodeAttributesTlv.
71 *
72 * @param llNodeAttributesSubTLVs LinkedList of PcepValueType
73 * @return object of TENodeAttributesTlv
74 */
75 public static TENodeAttributesTlv of(LinkedList<PcepValueType> llNodeAttributesSubTLVs) {
76 return new TENodeAttributesTlv(llNodeAttributesSubTLVs);
77 }
78
79 /**
80 * Returns Node Attributes Sub-TLVs.
81 *
82 * @return llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
83 */
84 public LinkedList<PcepValueType> getllNodeAttributesSubTLVs() {
85 return llNodeAttributesSubTLVs;
86 }
87
88 @Override
89 public PcepVersion getVersion() {
90 return PcepVersion.PCEP_1;
91 }
92
93 @Override
94 public short getType() {
95 return TYPE;
96 }
97
98 @Override
99 public short getLength() {
100 return hLength;
101 }
102
103 @Override
104 public int hashCode() {
105 return Objects.hash(llNodeAttributesSubTLVs.hashCode());
106 }
107
108 @Override
109 public boolean equals(Object obj) {
110 if (this == obj) {
111 return true;
112 }
113 /*
114 * Here we have a list of Tlv so to compare each sub tlv between the object
115 * we have to take a list iterator so one by one we can get each sub tlv object
116 * and can compare them.
117 * it may be possible that the size of 2 lists is not equal so we have to first check
118 * the size, if both are same then we should check for the subtlv objects otherwise
119 * we should return false.
120 */
121 if (obj instanceof TENodeAttributesTlv) {
122 int countObjSubTlv = 0;
123 int countOtherSubTlv = 0;
124 boolean isCommonSubTlv = true;
125 TENodeAttributesTlv other = (TENodeAttributesTlv) obj;
126 Iterator<PcepValueType> objListIterator = ((TENodeAttributesTlv) obj).llNodeAttributesSubTLVs.iterator();
127 countObjSubTlv = ((TENodeAttributesTlv) obj).llNodeAttributesSubTLVs.size();
128 countOtherSubTlv = other.llNodeAttributesSubTLVs.size();
129 if (countObjSubTlv != countOtherSubTlv) {
130 return false;
131 } else {
132 while (objListIterator.hasNext() && isCommonSubTlv) {
133 PcepValueType subTlv = objListIterator.next();
134 isCommonSubTlv = Objects.equals(llNodeAttributesSubTLVs.contains(subTlv),
135 other.llNodeAttributesSubTLVs.contains(subTlv));
136 }
137 return isCommonSubTlv;
138 }
139 }
140 return false;
141 }
142
143 @Override
144 public int write(ChannelBuffer c) {
145 int tlvStartIndex = c.writerIndex();
146 c.writeShort(TYPE);
147 int tlvLenIndex = c.writerIndex();
148 hLength = 0;
149 c.writeShort(hLength);
150
151 ListIterator<PcepValueType> listIterator = llNodeAttributesSubTLVs.listIterator();
152
153 while (listIterator.hasNext()) {
154 PcepValueType tlv = listIterator.next();
155
156 tlv.write(c);
157
158 // need to take care of padding
159 int pad = tlv.getLength() % 4;
160
161 if (0 != pad) {
162 pad = 4 - pad;
163 for (int i = 0; i < pad; ++i) {
164 c.writeByte((byte) 0);
165 }
166 }
167 }
168
169 hLength = (short) (c.writerIndex() - tlvStartIndex);
170 c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
171
172 return c.writerIndex() - tlvStartIndex;
173 }
174
175 /**
176 * Reads the channel buffer and returns object of TENodeAttributesTlv.
177 *
178 * @param c input channel buffer
179 * @param hLength length
180 * @return object of TENodeAttributesTlv
181 * @throws PcepParseException if mandatory fields are missing
182 */
183 public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
184
185 // Node Descriptor Sub-TLVs (variable)
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700186 LinkedList<PcepValueType> llNodeAttributesSubTLVs = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700187
188 ChannelBuffer tempCb = c.readBytes(hLength);
189
190 while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
191 PcepValueType tlv;
192 short hType = tempCb.readShort();
193 int iValue = 0;
194 short length = tempCb.readShort();
195 switch (hType) {
196
197 case NodeFlagBitsTlv.TYPE:
198 byte cValue = tempCb.readByte();
199 tlv = new NodeFlagBitsTlv(cValue);
200 break;
201 case OpaqueNodeAttributeTlv.TYPE:
202 tlv = OpaqueNodeAttributeTlv.read(tempCb, length);
203 break;
204 case NodeNameTlv.TYPE:
205 tlv = NodeNameTlv.read(tempCb, length);
206 break;
207 case ISISAreaIdentifierTlv.TYPE:
208 tlv = ISISAreaIdentifierTlv.read(tempCb, length);
209 break;
210 case IPv4TERouterIdOfLocalNodeTlv.TYPE:
211 iValue = tempCb.readInt();
212 tlv = new IPv4TERouterIdOfLocalNodeTlv(iValue);
213 break;
214 case IPv6TERouterIdofLocalNodeTlv.TYPE:
215 byte[] ipv6Value = new byte[IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH];
216 tempCb.readBytes(ipv6Value, 0, IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH);
217 tlv = new IPv6TERouterIdofLocalNodeTlv(ipv6Value);
218 break;
219 default:
220 throw new PcepParseException("Unsupported Sub TLV type :" + hType);
221 }
222
223 // Check for the padding
224 int pad = length % 4;
225 if (0 < pad) {
226 pad = 4 - pad;
227 if (pad <= tempCb.readableBytes()) {
228 tempCb.skipBytes(pad);
229 }
230 }
231
232 llNodeAttributesSubTLVs.add(tlv);
233 }
234
235 if (0 < tempCb.readableBytes()) {
236
237 throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
238 }
239 return new TENodeAttributesTlv(llNodeAttributesSubTLVs);
240 }
241
242 @Override
243 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700244 return MoreObjects.toStringHelper(getClass())
245 .add("Type", TYPE)
246 .add("Length", hLength)
247 .add("NodeAttributesSubTLVs", llNodeAttributesSubTLVs)
248 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700249 }
250}