Checkstyle enforcer
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / packet / LLDP.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.controller.sal.packet;
10
11 import java.util.ArrayList;
12 import java.util.LinkedHashMap;
13 import java.util.List;
14 import java.util.Map;
15 import org.opendaylight.controller.sal.utils.HexEncode;
16 import org.opendaylight.controller.sal.utils.NetUtils;
17
18 /**
19  * Class that represents the LLDP frame objects
20  */
21
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)
28             .setType((byte) 0);
29     public static final byte[] LLDPMulticastMac = { 1, (byte) 0x80,
30             (byte) 0xc2, 0, 0, (byte) 0xe };
31     private Map<Byte, LLDPTLV> tlvList;
32
33     /**
34      * Default constructor that creates the tlvList LinkedHashMap
35      */
36     public LLDP() {
37         super();
38         tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs);
39     }
40
41     /**
42      * Constructor that creates the tlvList LinkedHashMap and sets the write
43      * access for the same
44      */
45     public LLDP(boolean writeAccess) {
46         super(writeAccess);
47         tlvList = new LinkedHashMap<Byte, LLDPTLV>(LLDPDefaultTlvs); // Mandatory
48                                                                      // TLVs
49     }
50
51     /**
52      * @param String
53      *            - description of the type of TLV
54      * @return byte - type of TLV
55      */
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();
63         } else {
64             return LLDPTLV.TLVType.Unknown.getValue();
65         }
66     }
67
68     /**
69      * @param String
70      *            - description of the type of TLV
71      * @return LLDPTLV - full TLV
72      */
73     public LLDPTLV getTLV(String type) {
74         return tlvList.get(getType(type));
75     }
76
77     /**
78      * @param String
79      *            - description of the type of TLV
80      * @param LLDPTLV
81      *            - tlv to set
82      * @return void
83      */
84     public void setTLV(String type, LLDPTLV tlv) {
85         tlvList.put(getType(type), tlv);
86     }
87
88     /**
89      * @return the chassisId TLV
90      */
91     public LLDPTLV getChassisId() {
92         return getTLV(CHASSISID);
93     }
94
95     /**
96      * @param LLDPTLV
97      *            - the chassisId to set
98      */
99     public LLDP setChassisId(LLDPTLV chassisId) {
100         tlvList.put(getType(CHASSISID), chassisId);
101         return this;
102     }
103
104     /**
105      * @return LLDPTLV - the portId TLV
106      */
107     public LLDPTLV getPortId() {
108         return tlvList.get(getType(PORTID));
109     }
110
111     /**
112      * @param LLDPTLV
113      *            - the portId to set
114      * @return LLDP
115      */
116     public LLDP setPortId(LLDPTLV portId) {
117         tlvList.put(getType(PORTID), portId);
118         return this;
119     }
120
121     /**
122      * @return LLDPTLV - the ttl TLV
123      */
124     public LLDPTLV getTtl() {
125         return tlvList.get(getType(TTL));
126     }
127
128     /**
129      * @param LLDPTLV
130      *            - the ttl to set
131      * @return LLDP
132      */
133     public LLDP setTtl(LLDPTLV ttl) {
134         tlvList.put(getType(TTL), ttl);
135         return this;
136     }
137
138     /**
139      * @return the optionalTLVList
140      */
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())) {
148                 continue;
149             } else {
150                 list.add(entry.getValue());
151             }
152         }
153         return list;
154     }
155
156     /**
157      * @param optionalTLVList
158      *            the optionalTLVList to set
159      * @return LLDP
160      */
161     public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
162         for (LLDPTLV tlv : optionalTLVList) {
163             tlvList.put(tlv.getType(), tlv);
164         }
165         return this;
166     }
167
168     @Override
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
173
174         if (logger.isTraceEnabled()) {
175           logger.trace("LLDP: {} (offset {} bitsize {})", new Object[] {
176                   HexEncode.bytesToHexString(data), lldpOffset, lldpSize });
177         }
178         /*
179          * Deserialize the TLVs until we reach the end of the packet
180          */
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;
186             lldpSize -= tlvSize;
187             this.tlvList.put(tlv.getType(), tlv);
188         }
189         return this;
190     }
191
192     @Override
193     public byte[] serialize() throws PacketException {
194         int startOffset = 0;
195         byte[] serializedBytes = new byte[getLLDPPacketLength()];
196
197         for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
198             LLDPTLV tlv = entry.getValue();
199             int numBits = tlv.getTLVSize();
200             try {
201                 BitBufferHelper.setBytes(serializedBytes, tlv.serialize(),
202                         startOffset, numBits);
203             } catch (BufferException e) {
204                 throw new PacketException(e.getMessage());
205             }
206             startOffset += numBits;
207         }
208         // Now add the empty LLDPTLV at the end
209         try {
210             BitBufferHelper.setBytes(serializedBytes,
211                     LLDP.emptyTLV.serialize(), startOffset,
212                     LLDP.emptyTLV.getTLVSize());
213         } catch (BufferException e) {
214             throw new PacketException(e.getMessage());
215         }
216
217         if (logger.isTraceEnabled()) {
218           logger.trace("LLDP: serialized: {}",
219                   HexEncode.bytesToHexString(serializedBytes));
220         }
221         return serializedBytes;
222     }
223
224     /**
225      * Returns the size of LLDP packet in bytes
226      *
227      * @return int - LLDP Packet size in bytes
228      */
229     private int getLLDPPacketLength() {
230         int len = 0;
231         LLDPTLV tlv;
232
233         for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
234             tlv = entry.getValue();
235             len += tlv.getTLVSize();
236         }
237         len += LLDP.emptyTLV.getTLVSize();
238
239         return len / NetUtils.NumBitsInAByte;
240     }
241 }