3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.sal.packet;
12 import java.io.UnsupportedEncodingException;
13 import java.util.HashMap;
15 import java.util.Arrays;
16 import java.util.LinkedHashMap;
18 import org.apache.commons.lang3.builder.EqualsBuilder;
19 import org.apache.commons.lang3.builder.HashCodeBuilder;
20 import org.apache.commons.lang3.tuple.MutablePair;
21 import org.apache.commons.lang3.tuple.Pair;
22 import org.opendaylight.controller.sal.utils.HexEncode;
23 import org.opendaylight.controller.sal.utils.NetUtils;
26 * Class that represents the LLDPTLV objects
29 public class LLDPTLV extends Packet {
30 private static final String TYPE = "Type";
31 private static final String LENGTH = "Length";
32 private static final String VALUE = "Value";
33 private static final int LLDPTLVFields = 3;
34 public static final byte[] OFOUI = new byte[] {(byte)0x00, (byte)0x26, (byte)0xe1}; // OpenFlow OUI
35 public static final byte[] customTlvSubType = new byte[] {0};
36 public static final int customTlvOffset = OFOUI.length + 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
51 private TLVType(byte value) {
54 public byte getValue() {
59 private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
60 private static final long serialVersionUID = 1L;
63 put(TYPE, new MutablePair<Integer, Integer>(0, 7));
64 put(LENGTH, new MutablePair<Integer, Integer>(7, 9));
65 put(VALUE, new MutablePair<Integer, Integer>(16, 0));
69 protected Map<String, byte[]> fieldValues;
72 * Default constructor that creates and sets the hash map values
73 * and sets the payload to null
77 fieldValues = new HashMap<String, byte[]>(LLDPTLVFields);
78 hdrFieldCoordMap = fieldCoordinates;
79 hdrFieldsMap = fieldValues;
83 * Constructor that writes the passed LLDPTLV values to the
86 public LLDPTLV(LLDPTLV other) {
87 for (Map.Entry<String, byte[]> entry : other.hdrFieldsMap.entrySet()) {
88 this.hdrFieldsMap.put(entry.getKey(), entry.getValue());
93 * @return int - the length of TLV
95 public int getLength() {
96 return (int) BitBufferHelper.toNumber(fieldValues.get(LENGTH),
97 fieldCoordinates.get(LENGTH).getRight().intValue());
101 * @return byte - the type of TLV
103 public byte getType() {
104 return BitBufferHelper.getByte(fieldValues.get(TYPE));
108 * @return byte[] - the value field of TLV
110 public byte[] getValue() {
111 return fieldValues.get(VALUE);
115 * @param byte - the type to set
118 public LLDPTLV setType(byte type) {
119 byte[] lldpTLVtype = { type };
120 fieldValues.put(TYPE, lldpTLVtype);
125 * @param short - the length to set
128 public LLDPTLV setLength(short length) {
129 fieldValues.put(LENGTH, BitBufferHelper.toByteArray(length));
134 * @param byte[] - the value to set
137 public LLDPTLV setValue(byte[] value) {
138 fieldValues.put(VALUE, value);
143 public void setHeaderField(String headerField, byte[] readValue) {
144 hdrFieldsMap.put(headerField, readValue);
148 public int hashCode() {
149 return HashCodeBuilder.reflectionHashCode(this);
153 public boolean equals(Object obj) {
154 return EqualsBuilder.reflectionEquals(this, obj);
158 public int getfieldnumBits(String fieldName) throws Exception {
159 if (fieldName.equals(VALUE)) {
160 return (NetUtils.NumBitsInAByte * (int) BitBufferHelper.getShort(
161 fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH)
162 .getRight().intValue()));
164 return fieldCoordinates.get(fieldName).getRight();
168 * Returns the size in bits of the whole TLV
169 * @return int - size in bits of full TLV
172 public int getTLVSize() throws Exception {
173 return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static
174 LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
175 getfieldnumBits(VALUE)); // variable
179 * Creates the ChassisID TLV value including the subtype and ChassisID string
181 * @param nodeId node identifier string
182 * @return the ChassisID TLV value in byte array
184 static public byte[] createChassisIDTLVValue(String nodeId) {
185 byte[] cid = HexEncode.bytesFromHexString(nodeId);
186 byte[] cidValue = new byte[cid.length + chassisIDSubType.length];
188 System.arraycopy(chassisIDSubType, 0, cidValue, 0, chassisIDSubType.length);
189 System.arraycopy(cid, 0, cidValue, chassisIDSubType.length, cid.length);
195 * Creates the PortID TLV value including the subtype and PortID string
197 * @param portId port identifier string
198 * @return the PortID TLV value in byte array
200 static public byte[] createPortIDTLVValue(String portId) {
201 byte[] pid = portId.getBytes();
202 byte[] pidValue = new byte[pid.length + portIDSubType.length];
204 System.arraycopy(portIDSubType, 0, pidValue, 0, portIDSubType.length);
205 System.arraycopy(pid, 0, pidValue, portIDSubType.length, pid.length);
211 * Creates the custom TLV value including OUI, subtype and custom string
213 * @param portId port identifier string
214 * @return the custom TLV value in byte array
216 static public byte[] createCustomTLVValue(String customString) {
217 byte[] customArray = customString.getBytes();
218 byte[] customValue = new byte[customTlvOffset + customArray.length];
220 System.arraycopy(OFOUI, 0, customValue, 0, OFOUI.length);
221 System.arraycopy(customTlvSubType, 0, customValue, OFOUI.length,
222 customTlvSubType.length);
223 System.arraycopy(customArray, 0, customValue, customTlvOffset,
230 * Retrieves the string from TLV value and returns it in HexString format
232 * @param tlvValue the TLV value
233 * @param tlvLen the TLV length
234 * @return the HexString
236 static public String getHexStringValue(byte[] tlvValue, int tlvLen) {
237 byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];
238 System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0, cidBytes.length);
239 return HexEncode.bytesToHexStringFormat(cidBytes);
243 * Retrieves the string from TLV value
245 * @param tlvValue the TLV value
246 * @param tlvLen the TLV length
249 static public String getStringValue(byte[] tlvValue, int tlvLen) {
250 byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
251 System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0, pidBytes.length);
252 return (new String(pidBytes));
256 * Retrieves the custom string from the Custom TLV value which includes OUI, subtype and custom string
258 * @param customTlvValue the custom TLV value
259 * @param customTlvLen the custom TLV length
260 * @return the custom string
262 static public String getCustomString(byte[] customTlvValue, int customTlvLen) {
263 String customString = "";
264 byte[] vendor = new byte[3];
265 System.arraycopy(customTlvValue, 0, vendor, 0, vendor.length);
266 if (Arrays.equals(vendor, LLDPTLV.OFOUI)) {
267 int customArrayLength = customTlvLen - customTlvOffset;
268 byte[] customArray = new byte[customArrayLength];
269 System.arraycopy(customTlvValue, customTlvOffset,
270 customArray, 0, customArrayLength);
272 customString = new String(customArray, "UTF-8");
273 } catch (UnsupportedEncodingException e) {