Initial opendaylight infrastructure commit!!
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / packet / LLDPTLV.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.io.UnsupportedEncodingException;
13 import java.util.HashMap;
14
15 import java.util.Arrays;
16 import java.util.LinkedHashMap;
17 import java.util.Map;
18 import org.apache.commons.lang3.builder.EqualsBuilder;
19 import org.apache.commons.lang3.builder.HashCodeBuilder;
20 import org.apache.commons.lang3.tuple.MutablePair;
21 import org.apache.commons.lang3.tuple.Pair;
22 import org.opendaylight.controller.sal.utils.HexEncode;
23 import org.opendaylight.controller.sal.utils.NetUtils;
24
25 /**
26  * Class that represents the LLDPTLV objects
27  */
28
29 public class LLDPTLV extends Packet {
30     private static final String TYPE = "Type";
31     private static final String LENGTH = "Length";
32     private static final String VALUE = "Value";
33     private static final int LLDPTLVFields = 3;
34         public static final byte[] OFOUI = new byte[] {(byte)0x00, (byte)0x26, (byte)0xe1};     // OpenFlow OUI
35         public static final byte[] customTlvSubType = new byte[] {0};
36         public static final int customTlvOffset = OFOUI.length + customTlvSubType.length;
37         public static final byte chassisIDSubType[] = new byte[] {4};   // MAC address for the system
38         public static final byte portIDSubType[] = new byte[] {7};      // locally assigned
39
40         public enum TLVType {
41                 Unknown         ((byte)0),
42                 ChassisID       ((byte)1),
43                 PortID          ((byte)2),
44                 TTL                     ((byte)3),
45                 PortDesc        ((byte)4),
46                 SystemName      ((byte)5),
47                 SystemDesc      ((byte)6),
48                 Custom          ((byte)127);
49                 
50                 private byte value;
51                 private TLVType(byte value) {
52                         this.value = value;
53                 }
54                 public byte getValue() {
55                         return value;
56                 }
57         }
58
59     private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
60         private static final long serialVersionUID = 1L;
61
62         {
63             put(TYPE, new MutablePair<Integer, Integer>(0, 7));
64             put(LENGTH, new MutablePair<Integer, Integer>(7, 9));
65             put(VALUE, new MutablePair<Integer, Integer>(16, 0));
66         }
67     };
68
69     protected Map<String, byte[]> fieldValues;
70
71     /**
72      * Default constructor that creates and sets the hash map values
73      * and sets the payload to null
74      */
75     public LLDPTLV() {
76         payload = null;
77         fieldValues = new HashMap<String, byte[]>(LLDPTLVFields);
78         hdrFieldCoordMap = fieldCoordinates;
79         hdrFieldsMap = fieldValues;
80     }
81
82     /**
83      * Constructor that writes the passed LLDPTLV values to the
84      * hdrFieldsMap
85      */
86     public LLDPTLV(LLDPTLV other) {
87         for (Map.Entry<String, byte[]> entry : other.hdrFieldsMap.entrySet()) {
88             this.hdrFieldsMap.put(entry.getKey(), entry.getValue());
89         }
90     }
91
92     /**
93      * @return int - the length of TLV
94      */
95     public int getLength() {
96         return (int) BitBufferHelper.toNumber(fieldValues.get(LENGTH),
97                 fieldCoordinates.get(LENGTH).getRight().intValue());
98     }
99
100     /**
101      * @return byte - the type of TLV
102      */
103     public byte getType() {
104         return BitBufferHelper.getByte(fieldValues.get(TYPE));
105     }
106
107     /**
108      * @return byte[] - the value field of TLV
109      */
110     public byte[] getValue() {
111         return fieldValues.get(VALUE);
112     }
113
114     /**
115      * @param byte - the type to set
116      * @return LLDPTLV
117      */
118     public LLDPTLV setType(byte type) {
119         byte[] lldpTLVtype = { type };
120         fieldValues.put(TYPE, lldpTLVtype);
121         return this;
122     }
123
124     /**
125      * @param short - the length to set
126      * @return LLDPTLV
127      */
128     public LLDPTLV setLength(short length) {
129         fieldValues.put(LENGTH, BitBufferHelper.toByteArray(length));
130         return this;
131     }
132
133     /**
134      * @param byte[] - the value to set
135      * @return LLDPTLV
136      */
137     public LLDPTLV setValue(byte[] value) {
138         fieldValues.put(VALUE, value);
139         return this;
140     }
141
142     @Override
143     public void setHeaderField(String headerField, byte[] readValue) {
144         hdrFieldsMap.put(headerField, readValue);
145     }
146
147     @Override
148     public int hashCode() {
149         return HashCodeBuilder.reflectionHashCode(this);
150     }
151
152     @Override
153     public boolean equals(Object obj) {
154         return EqualsBuilder.reflectionEquals(this, obj);
155     }
156
157     @Override
158     public int getfieldnumBits(String fieldName) throws Exception {
159         if (fieldName.equals(VALUE)) {
160             return (NetUtils.NumBitsInAByte * (int) BitBufferHelper.getShort(
161                     fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH)
162                             .getRight().intValue()));
163         }
164         return fieldCoordinates.get(fieldName).getRight();
165     }
166
167     /**
168      * Returns the size in bits of the whole TLV
169      * @return int - size in bits of full TLV
170      * @throws Exception
171      */
172     public int getTLVSize() throws Exception {
173         return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static
174                 LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
175         getfieldnumBits(VALUE)); // variable
176     }
177     
178     /**
179      * Creates the ChassisID TLV value including the subtype and ChassisID string
180      * 
181      * @param nodeId node identifier string
182      * @return the ChassisID TLV value in byte array
183      */
184     static public byte[] createChassisIDTLVValue(String nodeId) {
185         byte[] cid = HexEncode.bytesFromHexString(nodeId);
186         byte[] cidValue = new byte[cid.length + chassisIDSubType.length];
187
188         System.arraycopy(chassisIDSubType, 0, cidValue, 0, chassisIDSubType.length);
189         System.arraycopy(cid, 0, cidValue, chassisIDSubType.length, cid.length);
190
191         return cidValue;
192     }
193
194     /**
195      * Creates the PortID TLV value including the subtype and PortID string
196      * 
197      * @param portId port identifier string
198      * @return the PortID TLV value in byte array
199      */
200     static public byte[] createPortIDTLVValue(String portId) {
201         byte[] pid = portId.getBytes();
202         byte[] pidValue = new byte[pid.length + portIDSubType.length];
203
204         System.arraycopy(portIDSubType, 0, pidValue, 0, portIDSubType.length);
205         System.arraycopy(pid, 0, pidValue, portIDSubType.length, pid.length);
206
207         return pidValue;
208     }
209
210     /**
211      * Creates the custom TLV value including OUI, subtype and custom string
212      * 
213      * @param portId port identifier string
214      * @return the custom TLV value in byte array
215      */
216     static public byte[] createCustomTLVValue(String customString) {
217         byte[] customArray = customString.getBytes();
218         byte[] customValue = new byte[customTlvOffset + customArray.length];
219
220         System.arraycopy(OFOUI, 0, customValue, 0, OFOUI.length);
221         System.arraycopy(customTlvSubType, 0, customValue, OFOUI.length,
222                 customTlvSubType.length);
223         System.arraycopy(customArray, 0, customValue, customTlvOffset,
224                 customArray.length);
225
226         return customValue;
227     }
228
229     /**
230      * Retrieves the string from TLV value and returns it in HexString format
231      * 
232      * @param tlvValue the TLV value
233      * @param tlvLen the TLV length
234      * @return the HexString
235      */
236     static public String getHexStringValue(byte[] tlvValue, int tlvLen) {
237         byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];                
238         System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0, cidBytes.length);
239         return HexEncode.bytesToHexStringWithColumn(cidBytes);
240     }
241
242     /**
243      * Retrieves the string from TLV value
244      * 
245      * @param tlvValue the TLV value
246      * @param tlvLen the TLV length
247      * @return the string
248      */
249     static public String getStringValue(byte[] tlvValue, int tlvLen) {
250         byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
251         System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0, pidBytes.length);
252         return (new String(pidBytes));
253     }
254
255     /**
256      * Retrieves the custom string from the Custom TLV value which includes OUI, subtype and custom string
257      * 
258      * @param customTlvValue the custom TLV value
259      * @param customTlvLen the custom TLV length
260      * @return the custom string
261      */
262     static public String getCustomString(byte[] customTlvValue, int customTlvLen) {
263         String customString = "";
264         byte[] vendor = new byte[3];
265         System.arraycopy(customTlvValue, 0, vendor, 0, vendor.length);
266         if (Arrays.equals(vendor, LLDPTLV.OFOUI)) {
267             int customArrayLength = customTlvLen - customTlvOffset;
268             byte[] customArray = new byte[customArrayLength];
269             System.arraycopy(customTlvValue, customTlvOffset,
270                     customArray, 0, customArrayLength);
271             try {
272                 customString = new String(customArray, "UTF-8");
273             } catch (UnsupportedEncodingException e) {
274             }
275         }
276         
277         return customString;
278     }    
279 }