blob: d5bb7fba4bcfa18356affc839fa338615d523d9a [file] [log] [blame]
Jonathan Hart299d1132014-06-27 09:25:28 -07001/*******************************************************************************
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080016/**
Jonathan Hart299d1132014-06-27 09:25:28 -070017 * Copyright 2011, Big Switch Networks, Inc.
18 * Originally created by David Erickson, Stanford University
Ray Milkey269ffb92014-04-03 14:43:30 -070019 *
Jonathan Hart299d1132014-06-27 09:25:28 -070020 * Licensed under the Apache License, Version 2.0 (the "License"); you may
21 * not use this file except in compliance with the License. You may obtain
22 * a copy of the License at
Ray Milkey269ffb92014-04-03 14:43:30 -070023 *
Jonathan Hart299d1132014-06-27 09:25:28 -070024 * http://www.apache.org/licenses/LICENSE-2.0
Ray Milkey269ffb92014-04-03 14:43:30 -070025 *
Jonathan Hart299d1132014-06-27 09:25:28 -070026 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
28 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
29 * License for the specific language governing permissions and limitations
30 * under the License.
Ray Milkey269ffb92014-04-03 14:43:30 -070031 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070033package net.onrc.onos.core.packet;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080034
35import java.nio.ByteBuffer;
36import java.util.Arrays;
37
Yuta HIGUCHIaa132f52014-06-26 10:18:39 -070038// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080039/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080040 * @author David Erickson (daviderickson@cs.stanford.edu)
41 */
42public class LLDPTLV {
43 protected byte type;
44 protected short length;
45 protected byte[] value;
46
47 /**
48 * @return the type
49 */
50 public byte getType() {
51 return type;
52 }
53
54 /**
55 * @param type the type to set
56 */
57 public LLDPTLV setType(byte type) {
58 this.type = type;
59 return this;
60 }
61
62 /**
63 * @return the length
64 */
65 public short getLength() {
66 return length;
67 }
68
69 /**
70 * @param length the length to set
71 */
72 public LLDPTLV setLength(short length) {
73 this.length = length;
74 return this;
75 }
76
77 /**
78 * @return the value
79 */
80 public byte[] getValue() {
Jonathan Hart299d1132014-06-27 09:25:28 -070081 return Arrays.copyOf(value, value.length);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080082 }
83
84 /**
85 * @param value the value to set
86 */
87 public LLDPTLV setValue(byte[] value) {
Jonathan Hart299d1132014-06-27 09:25:28 -070088 this.value = Arrays.copyOf(value, value.length);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080089 return this;
90 }
91
92 public byte[] serialize() {
93 // type = 7 bits
94 // info string length 9 bits, each value == byte
95 // info string
96 short scratch = (short) (((0x7f & this.type) << 9) | (0x1ff & this.length));
Ray Milkey269ffb92014-04-03 14:43:30 -070097 byte[] data = new byte[2 + this.length];
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080098 ByteBuffer bb = ByteBuffer.wrap(data);
99 bb.putShort(scratch);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700100 if (this.value != null) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800101 bb.put(this.value);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700102 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800103 return data;
104 }
105
106 public LLDPTLV deserialize(ByteBuffer bb) {
107 short sscratch;
108 sscratch = bb.getShort();
109 this.type = (byte) ((sscratch >> 9) & 0x7f);
110 this.length = (short) (sscratch & 0x1ff);
111 if (this.length > 0) {
112 this.value = new byte[this.length];
113
114 // if there is an underrun just toss the TLV
Ray Milkeyb29e6262014-04-09 16:02:14 -0700115 if (bb.remaining() < this.length) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800116 return null;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700117 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800118 bb.get(this.value);
119 }
120 return this;
121 }
122
Jonathan Hart299d1132014-06-27 09:25:28 -0700123 /*
124 * (non-Javadoc)
125 *
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800126 * @see java.lang.Object#hashCode()
127 */
128 @Override
129 public int hashCode() {
130 final int prime = 1423;
131 int result = 1;
132 result = prime * result + length;
133 result = prime * result + type;
134 result = prime * result + Arrays.hashCode(value);
135 return result;
136 }
137
Jonathan Hart299d1132014-06-27 09:25:28 -0700138 /*
139 * (non-Javadoc)
140 *
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800141 * @see java.lang.Object#equals(java.lang.Object)
142 */
143 @Override
144 public boolean equals(Object obj) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700145 if (this == obj) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800146 return true;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700147 }
148 if (obj == null) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800149 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700150 }
Pavlin Radoslavovadc3ec12014-04-11 16:08:53 -0700151 //
152 // NOTE: Subclasses are are considered as change of identity, hence
153 // equals() will return false if the class type doesn't match.
154 //
155 // The implication is that two instances - base class and derived class
156 // will be different even if they have same bits on the wire.
157 // We use this assumption to address the fundamental
158 // "equivalence relation" issue with class inheritance and "equals()":
159 // http://www.artima.com/lejava/articles/equality.html
160 // http://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.html
161 //
162 // Based on existing code, we don't mix the usage of based and derived
163 // class instances.
164 //
165 // Note that the fix below is different from the Floodlight fix.
166 // The Floodlight code uses "if (!(obj instanceof LLDPTLV))", but
167 // that statement breaks the "equivalence relation".
168 //
169 if (getClass() != obj.getClass()) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800170 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700171 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800172 LLDPTLV other = (LLDPTLV) obj;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700173 if (length != other.length) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800174 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700175 }
176 if (type != other.type) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800177 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700178 }
179 if (!Arrays.equals(value, other.value)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800180 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700181 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800182 return true;
183 }
184}