blob: 14edd04e096f7af5bc1386f98951e92077769426 [file] [log] [blame]
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
package net.onrc.onos.core.packet;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* The class representing LLDP Organizationally Specific TLV.
*
* @author Sho Shimizu (sho.shimizu@gmail.com)
*/
public class LLDPOrganizationalTLV extends LLDPTLV {
public static final int OUI_LENGTH = 3;
public static final int SUBTYPE_LENGTH = 1;
public static final byte ORGANIZATIONAL_TLV_TYPE = 127;
public static final int MAX_INFOSTRING_LENGTH = 507;
protected byte[] oui;
protected byte subType;
private byte[] infoString;
public LLDPOrganizationalTLV() {
type = ORGANIZATIONAL_TLV_TYPE;
}
/**
* Set the value of OUI.
*
* @param oui The value of OUI to be set.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setOUI(byte[] oui) {
if (oui.length != OUI_LENGTH) {
throw new IllegalArgumentException("The length of OUI must be " + OUI_LENGTH +
", but it is " + oui.length);
}
this.oui = Arrays.copyOf(oui, oui.length);
return this;
}
/**
* Returns the value of the OUI.
*
* @return The value of the OUI .
*/
public byte[] getOUI() {
return Arrays.copyOf(oui, oui.length);
}
/**
* Set the value of sub type.
*
* @param subType The value of sub type to be set.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setSubType(byte subType) {
this.subType = subType;
return this;
}
/**
* Returns the value of the sub type.
*
* @return The value of the sub type.
*/
public byte getSubType() {
return subType;
}
/**
* Set the value of information string.
*
* @param infoString the byte array of the value of information string.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setInfoString(byte[] infoString) {
if (infoString.length > MAX_INFOSTRING_LENGTH) {
throw new IllegalArgumentException("The length of infoString cannot exceed " + MAX_INFOSTRING_LENGTH);
}
this.infoString = Arrays.copyOf(infoString, infoString.length);
return this;
}
/**
* Set the value of information string.
* The String value is automatically converted into byte array with UTF-8 encoding.
*
* @param infoString the String value of information string.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setInfoString(String infoString) {
byte[] infoStringBytes = infoString.getBytes(Charset.forName("UTF-8"));
return setInfoString(infoStringBytes);
}
/**
* Returns the value of information string.
*
* @return the value of information string.
*/
public byte[] getInfoString() {
return Arrays.copyOf(infoString, infoString.length);
}
@Override
public byte[] serialize() {
int valueLength = OUI_LENGTH + SUBTYPE_LENGTH + infoString.length;
value = new byte[valueLength];
ByteBuffer bb = ByteBuffer.wrap(value);
bb.put(oui);
bb.put(subType);
bb.put(infoString);
return super.serialize();
}
@Override
public LLDPTLV deserialize(ByteBuffer bb) {
super.deserialize(bb);
ByteBuffer optionalField = ByteBuffer.wrap(value);
byte[] oui = new byte[OUI_LENGTH];
optionalField.get(oui);
setOUI(oui);
setSubType(optionalField.get());
byte[] infoString = new byte[getLength() - OUI_LENGTH - SUBTYPE_LENGTH];
optionalField.get(infoString);
setInfoString(infoString);
return this;
}
@Override
public int hashCode() {
final int prime = 1423;
int result = 1;
result = prime * result + type;
result = prime * result + length;
result = prime * result + Arrays.hashCode(oui);
result = prime * result + subType;
result = prime * result + Arrays.hashCode(infoString);
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!super.equals(o)) {
return false;
}
//
// NOTE: Subclasses are are considered as change of identity, hence
// equals() will return false if the class type doesn't match.
//
if (getClass() != o.getClass()) {
return false;
}
LLDPOrganizationalTLV other = (LLDPOrganizationalTLV) o;
if (this.type != other.type) {
return false;
}
if (this.length != other.length) {
return false;
}
if (!Arrays.equals(this.oui, other.oui)) {
return false;
}
if (this.subType != other.subType) {
return false;
}
if (!Arrays.equals(this.infoString, other.infoString)) {
return false;
}
return true;
}
}