blob: 1505a422684451d3d437d621dd024b915de1ad0a [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07003 *
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 Link Descriptors TLV.
34 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053035public class LinkDescriptorsTlv implements PcepValueType {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070036
37 /*
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053038 * Reference: draft-dhodylee-pce-pcep-ls-01, section 9.2.6.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070039 * 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=[TBD14] | Length |
43 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 | |
45 // Link Descriptor Sub-TLVs (variable) //
46 | |
47 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48
49 */
50
Ray Milkey9c9cde42018-01-12 14:22:06 -080051 private static final Logger log = LoggerFactory.getLogger(LinkDescriptorsTlv.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070052
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053053 public static final short TYPE = (short) 65284;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070054 public short hLength;
55
56 public static final int TLV_HEADER_LENGTH = 4;
57
58 // LinkDescriptors Sub-TLVs (variable)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053059 private List<PcepValueType> llLinkDescriptorsSubTLVs;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070060
61 /**
62 * Constructor to initialize llLinkDescriptorsSubTLVs.
63 *
64 * @param llLinkDescriptorsSubTLVs of PcepValueType
65 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053066 public LinkDescriptorsTlv(List<PcepValueType> llLinkDescriptorsSubTLVs) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070067 this.llLinkDescriptorsSubTLVs = llLinkDescriptorsSubTLVs;
68 }
69
70 /**
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053071 * Returns object of LinkDescriptorsTlv.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070072 *
73 * @param llLinkDescriptorsSubTLVs of PcepValueType
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053074 * @return object of LinkDescriptorsTlv
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070075 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053076 public static LinkDescriptorsTlv of(final List<PcepValueType> llLinkDescriptorsSubTLVs) {
77 return new LinkDescriptorsTlv(llLinkDescriptorsSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070078 }
79
80 /**
81 * Returns linked list of Link Attribute of Sub TLV.
82 *
83 * @return llLinkDescriptorsSubTLVs linked list of Link Attribute of Sub TLV
84 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053085 public List<PcepValueType> getllLinkDescriptorsSubTLVs() {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070086 return llLinkDescriptorsSubTLVs;
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(llLinkDescriptorsSubTLVs.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 LinkDescriptorsTlv) {
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 LinkDescriptorsTlv other = (LinkDescriptorsTlv) obj;
127 Iterator<PcepValueType> objListIterator = ((LinkDescriptorsTlv) obj).llLinkDescriptorsSubTLVs.iterator();
128 countObjSubTlv = ((LinkDescriptorsTlv) obj).llLinkDescriptorsSubTLVs.size();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700129 countOtherSubTlv = other.llLinkDescriptorsSubTLVs.size();
130 if (countObjSubTlv != countOtherSubTlv) {
131 return false;
132 } else {
133 while (objListIterator.hasNext() && isCommonSubTlv) {
134 PcepValueType subTlv = objListIterator.next();
135 isCommonSubTlv = Objects.equals(llLinkDescriptorsSubTLVs.contains(subTlv),
136 other.llLinkDescriptorsSubTLVs.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 = llLinkDescriptorsSubTLVs.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 channel buffer and returns object of LinkDescriptorsTlv.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700178 *
179 * @param c input channel buffer
180 * @param length length
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530181 * @return object of LinkDescriptorsTlv
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700182 * @throws PcepParseException if mandatory fields are missing
183 */
184 public static PcepValueType read(ChannelBuffer c, short length) throws PcepParseException {
185
186 // Node Descriptor Sub-TLVs (variable)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530187 List<PcepValueType> llLinkDescriptorsSubTLVs = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700188
189 ChannelBuffer tempCb = c.readBytes(length);
190
191 while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
192
193 PcepValueType tlv;
194 short hType = tempCb.readShort();
195 int iValue = 0;
196 short hLength = tempCb.readShort();
197 log.debug("sub Tlv Length" + hLength);
198 switch (hType) {
199
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530200 case LinkLocalRemoteIdentifiersSubTlv.TYPE:
201 tlv = LinkLocalRemoteIdentifiersSubTlv.read(tempCb);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700202 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530203 case IPv4InterfaceAddressSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700204 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530205 tlv = new IPv4InterfaceAddressSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700206 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530207 case IPv4NeighborAddressSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700208 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530209 tlv = new IPv4NeighborAddressSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700210 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530211 case IPv6InterfaceAddressSubTlv.TYPE:
212 byte[] ipv6Value = new byte[IPv6InterfaceAddressSubTlv.VALUE_LENGTH];
213 tempCb.readBytes(ipv6Value, 0, IPv6InterfaceAddressSubTlv.VALUE_LENGTH);
214 tlv = new IPv6InterfaceAddressSubTlv(ipv6Value);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700215 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530216 case IPv6NeighborAddressSubTlv.TYPE:
217 byte[] ipv6NeighborAdd = new byte[IPv6NeighborAddressSubTlv.VALUE_LENGTH];
218 tempCb.readBytes(ipv6NeighborAdd, 0, IPv6NeighborAddressSubTlv.VALUE_LENGTH);
219 tlv = new IPv6NeighborAddressSubTlv(ipv6NeighborAdd);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700220 break;
221 default:
222 throw new PcepParseException("Unsupported Sub TLV type:" + hType);
223 }
224
225 // Check for the padding
226 int pad = hLength % 4;
227 if (0 < pad) {
228 pad = 4 - pad;
229 if (pad <= tempCb.readableBytes()) {
230 tempCb.skipBytes(pad);
231 }
232 }
233 llLinkDescriptorsSubTLVs.add(tlv);
234
235 }
236
237 if (0 < tempCb.readableBytes()) {
238
239 throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
240 }
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530241 return new LinkDescriptorsTlv(llLinkDescriptorsSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700242 }
243
244 @Override
245 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700246 return MoreObjects.toStringHelper(getClass())
247 .add("Type", TYPE)
248 .add("Length", hLength)
249 .add("LinkDescriptorsSubTLVs", llLinkDescriptorsSubTLVs)
250 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700251 }
252}