blob: b31dac2c6d33e79f87e967bbed355b4acd22cefc [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 Local TE Node Descriptors TLV which contains Node Descriptor Sub-TLVs.
33 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070034public class LocalTENodeDescriptorsTlv implements PcepValueType {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070035
36 /* REFERENCE :draft-ietf-idr-ls-distribution-10
37 * 0 1 2 3
38 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
39 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 | Type=[TBD8] | Length |
41 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 | |
43 // Node Descriptor Sub-TLVs (variable) //
44 | |
45 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 Note: Length is including header here. Refer Routing Universe TLV.
47 */
48
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070049 protected static final Logger log = LoggerFactory.getLogger(LocalTENodeDescriptorsTlv.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070050
51 public static final short TYPE = 1637; //TODD:change this TBD8
52 public short hLength;
53
54 public static final int TLV_HEADER_LENGTH = 4;
55 // Node Descriptor Sub-TLVs (variable)
56 private LinkedList<PcepValueType> llNodeDescriptorSubTLVs;
57
58 /**
59 * Constructor to initialize llNodeDescriptorSubTLVs.
60 *
61 * @param llNodeDescriptorSubTLVs LinkedList of PcepValueType
62 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070063 public LocalTENodeDescriptorsTlv(LinkedList<PcepValueType> llNodeDescriptorSubTLVs) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070064 this.llNodeDescriptorSubTLVs = llNodeDescriptorSubTLVs;
65 }
66
67 /**
68 * Returns a new object of LocalTENodeDescriptorsTLV.
69 *
70 * @param llNodeDescriptorSubTLVs linked list of Node Descriptor Sub TLVs
71 * @return object of LocalTENodeDescriptorsTLV
72 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070073 public static LocalTENodeDescriptorsTlv of(final LinkedList<PcepValueType> llNodeDescriptorSubTLVs) {
74 return new LocalTENodeDescriptorsTlv(llNodeDescriptorSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070075 }
76
77 /**
78 * Returns Linked List of tlvs.
79 *
80 * @return llNodeDescriptorSubTLVs linked list of Node Descriptor Sub TLV
81 */
82 public LinkedList<PcepValueType> getllNodeDescriptorSubTLVs() {
83 return llNodeDescriptorSubTLVs;
84 }
85
86 @Override
87 public PcepVersion getVersion() {
88 return PcepVersion.PCEP_1;
89 }
90
91 @Override
92 public short getType() {
93 return TYPE;
94 }
95
96 @Override
97 public short getLength() {
98 return hLength;
99 }
100
101 @Override
102 public int hashCode() {
103 return Objects.hash(llNodeDescriptorSubTLVs.hashCode());
104 }
105
106 @Override
107 public boolean equals(Object obj) {
108 if (this == obj) {
109 return true;
110 }
111
112 /*
113 * Here we have a list of Tlv so to compare each sub tlv between the object
114 * we have to take a list iterator so one by one we can get each sub tlv object
115 * and can compare them.
116 * it may be possible that the size of 2 lists is not equal so we have to first check
117 * the size, if both are same then we should check for the subtlv objects otherwise
118 * we should return false.
119 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700120 if (obj instanceof LocalTENodeDescriptorsTlv) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700121 int countObjSubTlv = 0;
122 int countOtherSubTlv = 0;
123 boolean isCommonSubTlv = true;
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700124 LocalTENodeDescriptorsTlv other = (LocalTENodeDescriptorsTlv) obj;
125 Iterator<PcepValueType> objListIterator = ((LocalTENodeDescriptorsTlv) obj).llNodeDescriptorSubTLVs
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700126 .iterator();
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700127 countObjSubTlv = ((LocalTENodeDescriptorsTlv) obj).llNodeDescriptorSubTLVs.size();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700128 countOtherSubTlv = other.llNodeDescriptorSubTLVs.size();
129 if (countObjSubTlv != countOtherSubTlv) {
130 return false;
131 } else {
132 while (objListIterator.hasNext() && isCommonSubTlv) {
133 PcepValueType subTlv = objListIterator.next();
134 isCommonSubTlv = Objects.equals(llNodeDescriptorSubTLVs.contains(subTlv),
135 other.llNodeDescriptorSubTLVs.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(0);
150
151 ListIterator<PcepValueType> listIterator = llNodeDescriptorSubTLVs.listIterator();
152
153 while (listIterator.hasNext()) {
154 PcepValueType tlv = listIterator.next();
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700155 if (tlv == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700156 log.debug("TLV is null from subTlv list");
157 continue;
158 }
159 tlv.write(c);
160
161 // need to take care of padding
162 int pad = tlv.getLength() % 4;
163
164 if (0 != pad) {
165 pad = 4 - pad;
166 for (int i = 0; i < pad; ++i) {
167 c.writeByte((byte) 0);
168 }
169 }
170 }
171 hLength = (short) (c.writerIndex() - tlvStartIndex);
172 c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
173 return c.writerIndex() - tlvStartIndex;
174 }
175
176 /**
177 * Reads the channel buffer and returns object of AutonomousSystemTlv.
178 *
179 * @param c input channel buffer
180 * @param hLength length of subtlvs.
181 * @return object of AutonomousSystemTlv
182 * @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)
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700187 LinkedList<PcepValueType> llNodeDescriptorSubTLVs = 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
193 PcepValueType tlv;
194 short hType = tempCb.readShort();
195 int iValue = 0;
196 short length = tempCb.readShort();
197
198 switch (hType) {
199
200 case AutonomousSystemTlv.TYPE:
201 iValue = tempCb.readInt();
202 tlv = new AutonomousSystemTlv(iValue);
203 break;
204 case BGPLSidentifierTlv.TYPE:
205 iValue = tempCb.readInt();
206 tlv = new BGPLSidentifierTlv(iValue);
207 break;
208 case OSPFareaIDsubTlv.TYPE:
209 iValue = tempCb.readInt();
210 tlv = new OSPFareaIDsubTlv(iValue);
211 break;
212 case RouterIDSubTlv.TYPE:
213 tlv = RouterIDSubTlv.read(tempCb, length);
214 break;
215
216 default:
217 throw new PcepParseException("Unsupported Sub TLV type :" + hType);
218 }
219
220 // Check for the padding
221 int pad = length % 4;
222 if (0 < pad) {
223 pad = 4 - pad;
224 if (pad <= tempCb.readableBytes()) {
225 tempCb.skipBytes(pad);
226 }
227 }
228
229 llNodeDescriptorSubTLVs.add(tlv);
230 }
231
232 if (0 < tempCb.readableBytes()) {
233 throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
234 }
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700235 return new LocalTENodeDescriptorsTlv(llNodeDescriptorSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700236 }
237
238 @Override
239 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700240 return MoreObjects.toStringHelper(getClass())
241 .add("Type", TYPE)
242 .add("Length", hLength)
243 .add("NodeDescriptorSubTLVs", llNodeDescriptorSubTLVs)
244 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700245 }
246}