2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.sal.packet;
11 import java.io.UnsupportedEncodingException;
12 import java.nio.charset.Charset;
13 import java.util.Arrays;
14 import java.util.HashMap;
15 import java.util.LinkedHashMap;
18 import org.apache.commons.lang3.tuple.MutablePair;
19 import org.apache.commons.lang3.tuple.Pair;
20 import org.opendaylight.controller.sal.utils.HexEncode;
21 import org.opendaylight.controller.sal.utils.NetUtils;
24 * Class that represents the LLDPTLV objects
27 public class LLDPTLV extends Packet {
28 private static final String TYPE = "Type";
29 private static final String LENGTH = "Length";
30 private static final String VALUE = "Value";
31 private static final int LLDPTLVFields = 3;
32 public static final byte[] OFOUI = new byte[] { (byte) 0x00, (byte) 0x26,
33 (byte) 0xe1 }; // OpenFlow OUI
34 public static final byte[] customTlvSubType = new byte[] { 0 };
35 public static final int customTlvOffset = OFOUI.length
36 + customTlvSubType.length;
37 public static final byte chassisIDSubType[] = new byte[] { 4 }; // MAC address for the system
38 public static final byte portIDSubType[] = new byte[] { 7 }; // locally assigned
41 Unknown((byte) 0), ChassisID((byte) 1), PortID((byte) 2), TTL((byte) 3), PortDesc(
42 (byte) 4), SystemName((byte) 5), SystemDesc((byte) 6), Custom(
47 private TLVType(byte value) {
51 public byte getValue() {
56 private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
57 private static final long serialVersionUID = 1L;
60 put(TYPE, new MutablePair<Integer, Integer>(0, 7));
61 put(LENGTH, new MutablePair<Integer, Integer>(7, 9));
62 put(VALUE, new MutablePair<Integer, Integer>(16, 0));
66 protected Map<String, byte[]> fieldValues;
69 * Default constructor that creates and sets the hash map values and sets
74 fieldValues = new HashMap<String, byte[]>(LLDPTLVFields);
75 hdrFieldCoordMap = fieldCoordinates;
76 hdrFieldsMap = fieldValues;
80 * Constructor that writes the passed LLDPTLV values to the hdrFieldsMap
82 public LLDPTLV(LLDPTLV other) {
83 for (Map.Entry<String, byte[]> entry : other.hdrFieldsMap.entrySet()) {
84 this.hdrFieldsMap.put(entry.getKey(), entry.getValue());
89 * @return int - the length of TLV
91 public int getLength() {
92 return (int) BitBufferHelper.toNumber(fieldValues.get(LENGTH),
93 fieldCoordinates.get(LENGTH).getRight().intValue());
97 * @return byte - the type of TLV
99 public byte getType() {
100 return BitBufferHelper.getByte(fieldValues.get(TYPE));
104 * @return byte[] - the value field of TLV
106 public byte[] getValue() {
107 return fieldValues.get(VALUE);
111 * @param byte - the type to set
114 public LLDPTLV setType(byte type) {
115 byte[] lldpTLVtype = { type };
116 fieldValues.put(TYPE, lldpTLVtype);
121 * @param short - the length to set
124 public LLDPTLV setLength(short length) {
125 fieldValues.put(LENGTH, BitBufferHelper.toByteArray(length));
130 * @param byte[] - the value to set
133 public LLDPTLV setValue(byte[] value) {
134 fieldValues.put(VALUE, value);
139 public void setHeaderField(String headerField, byte[] readValue) {
140 hdrFieldsMap.put(headerField, readValue);
144 public int hashCode() {
145 final int prime = 31;
146 int result = super.hashCode();
147 result = prime * result
148 + ((fieldValues == null) ? 0 : fieldValues.hashCode());
153 public boolean equals(Object obj) {
156 if (!super.equals(obj))
158 if (getClass() != obj.getClass())
160 LLDPTLV other = (LLDPTLV) obj;
161 if (fieldValues == null) {
162 if (other.fieldValues != null)
164 } else if (!fieldValues.equals(other.fieldValues))
170 public int getfieldnumBits(String fieldName) {
171 if (fieldName.equals(VALUE)) {
172 return (NetUtils.NumBitsInAByte * BitBufferHelper.getShort(
173 fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH)
174 .getRight().intValue()));
176 return fieldCoordinates.get(fieldName).getRight();
180 * Returns the size in bits of the whole TLV
182 * @return int - size in bits of full TLV
184 public int getTLVSize() {
185 return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static
186 LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
187 getfieldnumBits(VALUE)); // variable
191 * Creates the SystemName TLV value
194 * node identifier string
195 * @return the SystemName TLV value in byte array
197 static public byte[] createSystemNameTLVValue(String nodeId) {
198 byte[] nid = nodeId.getBytes();
203 * Creates the ChassisID TLV value including the subtype and ChassisID
207 * node identifier string
208 * @return the ChassisID TLV value in byte array
210 static public byte[] createChassisIDTLVValue(String nodeId) {
211 byte[] nid = HexEncode.bytesFromHexString(nodeId);
212 byte[] cid = new byte[6];
213 int srcPos = 0, dstPos = 0;
215 if (nid.length > cid.length) {
216 srcPos = nid.length - cid.length;
218 dstPos = cid.length - nid.length;
220 System.arraycopy(nid, srcPos, cid, dstPos, cid.length);
222 byte[] cidValue = new byte[cid.length + chassisIDSubType.length];
224 System.arraycopy(chassisIDSubType, 0, cidValue, 0,
225 chassisIDSubType.length);
226 System.arraycopy(cid, 0, cidValue, chassisIDSubType.length, cid.length);
232 * Creates the PortID TLV value including the subtype and PortID string
235 * port identifier string
236 * @return the PortID TLV value in byte array
238 static public byte[] createPortIDTLVValue(String portId) {
239 byte[] pid = portId.getBytes(Charset.defaultCharset());
240 byte[] pidValue = new byte[pid.length + portIDSubType.length];
242 System.arraycopy(portIDSubType, 0, pidValue, 0, portIDSubType.length);
243 System.arraycopy(pid, 0, pidValue, portIDSubType.length, pid.length);
249 * Creates the custom TLV value including OUI, subtype and custom string
252 * port identifier string
253 * @return the custom TLV value in byte array
255 static public byte[] createCustomTLVValue(String customString) {
256 byte[] customArray = customString.getBytes(Charset.defaultCharset());
257 byte[] customValue = new byte[customTlvOffset + customArray.length];
259 System.arraycopy(OFOUI, 0, customValue, 0, OFOUI.length);
260 System.arraycopy(customTlvSubType, 0, customValue, OFOUI.length,
261 customTlvSubType.length);
262 System.arraycopy(customArray, 0, customValue, customTlvOffset,
269 * Retrieves the string from TLV value and returns it in HexString format
275 * @return the HexString
277 static public String getHexStringValue(byte[] tlvValue, int tlvLen) {
278 byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];
279 System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0,
281 return HexEncode.bytesToHexStringFormat(cidBytes);
285 * Retrieves the string from TLV value
293 static public String getStringValue(byte[] tlvValue, int tlvLen) {
294 byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
295 System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0,
297 return (new String(pidBytes, Charset.defaultCharset()));
301 * Retrieves the custom string from the Custom TLV value which includes OUI,
302 * subtype and custom string
304 * @param customTlvValue
305 * the custom TLV value
306 * @param customTlvLen
307 * the custom TLV length
308 * @return the custom string
310 static public String getCustomString(byte[] customTlvValue, int customTlvLen) {
311 String customString = "";
312 byte[] vendor = new byte[3];
313 System.arraycopy(customTlvValue, 0, vendor, 0, vendor.length);
314 if (Arrays.equals(vendor, LLDPTLV.OFOUI)) {
315 int customArrayLength = customTlvLen - customTlvOffset;
316 byte[] customArray = new byte[customArrayLength];
317 System.arraycopy(customTlvValue, customTlvOffset, customArray, 0,
320 customString = new String(customArray, "UTF-8");
321 } catch (UnsupportedEncodingException e) {