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.liblldp;
11 import java.util.ArrayList;
12 import java.util.LinkedHashMap;
13 import java.util.List;
17 * Class that represents the LLDP frame objects
20 public class LLDP extends Packet {
21 private static final String CHASSISID = "ChassisId";
22 private static final String SYSTEMNAMEID = "SystemNameID";
23 private static final String PORTID = "PortId";
24 private static final String TTL = "TTL";
25 private static final int LLDPDefaultTlvs = 4;
26 private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0)
28 public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80,
29 (byte) 0xc2, 0, 0, (byte) 0xe };
30 private Map<Byte, LLDPTLV> tlvList;
33 * Default constructor that creates the tlvList LinkedHashMap
37 tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
41 * Constructor that creates the tlvList LinkedHashMap and sets the write
44 public LLDP(boolean writeAccess) {
46 tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs); // Mandatory
52 * - description of the type of TLV
53 * @return byte - type of TLV
55 private byte getType(String typeDesc) {
56 if (typeDesc.equals(CHASSISID)) {
57 return LLDPTLV.TLVType.ChassisID.getValue();
58 } else if (typeDesc.equals(PORTID)) {
59 return LLDPTLV.TLVType.PortID.getValue();
60 } else if (typeDesc.equals(TTL)) {
61 return LLDPTLV.TLVType.TTL.getValue();
63 return LLDPTLV.TLVType.Unknown.getValue();
69 * - description of the type of TLV
70 * @return LLDPTLV - full TLV
72 public LLDPTLV getTLV(String type) {
73 return tlvList.get(getType(type));
78 * - description of the type of TLV
83 public void setTLV(String type, LLDPTLV tlv) {
84 tlvList.put(getType(type), tlv);
88 * @return the chassisId TLV
90 public LLDPTLV getChassisId() {
91 return getTLV(CHASSISID);
96 * - the chassisId to set
98 public LLDP setChassisId(LLDPTLV chassisId) {
99 tlvList.put(getType(CHASSISID), chassisId);
104 * @return the SystemName TLV
106 public LLDPTLV getSystemNameId() {
107 return getTLV(SYSTEMNAMEID);
112 * - the chassisId to set
114 public LLDP setSystemNameId(LLDPTLV systemNameId) {
115 tlvList.put(getType(SYSTEMNAMEID), systemNameId);
120 * @return LLDPTLV - the portId TLV
122 public LLDPTLV getPortId() {
123 return tlvList.get(getType(PORTID));
128 * - the portId to set
131 public LLDP setPortId(LLDPTLV portId) {
132 tlvList.put(getType(PORTID), portId);
137 * @return LLDPTLV - the ttl TLV
139 public LLDPTLV getTtl() {
140 return tlvList.get(getType(TTL));
148 public LLDP setTtl(LLDPTLV ttl) {
149 tlvList.put(getType(TTL), ttl);
154 * @return the optionalTLVList
156 public List<LLDPTLV> getOptionalTLVList() {
157 List<LLDPTLV> list = new ArrayList<LLDPTLV>();
158 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
159 byte type = entry.getKey();
160 if ((type == LLDPTLV.TLVType.ChassisID.getValue())
161 || (type == LLDPTLV.TLVType.PortID.getValue())
162 || (type == LLDPTLV.TLVType.TTL.getValue())) {
165 list.add(entry.getValue());
172 * @param optionalTLVList
173 * the optionalTLVList to set
176 public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
177 for (LLDPTLV tlv : optionalTLVList) {
178 tlvList.put(tlv.getType(), tlv);
184 public Packet deserialize(byte[] data, int bitOffset, int size)
185 throws PacketException {
186 int lldpOffset = bitOffset; // LLDP start
187 int lldpSize = size; // LLDP size
189 if (logger.isTraceEnabled()) {
190 logger.trace("LLDP: {} (offset {} bitsize {})", new Object[] {
191 HexEncode.bytesToHexString(data), lldpOffset, lldpSize });
194 * Deserialize the TLVs until we reach the end of the packet
196 while (lldpSize > 0) {
197 LLDPTLV tlv = new LLDPTLV();
198 tlv.deserialize(data, lldpOffset, lldpSize);
199 if (tlv.getType() == 0 && tlv.getLength() == 0) {
202 int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits
203 lldpOffset += tlvSize;
205 this.tlvList.put(tlv.getType(), tlv);
211 public byte[] serialize() throws PacketException {
213 byte[] serializedBytes = new byte[getLLDPPacketLength()];
215 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
216 LLDPTLV tlv = entry.getValue();
217 int numBits = tlv.getTLVSize();
219 BitBufferHelper.setBytes(serializedBytes, tlv.serialize(),
220 startOffset, numBits);
221 } catch (BufferException e) {
222 throw new PacketException(e.getMessage());
224 startOffset += numBits;
226 // Now add the empty LLDPTLV at the end
228 BitBufferHelper.setBytes(serializedBytes,
229 LLDP.emptyTLV.serialize(), startOffset,
230 LLDP.emptyTLV.getTLVSize());
231 } catch (BufferException e) {
232 throw new PacketException(e.getMessage());
235 if (logger.isTraceEnabled()) {
236 logger.trace("LLDP: serialized: {}",
237 HexEncode.bytesToHexString(serializedBytes));
239 return serializedBytes;
243 * Returns the size of LLDP packet in bytes
245 * @return int - LLDP Packet size in bytes
247 private int getLLDPPacketLength() {
251 for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
252 tlv = entry.getValue();
253 len += tlv.getTLVSize();
255 len += LLDP.emptyTLV.getTLVSize();
257 return len / NetUtils.NumBitsInAByte;