package org.opendaylight.controller.liblldp;
-import java.util.Collections;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.LinkedHashMap;
(byte) 0xc2, 0, 0, (byte) 0xe };
private Map<Byte, LLDPTLV> tlvList;
- private List<LLDPTLV> customTlvList = Collections.emptyList();
+ private List<LLDPTLV> customTlvList;
/**
* Default constructor that creates the tlvList LinkedHashMap
*/
public LLDP() {
super();
- tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
+ tlvList = new LinkedHashMap<>(LLDPDefaultTlvs);
+ customTlvList = new ArrayList<>();
}
/**
return LLDPTLV.TLVType.PortID.getValue();
} else if (typeDesc.equals(TTL)) {
return LLDPTLV.TLVType.TTL.getValue();
+ } else if (typeDesc.equals(SYSTEMNAMEID)) {
+ return LLDPTLV.TLVType.SystemName.getValue();
} else {
return LLDPTLV.TLVType.Unknown.getValue();
}
byte type = entry.getKey();
if ((type == LLDPTLV.TLVType.ChassisID.getValue())
|| (type == LLDPTLV.TLVType.PortID.getValue())
- || (type == LLDPTLV.TLVType.TTL.getValue())) {
+ || (type == LLDPTLV.TLVType.TTL.getValue())
+ || (type == LLDPTLV.TLVType.SystemName.getValue())) {
continue;
} else {
list.add(entry.getValue());
return list;
}
+ /**
+ * @return the customTlvList
+ */
+ public List<LLDPTLV> getCustomTlvList() {
+ return customTlvList;
+ }
+
/**
* @param optionalTLVList
* the optionalTLVList to set
int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits
lldpOffset += tlvSize;
lldpSize -= tlvSize;
- this.tlvList.put(tlv.getType(), tlv);
+ if (tlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
+ customTlvList.add(tlv);
+ } else {
+ this.tlvList.put(tlv.getType(), tlv);
+ }
}
return this;
}
--- /dev/null
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.liblldp;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.BaseEncoding;
+import com.google.common.primitives.Bytes;
+
+/**
+ *
+ */
+public class LLDPTLVTest {
+
+ /** dummy custom tlv value */
+ private static final String CUSTOM_TLV_ULTIMATE = "What do you get when you multiply 6 by 9?";
+ /** dummy custom tlv value in binary form */
+ private static final byte[] CUSTOM_TLV_ULTIMATE_BIN = new byte[] {
+ 0x57, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x65, 0x74,
+ 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69,
+ 0x70, 0x6c, 0x79, 0x20, 0x36, 0x20, 0x62, 0x79, 0x20, 0x39, 0x3f
+ };
+
+ private static final Logger LOG = LoggerFactory.getLogger(LLDPTLVTest.class);
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.liblldp.LLDPTLV#createCustomTLVValue(java.lang.String)}
+ * .
+ */
+ @Test
+ public void testCreateCustomTLVValue() {
+ byte[] tlv = LLDPTLV.createCustomTLVValue(CUSTOM_TLV_ULTIMATE);
+
+ byte[] expectedCustomTlv = Bytes.concat(new byte[] {
+ // custom type (7b) + length (9b) = 16b = 2B (skipped)
+ // 0x7f, 24,
+ // openflow OUI
+ 0x00, 0x26, (byte) 0xe1,
+ // subtype
+ 0x00},
+ // custom value
+ CUSTOM_TLV_ULTIMATE_BIN);
+
+ BaseEncoding be = BaseEncoding.base16().withSeparator(" ", 2).lowerCase();
+ LOG.debug("expected: {}", be.encode(expectedCustomTlv));
+ LOG.debug("actual : {}", be.encode(tlv));
+ Assert.assertArrayEquals(expectedCustomTlv, tlv);
+ }
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.liblldp.LLDPTLV#getCustomString(byte[], int)}
+ * .
+ * @throws Exception
+ */
+ @Test
+ public void testGetCustomString() throws Exception {
+ byte[] inputCustomTlv = Bytes.concat(new byte[] {
+ // custom type (7b) + length (9b) = 16b = 2B (skipped)
+ // 0x7f, 24,
+ // openflow OUI
+ 0x00, 0x26, (byte) 0xe1,
+ // subtype
+ 0x00},
+ // custom value
+ CUSTOM_TLV_ULTIMATE_BIN);
+
+ String actual = LLDPTLV.getCustomString(inputCustomTlv, inputCustomTlv.length);
+ LOG.debug("actual custom TLV value as string: {}", actual);
+ Assert.assertEquals(CUSTOM_TLV_ULTIMATE, actual);
+ }
+}
import static org.junit.Assert.assertArrayEquals;
import java.util.ArrayList;
-
import java.util.List;
-import org.junit.internal.ArrayComparisonFailure;
-import org.junit.Test;
+
import org.apache.commons.lang3.ArrayUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.internal.ArrayComparisonFailure;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.primitives.Bytes;
/**
* Test of {@link LLDP} serialization feature (TODO: and deserialization)
*/
public class LLDPTest {
+ private static final Logger LOG = LoggerFactory.getLogger(LLDPTest.class);
+
private static final byte[] CHASSIS_ID_VALUE = "chassis".getBytes();
private static final short CHASSIS_ID_LENGTH = (short) CHASSIS_ID_VALUE.length;
/**
* Tests whether serialization of LLDP packet is correct
+ *
* @see LLDP#serialize()
* @throws PacketException
*/
offset = checkTLV(serialized, offset, (byte) 0b00000010, "ChassisID", CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE);
offset = checkTLV(serialized, offset, (byte) 0b00000110, "TTL", TTL_LENGTH, TTL_VALUE);
offset = checkTLV(serialized, offset, (byte) 0b00000100, "PortID", PORT_LENGTH, PORT_VALUE);
- offset = checkTLV(serialized, offset, (byte) 0b00001010, "SystemName", SYSTEM_NAME_LENGTH, SYSTEM_NAME_VALUE);
- offset = checkTLV(serialized, offset, (byte) 0b00010000, "System capabilities", SYSTEM_CAPABILITIES_LENGTH,
- SYSTEM_CAPABILITIES_VALUE);
- offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype A", CUSTOM_SUBTYPE_A_LENGTH,
- CUSTOM_SUBTYPE_A_VALUE, OUI[0], OUI[1], OUI[2], OUI_SUBTYPE_A[0]);
- offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype B", CUSTOM_SUBTYPE_B_LENGTH,
- CUSTOM_SUBTYPE_B_VALUE, OUI[0], OUI[1], OUI[2], OUI_SUBTYPE_B[0]);
+ offset = checkTLV(serialized, offset, (byte) 0b00001010, "SystemName", SYSTEM_NAME_LENGTH,
+ SYSTEM_NAME_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b00010000, "System capabilities",
+ SYSTEM_CAPABILITIES_LENGTH, SYSTEM_CAPABILITIES_VALUE);
+ offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype A",
+ CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE, OUI[0], OUI[1], OUI[2],
+ OUI_SUBTYPE_A[0]);
+ offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype B",
+ CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE, OUI[0], OUI[1], OUI[2],
+ OUI_SUBTYPE_B[0]);
+
+ }
+ /**
+ * Tests whether serialization of LLDP packet is correct
+ *
+ * @see LLDP#deserialize(byte[], int, int)
+ * @throws Exception
+ */
+ @Test
+ public void testDeserialize() throws Exception {
+ LLDP lldp = new LLDP();
+ byte[] bytesBeforeCustomA = new byte[] { 0x00, 0x26, (byte) 0xe1, OUI_SUBTYPE_A[0] };
+ byte[] bytesBeforeCustomB = new byte[] { 0x00, 0x26, (byte) 0xe1, OUI_SUBTYPE_B[0] };
+
+ byte[] rawLldpTlv = Bytes.concat(
+ awaitedBytes((byte) 0b00000010, CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE, null),
+ awaitedBytes((byte) 0b00000110, TTL_LENGTH, TTL_VALUE, null),
+ awaitedBytes((byte) 0b00000100, PORT_LENGTH, PORT_VALUE, null),
+ awaitedBytes((byte) 0b00001010, SYSTEM_NAME_LENGTH, SYSTEM_NAME_VALUE, null),
+ awaitedBytes((byte) 0b00010010, SYSTEM_CAPABILITIES_LENGTH,
+ SYSTEM_CAPABILITIES_VALUE, null),
+ awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE,
+ bytesBeforeCustomA),
+ awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE,
+ bytesBeforeCustomB));
+
+ lldp.deserialize(rawLldpTlv, 0, rawLldpTlv.length * NetUtils.NumBitsInAByte);
+ Assert.assertEquals("chassis", new String(lldp.getChassisId().getValue()));
+ Assert.assertArrayEquals(TTL_VALUE, lldp.getTtl().getValue());
+ Assert.assertEquals("dummy port id", new String(lldp.getPortId().getValue()));
+ Assert.assertEquals("dummy system name", new String(lldp.getSystemNameId().getValue()));
+
+ // optional items check
+ List<LLDPTLV> tlvOptionalList = lldp.getOptionalTLVList();
+ Assert.assertEquals(1, tlvOptionalList.size());
+
+ LLDPTLV itemOpt0 = tlvOptionalList.get(0);
+ Assert.assertEquals(9, itemOpt0.getType());
+ Assert.assertEquals("dummy system capabilities", new String(itemOpt0.getValue()));
+
+ // custom items check
+ List<LLDPTLV> tlvCustomList = lldp.getCustomTlvList();
+ Assert.assertEquals(2, tlvCustomList.size());
+
+ checkCustomTlv(tlvCustomList.get(0), "first custom value A");
+ checkCustomTlv(tlvCustomList.get(1), "second custom value B");
+ }
+
+ /**
+ * @param customItem
+ * @param expectedValue
+ */
+ private static void checkCustomTlv(LLDPTLV customItem, String expectedValue) {
+ Assert.assertEquals(127, customItem.getType());
+ LOG.debug("custom TLV1.length: {}", customItem.getLength());
+ Assert.assertEquals(expectedValue,
+ new String(
+ LLDPTLV.getCustomString(
+ customItem.getValue(),
+ customItem.getLength()))
+ );
}
private static int checkTLV(byte[] serializedData, int offset, byte typeTLVBits, String typeTLVName, short lengthTLV,