Initial opendaylight infrastructure commit!!
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / packet / LLDP.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.sal.packet;
11
12 import java.util.ArrayList;
13 import java.util.LinkedHashMap;
14 import java.util.List;
15 import java.util.Map;
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).setType((byte)0);
28         public static final byte[] LLDPMulticastMac = {1,(byte)0x80,(byte)0xc2, 0, 0,(byte)0xe};
29         private Map<Byte, LLDPTLV> tlvList;
30
31         /**
32          * Default constructor that creates the tlvList LinkedHashMap
33          */
34         public LLDP() {
35                 super();
36                 tlvList = new LinkedHashMap<Byte,LLDPTLV>(LLDPDefaultTlvs);
37         }
38
39         /**
40          * Constructor that creates the tlvList LinkedHashMap and sets
41          * the write access for the same
42          */
43         public LLDP (boolean writeAccess) {
44                 super(writeAccess);
45                 tlvList = new LinkedHashMap<Byte,LLDPTLV>(LLDPDefaultTlvs);     // Mandatory TLVs       
46         }
47         
48         /**
49          * @param String - description of the type of TLV
50          * @return byte - type of TLV
51          */
52         private byte getType(String typeDesc) {
53                 if (typeDesc.equals(CHASSISID)) {
54                         return LLDPTLV.TLVType.ChassisID.getValue();
55                 } else if (typeDesc.equals(PORTID)) {
56                         return LLDPTLV.TLVType.PortID.getValue();
57                 } else if (typeDesc.equals(TTL)) {
58                         return LLDPTLV.TLVType.TTL.getValue();
59                 } else {
60                         return LLDPTLV.TLVType.Unknown.getValue();
61                 }                       
62         }
63
64         /**
65          * @param String - description of the type of TLV
66          * @return LLDPTLV - full TLV
67          */
68     public LLDPTLV getTLV(String type) {
69         return tlvList.get(getType(type));
70     }
71
72         /**
73          * @param String - description of the type of TLV
74          * @param LLDPTLV - tlv to set
75          * @return void
76          */
77     public void setTLV(String type, LLDPTLV tlv) {
78         tlvList.put(getType(type), tlv);
79     }
80
81     /**
82      * @return the chassisId TLV
83      */
84     public LLDPTLV getChassisId() {
85         return getTLV(CHASSISID);
86     }
87
88     /**
89      * @param LLDPTLV - the chassisId to set
90      */
91     public LLDP setChassisId(LLDPTLV chassisId) {
92         tlvList.put(getType(CHASSISID), chassisId);
93         return this;
94     }
95     
96     /**
97      * @return LLDPTLV - the portId TLV
98      */
99     public LLDPTLV getPortId() {
100         return tlvList.get(getType(PORTID));
101     }
102
103     /**
104      * @param LLDPTLV - the portId to set
105      * @return LLDP
106      */
107     public LLDP setPortId(LLDPTLV portId) {
108         tlvList.put(getType(PORTID), portId);
109         return this;
110     }
111
112     /**
113      * @return LLDPTLV - the ttl TLV
114      */
115     public LLDPTLV getTtl() {
116         return tlvList.get(getType(TTL));
117     }
118
119     /**
120      * @param LLDPTLV - the ttl to set
121      * @return LLDP
122      */
123     public LLDP setTtl(LLDPTLV ttl) {
124         tlvList.put(getType(TTL), ttl);
125         return this;
126     }
127
128     /**
129      * @return the optionalTLVList
130      */
131     public List<LLDPTLV> getOptionalTLVList() {
132         List<LLDPTLV> list = new ArrayList<LLDPTLV>();
133         for (Map.Entry<Byte,LLDPTLV> entry : tlvList.entrySet()) {
134                 byte type = entry.getKey();
135                 if ((type == LLDPTLV.TLVType.ChassisID.getValue()) ||
136                         (type == LLDPTLV.TLVType.PortID.getValue()) ||
137                         (type == LLDPTLV.TLVType.TTL.getValue())) {
138                         continue;
139                 } else {
140                         list.add(entry.getValue());
141                 }
142         }
143         return list;
144     }
145
146     /**
147      * @param optionalTLVList the optionalTLVList to set
148      * @return LLDP
149      */
150     public LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList)
151     {
152         for (LLDPTLV tlv : optionalTLVList) {
153                 tlvList.put(tlv.getType(), tlv);
154         }
155         return this;
156     }
157
158     @Override
159     public Packet deserialize (byte[] data, int bitOffset, int size) throws Exception {
160         int lldpOffset = bitOffset; // LLDP start 
161         int lldpSize = size; // LLDP size
162
163         /*
164          * Deserialize the TLVs until we reach the end of the packet
165          */
166         
167         while (lldpSize > 0) {
168                 LLDPTLV tlv = new LLDPTLV();
169                 tlv.deserialize(data, lldpOffset, lldpSize);
170                 lldpOffset += tlv.getTLVSize(); //Size of current TLV in bits
171                 lldpSize -= tlv.getTLVSize();
172                 this.tlvList.put(tlv.getType(), tlv);
173         }
174                 return this;
175         }
176     
177     @Override
178     public byte[] serialize() throws Exception {
179                 int startOffset = 0;
180                 byte[] serializedBytes = new byte[getLLDPPacketLength()];
181                 
182                 for (Map.Entry<Byte, LLDPTLV> entry : tlvList.entrySet()) {
183                         LLDPTLV tlv = entry.getValue();
184                         int numBits = tlv.getTLVSize();
185                         BitBufferHelper.setBytes(serializedBytes, tlv.serialize(), startOffset, numBits);
186                         startOffset += numBits;
187                 }
188                 // Now add the empty LLDPTLV at the end
189                 BitBufferHelper.setBytes(serializedBytes, LLDP.emptyTLV.serialize(), startOffset, LLDP.emptyTLV.getTLVSize());
190                 
191                 return serializedBytes;
192     }
193     
194     /**
195      * Returns the size of LLDP packet in bytes
196      * @return int - LLDP Packet size in bytes
197      * @throws Exception 
198      */
199     private int getLLDPPacketLength() throws Exception {
200         int len = 0;
201         LLDPTLV tlv;
202         
203         for (Map.Entry<Byte, LLDPTLV> entry : this.tlvList.entrySet()) {
204                 tlv = entry.getValue();
205                 len += tlv.getTLVSize();
206         }
207         len += LLDP.emptyTLV.getTLVSize();
208         
209         return len/NetUtils.NumBitsInAByte;
210     }
211 }