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.util.ArrayList;
12 import java.util.LinkedHashMap;
13 import java.util.List;
16 import org.opendaylight.controller.sal.utils.HexEncode;
17 import org.opendaylight.controller.sal.utils.NetUtils;
20 * Class that represents the LLDP frame objects
23 public class LLDP extends Packet {
24 private static final String CHASSISID = "ChassisId";
25 private static final String SYSTEMNAMEID = "SystemNameID";
26 private static final String PORTID = "PortId";
27 private static final String TTL = "TTL";
28 private static final int LLDPDefaultTlvs = 4;
29 private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0)
31 public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80,
32 (byte) 0xc2, 0, 0, (byte) 0xe };
33 private Map<Byte, LLDPTLV> tlvList;
36 * Default constructor that creates the tlvList LinkedHashMap
40 tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
44 * Constructor that creates the tlvList LinkedHashMap and sets the write
47 public LLDP(boolean writeAccess) {
49 tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs); // Mandatory
55 * - description of the type of TLV
56 * @return byte - type of TLV
58 private byte getType(String typeDesc) {
59 if (typeDesc.equals(CHASSISID)) {
60 return LLDPTLV.TLVType.ChassisID.getValue();
61 } else if (typeDesc.equals(PORTID)) {
62 return LLDPTLV.TLVType.PortID.getValue();
63 } else if (typeDesc.equals(TTL)) {
64 return LLDPTLV.TLVType.TTL.getValue();
66 return LLDPTLV.TLVType.Unknown.getValue();
72 * - description of the type of TLV
73 * @return LLDPTLV - full TLV
75 public LLDPTLV getTLV(String type) {
76 return tlvList.get(getType(type));
81 * - description of the type of TLV
86 public void setTLV(String type, LLDPTLV tlv) {
87 tlvList.put(getType(type), tlv);
91 * @return the chassisId TLV
93 public LLDPTLV getChassisId() {
94 return getTLV(CHASSISID);
99 * - the chassisId to set
101 public LLDP setChassisId(LLDPTLV chassisId) {
102 tlvList.put(getType(CHASSISID), chassisId);
107 * @return the SystemName TLV
109 public LLDPTLV getSystemNameId() {
110 return getTLV(SYSTEMNAMEID);
115 * - the chassisId to set
117 public LLDP setSystemNameId(LLDPTLV systemNameId) {
118 tlvList.put(getType(SYSTEMNAMEID), systemNameId);
123 * @return LLDPTLV - the portId TLV
125 public LLDPTLV getPortId() {
126 return tlvList.get(getType(PORTID));
131 * - the portId to set
134 public LLDP setPortId(LLDPTLV portId) {
135 tlvList.put(getType(PORTID), portId);
140 * @return LLDPTLV - the ttl TLV
142 public LLDPTLV getTtl() {
143 return tlvList.get(getType(TTL));
151 public LLDP setTtl(LLDPTLV ttl) {
152 tlvList.put(getType(TTL), ttl);
157 * @return the optionalTLVList
159 public List<LLDPTLV> getOptionalTLVList() {
160 List<LLDPTLV> list = new ArrayList<LLDPTLV>();
161 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
162 byte type = entry.getKey();
163 if ((type == LLDPTLV.TLVType.ChassisID.getValue())
164 || (type == LLDPTLV.TLVType.PortID.getValue())
165 || (type == LLDPTLV.TLVType.TTL.getValue())) {
168 list.add(entry.getValue());
175 * @param optionalTLVList
176 * the optionalTLVList to set
179 public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
180 for (LLDPTLV tlv : optionalTLVList) {
181 tlvList.put(tlv.getType(), tlv);
187 public Packet deserialize(byte[] data, int bitOffset, int size)
188 throws PacketException {
189 int lldpOffset = bitOffset; // LLDP start
190 int lldpSize = size; // LLDP size
192 if (logger.isTraceEnabled()) {
193 logger.trace("LLDP: {} (offset {} bitsize {})", new Object[] {
194 HexEncode.bytesToHexString(data), lldpOffset, lldpSize });
197 * Deserialize the TLVs until we reach the end of the packet
199 while (lldpSize > 0) {
200 LLDPTLV tlv = new LLDPTLV();
201 tlv.deserialize(data, lldpOffset, lldpSize);
202 if (tlv.getType() == 0 && tlv.getLength() == 0) {
205 int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits
206 lldpOffset += tlvSize;
208 this.tlvList.put(tlv.getType(), tlv);
214 public byte[] serialize() throws PacketException {
216 byte[] serializedBytes = new byte[getLLDPPacketLength()];
218 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
219 LLDPTLV tlv = entry.getValue();
220 int numBits = tlv.getTLVSize();
222 BitBufferHelper.setBytes(serializedBytes, tlv.serialize(),
223 startOffset, numBits);
224 } catch (BufferException e) {
225 throw new PacketException(e.getMessage());
227 startOffset += numBits;
229 // Now add the empty LLDPTLV at the end
231 BitBufferHelper.setBytes(serializedBytes,
232 LLDP.emptyTLV.serialize(), startOffset,
233 LLDP.emptyTLV.getTLVSize());
234 } catch (BufferException e) {
235 throw new PacketException(e.getMessage());
238 if (logger.isTraceEnabled()) {
239 logger.trace("LLDP: serialized: {}",
240 HexEncode.bytesToHexString(serializedBytes));
242 return serializedBytes;
246 * Returns the size of LLDP packet in bytes
248 * @return int - LLDP Packet size in bytes
250 private int getLLDPPacketLength() {
254 for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
255 tlv = entry.getValue();
256 len += tlv.getTLVSize();
258 len += LLDP.emptyTLV.getTLVSize();
260 return len / NetUtils.NumBitsInAByte;