| /** |
| * Copyright 2012, Big Switch Networks, Inc. |
| * |
| * 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.floodlightcontroller.packet; |
| |
| import java.nio.ByteBuffer; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * @author Shudong Zhou (shudong.zhou@bigswitch.com) |
| * |
| */ |
| public class BSN extends BasePacket { |
| public static final int BSN_MAGIC = 0x20000604; |
| public static final short BSN_VERSION_CURRENT = 0x0; |
| public static final short BSN_TYPE_PROBE = 0x1; |
| public static final short BSN_TYPE_BDDP = 0x2; |
| public static Map<Short, Class<? extends IPacket>> typeClassMap; |
| |
| static { |
| typeClassMap = new HashMap<Short, Class<? extends IPacket>>(); |
| typeClassMap.put(BSN_TYPE_PROBE, BSNPROBE.class); |
| typeClassMap.put(BSN_TYPE_BDDP, LLDP.class); |
| } |
| |
| protected short type; |
| protected short version; |
| |
| public BSN() { |
| version = BSN_VERSION_CURRENT; |
| } |
| |
| public BSN(short type) { |
| this.type = type; |
| version = BSN_VERSION_CURRENT; |
| } |
| |
| public short getType() { |
| return type; |
| } |
| |
| public BSN setType(short type) { |
| this.type = type; |
| return this; |
| } |
| |
| public short getVersion() { |
| return version; |
| } |
| |
| public BSN setVersion(short version) { |
| this.version = version; |
| return this; |
| } |
| |
| @Override |
| public byte[] serialize() { |
| short length = 4 /* magic */ + 2 /* type */ + 2 /* version */; |
| |
| byte[] payloadData = null; |
| if (this.payload != null) { |
| payload.setParent(this); |
| payloadData = payload.serialize(); |
| length += payloadData.length; |
| } |
| |
| byte[] data = new byte[length]; |
| ByteBuffer bb = ByteBuffer.wrap(data); |
| bb.putInt(BSN_MAGIC); |
| bb.putShort(this.type); |
| bb.putShort(this.version); |
| if (payloadData != null) |
| bb.put(payloadData); |
| |
| if (this.parent != null && this.parent instanceof Ethernet) |
| ((Ethernet)this.parent).setEtherType(Ethernet.TYPE_BSN); |
| |
| return data; |
| } |
| |
| @Override |
| public IPacket deserialize(byte[] data, int offset, int length) { |
| ByteBuffer bb = ByteBuffer.wrap(data, offset, length); |
| |
| int magic = bb.getInt(); |
| if (magic != BSN_MAGIC) { |
| throw new RuntimeException("Invalid BSN magic " + magic); |
| } |
| |
| this.type = bb.getShort(); |
| this.version = bb.getShort(); |
| if (this.version != BSN_VERSION_CURRENT) { |
| throw new RuntimeException( |
| "Invalid BSN packet version " + this.version + ", should be " |
| + BSN_VERSION_CURRENT); |
| } |
| |
| IPacket payload; |
| if (typeClassMap.containsKey(this.type)) { |
| Class<? extends IPacket> clazz = typeClassMap.get(this.type); |
| try { |
| payload = clazz.newInstance(); |
| } catch (Exception e) { |
| throw new RuntimeException("Error parsing payload for BSN packet" + e); |
| } |
| } else { |
| payload = new Data(); |
| } |
| |
| this.payload = new Data(); |
| this.payload = payload.deserialize(data, bb.position(), bb.limit() - bb.position()); |
| this.payload.setParent(this); |
| |
| return this; |
| } |
| |
| /* (non-Javadoc) |
| * @see java.lang.Object#hashCode() |
| */ |
| @Override |
| public int hashCode() { |
| final int prime = 883; |
| int result = super.hashCode(); |
| result = prime * result + version; |
| result = prime * result + type; |
| return result; |
| } |
| |
| /* (non-Javadoc) |
| * @see java.lang.Object#equals(java.lang.Object) |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) |
| return true; |
| if (!super.equals(obj)) |
| return false; |
| if (!(obj instanceof BSN)) |
| return false; |
| BSN other = (BSN) obj; |
| return (type == other.type && |
| version == other.version); |
| } |
| |
| public String toString() { |
| StringBuffer sb = new StringBuffer("\n"); |
| sb.append("BSN packet"); |
| if (typeClassMap.containsKey(this.type)) |
| sb.append(" type: " + typeClassMap.get(this.type).getCanonicalName()); |
| else |
| sb.append(" type: " + this.type); |
| |
| return sb.toString(); |
| } |
| } |