blob: 483b11d01ca0bd33eb48c6325b44e95f646159cc [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
alshabibc4901cd2014-09-05 16:50:40 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
alshabibc4901cd2014-09-05 16:50:40 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
alshabibc4901cd2014-09-05 16:50:40 -070016/**
17 * Licensed under the Apache License, Version 2.0 (the "License"); you may
18 * not use this file except in compliance with the License. You may obtain
19 * a copy of the License at
20 *
21 * http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
26 * License for the specific language governing permissions and limitations
27 * under the License.
28 **/
29
30package org.onlab.packet;
31
32import java.nio.ByteBuffer;
HIGUCHI Yuta436f8d52015-12-07 21:17:48 -080033import java.nio.charset.StandardCharsets;
alshabibc4901cd2014-09-05 16:50:40 -070034import java.util.Arrays;
35
36/**
37 * The class representing LLDP Organizationally Specific TLV.
38 *
alshabibc4901cd2014-09-05 16:50:40 -070039 */
40public class LLDPOrganizationalTLV extends LLDPTLV {
41 public static final int OUI_LENGTH = 3;
42 public static final int SUBTYPE_LENGTH = 1;
43 public static final byte ORGANIZATIONAL_TLV_TYPE = 127;
44 public static final int MAX_INFOSTRING_LENGTH = 507;
45
46 protected byte[] oui;
47 protected byte subType;
48 private byte[] infoString;
49
50 public LLDPOrganizationalTLV() {
51 this.type = LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE;
52 }
53
54 /**
55 * Set the value of OUI.
56 *
57 * @param oui
58 * The value of OUI to be set.
59 * @return This LLDP Organizationally Specific TLV.
60 */
61 public LLDPOrganizationalTLV setOUI(final byte[] oui) {
62 if (oui.length != LLDPOrganizationalTLV.OUI_LENGTH) {
63 throw new IllegalArgumentException("The length of OUI must be "
64 + LLDPOrganizationalTLV.OUI_LENGTH + ", but it is "
65 + oui.length);
66 }
67 this.oui = Arrays.copyOf(oui, oui.length);
68 return this;
69 }
70
71 /**
72 * Returns the value of the OUI.
73 *
74 * @return The value of the OUI .
75 */
76 public byte[] getOUI() {
77 return Arrays.copyOf(this.oui, this.oui.length);
78 }
79
80 /**
81 * Set the value of sub type.
82 *
83 * @param subType
84 * The value of sub type to be set.
85 * @return This LLDP Organizationally Specific TLV.
86 */
87 public LLDPOrganizationalTLV setSubType(final byte subType) {
88 this.subType = subType;
89 return this;
90 }
91
92 /**
93 * Returns the value of the sub type.
94 *
95 * @return The value of the sub type.
96 */
97 public byte getSubType() {
98 return this.subType;
99 }
100
101 /**
102 * Set the value of information string.
103 *
104 * @param infoString
105 * the byte array of the value of information string.
106 * @return This LLDP Organizationally Specific TLV.
107 */
108 public LLDPOrganizationalTLV setInfoString(final byte[] infoString) {
109 if (infoString.length > LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH) {
110 throw new IllegalArgumentException(
111 "The length of infoString cannot exceed "
112 + LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH);
113 }
114 this.infoString = Arrays.copyOf(infoString, infoString.length);
115 return this;
116 }
117
118 /**
119 * Set the value of information string. The String value is automatically
120 * converted into byte array with UTF-8 encoding.
121 *
122 * @param infoString
123 * the String value of information string.
124 * @return This LLDP Organizationally Specific TLV.
125 */
126 public LLDPOrganizationalTLV setInfoString(final String infoString) {
HIGUCHI Yuta436f8d52015-12-07 21:17:48 -0800127 final byte[] infoStringBytes = infoString.getBytes(StandardCharsets.UTF_8);
alshabibc4901cd2014-09-05 16:50:40 -0700128 return this.setInfoString(infoStringBytes);
129 }
130
131 /**
132 * Returns the value of information string.
133 *
134 * @return the value of information string.
135 */
136 public byte[] getInfoString() {
137 return Arrays.copyOf(this.infoString, this.infoString.length);
138 }
139
140 @Override
141 public byte[] serialize() {
alshabib7911a052014-10-16 17:49:37 -0700142 if (this.type != LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
143 return super.serialize();
144 }
alshabibc4901cd2014-09-05 16:50:40 -0700145 final int valueLength = LLDPOrganizationalTLV.OUI_LENGTH
146 + LLDPOrganizationalTLV.SUBTYPE_LENGTH + this.infoString.length;
147 this.value = new byte[valueLength];
148 final ByteBuffer bb = ByteBuffer.wrap(this.value);
149 bb.put(this.oui);
150 bb.put(this.subType);
151 bb.put(this.infoString);
152 return super.serialize();
153 }
154
155 @Override
Jonathan Hart2a655752015-04-07 16:46:33 -0700156 public LLDPTLV deserialize(final ByteBuffer bb) throws DeserializationException {
157 super.deserialize(bb);
158 if (this.getType() != LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
159 return this;
160 }
161
162 if (this.getLength() <= OUI_LENGTH + SUBTYPE_LENGTH) {
163 throw new DeserializationException(
164 "TLV length is less than required for organizational TLV");
alshabib7911a052014-10-16 17:49:37 -0700165 }
166
alshabibc4901cd2014-09-05 16:50:40 -0700167 final ByteBuffer optionalField = ByteBuffer.wrap(this.value);
168
169 final byte[] oui = new byte[LLDPOrganizationalTLV.OUI_LENGTH];
170 optionalField.get(oui);
171 this.setOUI(oui);
172
173 this.setSubType(optionalField.get());
174
175 final byte[] infoString = new byte[this.getLength()
alshabib638dc712014-09-05 18:03:45 -0700176 - LLDPOrganizationalTLV.OUI_LENGTH
177 - LLDPOrganizationalTLV.SUBTYPE_LENGTH];
alshabibc4901cd2014-09-05 16:50:40 -0700178 optionalField.get(infoString);
179 this.setInfoString(infoString);
180 return this;
181 }
182
183 @Override
184 public int hashCode() {
185 final int prime = 1423;
186 int result = 1;
187 result = prime * result + this.type;
188 result = prime * result + this.length;
189 result = prime * result + Arrays.hashCode(this.oui);
190 result = prime * result + this.subType;
191 result = prime * result + Arrays.hashCode(this.infoString);
192 return result;
193 }
194
195 @Override
196 public boolean equals(final Object o) {
197 if (o == this) {
198 return true;
199 }
200
201 if (!(o instanceof LLDPOrganizationalTLV)) {
202 return false;
203 }
204
205 final LLDPOrganizationalTLV other = (LLDPOrganizationalTLV) o;
206 if (this.type != other.type) {
207 return false;
208 }
209 if (this.length != other.length) {
210 return false;
211 }
212 if (!Arrays.equals(this.oui, other.oui)) {
213 return false;
214 }
215 if (this.subType != other.subType) {
216 return false;
217 }
218 if (!Arrays.equals(this.infoString, other.infoString)) {
219 return false;
220 }
221
222 return true;
223 }
224}