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;
15 import org.opendaylight.controller.sal.utils.HexEncode;
16 import org.opendaylight.controller.sal.utils.NetUtils;
19 * Class that represents the LLDP frame objects
22 public class LLDP extends Packet {
23 private static final String CHASSISID = "ChassisId";
24 private static final String PORTID = "PortId";
25 private static final String TTL = "TTL";
26 private static final int LLDPDefaultTlvs = 3;
27 private static LLDPTLV emptyTLV = new LLDPTLV().setLength((short) 0)
29 public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80,
30 (byte) 0xc2, 0, 0, (byte) 0xe };
31 private Map<Byte, LLDPTLV> tlvList;
34 * Default constructor that creates the tlvList LinkedHashMap
38 tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
42 * Constructor that creates the tlvList LinkedHashMap and sets the write
45 public LLDP(boolean writeAccess) {
47 tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs); // Mandatory
53 * - description of the type of TLV
54 * @return byte - type of TLV
56 private byte getType(String typeDesc) {
57 if (typeDesc.equals(CHASSISID)) {
58 return LLDPTLV.TLVType.ChassisID.getValue();
59 } else if (typeDesc.equals(PORTID)) {
60 return LLDPTLV.TLVType.PortID.getValue();
61 } else if (typeDesc.equals(TTL)) {
62 return LLDPTLV.TLVType.TTL.getValue();
64 return LLDPTLV.TLVType.Unknown.getValue();
70 * - description of the type of TLV
71 * @return LLDPTLV - full TLV
73 public LLDPTLV getTLV(String type) {
74 return tlvList.get(getType(type));
79 * - description of the type of TLV
84 public void setTLV(String type, LLDPTLV tlv) {
85 tlvList.put(getType(type), tlv);
89 * @return the chassisId TLV
91 public LLDPTLV getChassisId() {
92 return getTLV(CHASSISID);
97 * - the chassisId to set
99 public LLDP setChassisId(LLDPTLV chassisId) {
100 tlvList.put(getType(CHASSISID), chassisId);
105 * @return LLDPTLV - the portId TLV
107 public LLDPTLV getPortId() {
108 return tlvList.get(getType(PORTID));
113 * - the portId to set
116 public LLDP setPortId(LLDPTLV portId) {
117 tlvList.put(getType(PORTID), portId);
122 * @return LLDPTLV - the ttl TLV
124 public LLDPTLV getTtl() {
125 return tlvList.get(getType(TTL));
133 public LLDP setTtl(LLDPTLV ttl) {
134 tlvList.put(getType(TTL), ttl);
139 * @return the optionalTLVList
141 public List<LLDPTLV> getOptionalTLVList() {
142 List<LLDPTLV> list = new ArrayList<LLDPTLV>();
143 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
144 byte type = entry.getKey();
145 if ((type == LLDPTLV.TLVType.ChassisID.getValue())
146 || (type == LLDPTLV.TLVType.PortID.getValue())
147 || (type == LLDPTLV.TLVType.TTL.getValue())) {
150 list.add(entry.getValue());
157 * @param optionalTLVList
158 * the optionalTLVList to set
161 public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
162 for (LLDPTLV tlv : optionalTLVList) {
163 tlvList.put(tlv.getType(), tlv);
169 public Packet deserialize(byte[] data, int bitOffset, int size)
170 throws PacketException {
171 int lldpOffset = bitOffset; // LLDP start
172 int lldpSize = size; // LLDP size
174 if (logger.isTraceEnabled()) {
175 logger.trace("LLDP: {} (offset {} bitsize {})", new Object[] {
176 HexEncode.bytesToHexString(data), lldpOffset, lldpSize });
179 * Deserialize the TLVs until we reach the end of the packet
181 while (lldpSize > 0) {
182 LLDPTLV tlv = new LLDPTLV();
183 tlv.deserialize(data, lldpOffset, lldpSize);
184 int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits
185 lldpOffset += tlvSize;
187 this.tlvList.put(tlv.getType(), tlv);
193 public byte[] serialize() throws PacketException {
195 byte[] serializedBytes = new byte[getLLDPPacketLength()];
197 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
198 LLDPTLV tlv = entry.getValue();
199 int numBits = tlv.getTLVSize();
201 BitBufferHelper.setBytes(serializedBytes, tlv.serialize(),
202 startOffset, numBits);
203 } catch (BufferException e) {
204 throw new PacketException(e.getMessage());
206 startOffset += numBits;
208 // Now add the empty LLDPTLV at the end
210 BitBufferHelper.setBytes(serializedBytes,
211 LLDP.emptyTLV.serialize(), startOffset,
212 LLDP.emptyTLV.getTLVSize());
213 } catch (BufferException e) {
214 throw new PacketException(e.getMessage());
217 if (logger.isTraceEnabled()) {
218 logger.trace("LLDP: serialized: {}",
219 HexEncode.bytesToHexString(serializedBytes));
221 return serializedBytes;
225 * Returns the size of LLDP packet in bytes
227 * @return int - LLDP Packet size in bytes
229 private int getLLDPPacketLength() {
233 for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
234 tlv = entry.getValue();
235 len += tlv.getTLVSize();
237 len += LLDP.emptyTLV.getTLVSize();
239 return len / NetUtils.NumBitsInAByte;