blob: b974cf827bef028b1ef1d4a0b878c908bb44e247 [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 Link Descriptors TLV.
33 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070034public class TELinkDescriptorsTlv implements PcepValueType {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070035
36 /*
37 * Reference: PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
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=[TBD14] | Length |
42 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 | |
44 // Link Descriptor Sub-TLVs (variable) //
45 | |
46 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
48 */
49
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070050 protected static final Logger log = LoggerFactory.getLogger(TELinkDescriptorsTlv.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070051
52 public static final short TYPE = 1070; //TODD:change this TBD14
53 public short hLength;
54
55 public static final int TLV_HEADER_LENGTH = 4;
56
57 // LinkDescriptors Sub-TLVs (variable)
58 private LinkedList<PcepValueType> llLinkDescriptorsSubTLVs;
59
60 /**
61 * Constructor to initialize llLinkDescriptorsSubTLVs.
62 *
63 * @param llLinkDescriptorsSubTLVs of PcepValueType
64 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070065 public TELinkDescriptorsTlv(LinkedList<PcepValueType> llLinkDescriptorsSubTLVs) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070066 this.llLinkDescriptorsSubTLVs = llLinkDescriptorsSubTLVs;
67 }
68
69 /**
70 * Returns object of TELinkDescriptorsTLV.
71 *
72 * @param llLinkDescriptorsSubTLVs of PcepValueType
73 * @return object of TELinkDescriptorsTLV
74 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -070075 public static TELinkDescriptorsTlv of(final LinkedList<PcepValueType> llLinkDescriptorsSubTLVs) {
76 return new TELinkDescriptorsTlv(llLinkDescriptorsSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070077 }
78
79 /**
80 * Returns linked list of Link Attribute of Sub TLV.
81 *
82 * @return llLinkDescriptorsSubTLVs linked list of Link Attribute of Sub TLV
83 */
84 public LinkedList<PcepValueType> getllLinkDescriptorsSubTLVs() {
85 return llLinkDescriptorsSubTLVs;
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(llLinkDescriptorsSubTLVs.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 */
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700121 if (obj instanceof TELinkDescriptorsTlv) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700122 int countObjSubTlv = 0;
123 int countOtherSubTlv = 0;
124 boolean isCommonSubTlv = true;
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700125 TELinkDescriptorsTlv other = (TELinkDescriptorsTlv) obj;
126 Iterator<PcepValueType> objListIterator = ((TELinkDescriptorsTlv) obj).llLinkDescriptorsSubTLVs.iterator();
127 countObjSubTlv = ((TELinkDescriptorsTlv) obj).llLinkDescriptorsSubTLVs.size();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700128 countOtherSubTlv = other.llLinkDescriptorsSubTLVs.size();
129 if (countObjSubTlv != countOtherSubTlv) {
130 return false;
131 } else {
132 while (objListIterator.hasNext() && isCommonSubTlv) {
133 PcepValueType subTlv = objListIterator.next();
134 isCommonSubTlv = Objects.equals(llLinkDescriptorsSubTLVs.contains(subTlv),
135 other.llLinkDescriptorsSubTLVs.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 = llLinkDescriptorsSubTLVs.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 channel buffer and returns object of TELinkDescriptorsTLV.
177 *
178 * @param c input channel buffer
179 * @param length length
180 * @return object of TELinkDescriptorsTLV
181 * @throws PcepParseException if mandatory fields are missing
182 */
183 public static PcepValueType read(ChannelBuffer c, short length) throws PcepParseException {
184
185 // Node Descriptor Sub-TLVs (variable)
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700186 LinkedList<PcepValueType> llLinkDescriptorsSubTLVs = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700187
188 ChannelBuffer tempCb = c.readBytes(length);
189
190 while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
191
192 PcepValueType tlv;
193 short hType = tempCb.readShort();
194 int iValue = 0;
195 short hLength = tempCb.readShort();
196 log.debug("sub Tlv Length" + hLength);
197 switch (hType) {
198
199 case LinkLocalRemoteIdentifiersTlv.TYPE:
200 tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
201 break;
202 case IPv4InterfaceAddressTlv.TYPE:
203 iValue = tempCb.readInt();
204 tlv = new IPv4InterfaceAddressTlv(iValue);
205 break;
206 case IPv4NeighborAddressTlv.TYPE:
207 iValue = tempCb.readInt();
208 tlv = new IPv4NeighborAddressTlv(iValue);
209 break;
210 case IPv6InterfaceAddressTlv.TYPE:
211 byte[] ipv6Value = new byte[IPv6InterfaceAddressTlv.VALUE_LENGTH];
212 tempCb.readBytes(ipv6Value, 0, IPv6InterfaceAddressTlv.VALUE_LENGTH);
213 tlv = new IPv6InterfaceAddressTlv(ipv6Value);
214 break;
215 case IPv6NeighborAddressTlv.TYPE:
216 byte[] ipv6NeighborAdd = new byte[IPv6NeighborAddressTlv.VALUE_LENGTH];
217 tempCb.readBytes(ipv6NeighborAdd, 0, IPv6NeighborAddressTlv.VALUE_LENGTH);
218 tlv = new IPv6NeighborAddressTlv(ipv6NeighborAdd);
219 break;
220 default:
221 throw new PcepParseException("Unsupported Sub TLV type:" + hType);
222 }
223
224 // Check for the padding
225 int pad = hLength % 4;
226 if (0 < pad) {
227 pad = 4 - pad;
228 if (pad <= tempCb.readableBytes()) {
229 tempCb.skipBytes(pad);
230 }
231 }
232 llLinkDescriptorsSubTLVs.add(tlv);
233
234 }
235
236 if (0 < tempCb.readableBytes()) {
237
238 throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
239 }
Sho SHIMIZUa5356ec2015-09-03 13:27:38 -0700240 return new TELinkDescriptorsTlv(llLinkDescriptorsSubTLVs);
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("LinkDescriptorsSubTLVs", llLinkDescriptorsSubTLVs)
249 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700250 }
251}