| /** |
| * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior |
| * University |
| * |
| * 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 org.openflow.protocol; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.jboss.netty.buffer.ChannelBuffer; |
| import org.openflow.protocol.action.OFAction; |
| import org.openflow.protocol.factory.OFActionFactory; |
| import org.openflow.protocol.factory.OFActionFactoryAware; |
| import org.openflow.util.U16; |
| |
| /** |
| * Represents an ofp_packet_out message |
| * |
| * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 12, 2010 |
| */ |
| public class OFPacketOut extends OFMessage implements OFActionFactoryAware { |
| public static int MINIMUM_LENGTH = 16; |
| public static int BUFFER_ID_NONE = 0xffffffff; |
| |
| protected OFActionFactory actionFactory; |
| protected int bufferId; |
| protected short inPort; |
| protected short actionsLength; |
| protected List<OFAction> actions; |
| protected byte[] packetData; |
| |
| public OFPacketOut() { |
| super(); |
| this.type = OFType.PACKET_OUT; |
| this.length = U16.t(MINIMUM_LENGTH); |
| } |
| |
| /** |
| * Get buffer_id |
| * @return |
| */ |
| public int getBufferId() { |
| return this.bufferId; |
| } |
| |
| /** |
| * Set buffer_id |
| * @param bufferId |
| */ |
| public OFPacketOut setBufferId(int bufferId) { |
| this.bufferId = bufferId; |
| return this; |
| } |
| |
| /** |
| * Returns the packet data |
| * @return |
| */ |
| public byte[] getPacketData() { |
| return this.packetData; |
| } |
| |
| /** |
| * Sets the packet data |
| * @param packetData |
| */ |
| public OFPacketOut setPacketData(byte[] packetData) { |
| this.packetData = packetData; |
| return this; |
| } |
| |
| /** |
| * Get in_port |
| * @return |
| */ |
| public short getInPort() { |
| return this.inPort; |
| } |
| |
| /** |
| * Set in_port |
| * @param inPort |
| */ |
| public OFPacketOut setInPort(short inPort) { |
| this.inPort = inPort; |
| return this; |
| } |
| |
| /** |
| * Set in_port. Convenience method using OFPort enum. |
| * @param inPort |
| */ |
| public OFPacketOut setInPort(OFPort inPort) { |
| this.inPort = inPort.getValue(); |
| return this; |
| } |
| |
| /** |
| * Get actions_len |
| * @return |
| */ |
| public short getActionsLength() { |
| return this.actionsLength; |
| } |
| |
| /** |
| * Get actions_len, unsigned |
| * @return |
| */ |
| public int getActionsLengthU() { |
| return U16.f(this.actionsLength); |
| } |
| |
| /** |
| * Set actions_len |
| * @param actionsLength |
| */ |
| public OFPacketOut setActionsLength(short actionsLength) { |
| this.actionsLength = actionsLength; |
| return this; |
| } |
| |
| /** |
| * Returns the actions contained in this message |
| * @return a list of ordered OFAction objects |
| */ |
| public List<OFAction> getActions() { |
| return this.actions; |
| } |
| |
| /** |
| * Sets the list of actions on this message |
| * @param actions a list of ordered OFAction objects |
| */ |
| public OFPacketOut setActions(List<OFAction> actions) { |
| this.actions = actions; |
| return this; |
| } |
| |
| @Override |
| public void setActionFactory(OFActionFactory actionFactory) { |
| this.actionFactory = actionFactory; |
| } |
| |
| @Override |
| public void readFrom(ChannelBuffer data) { |
| super.readFrom(data); |
| this.bufferId = data.readInt(); |
| this.inPort = data.readShort(); |
| this.actionsLength = data.readShort(); |
| if ( this.actionFactory == null) |
| throw new RuntimeException("ActionFactory not set"); |
| this.actions = this.actionFactory.parseActions(data, getActionsLengthU()); |
| this.packetData = new byte[getLengthU() - MINIMUM_LENGTH - getActionsLengthU()]; |
| data.readBytes(this.packetData); |
| } |
| |
| @Override |
| public void writeTo(ChannelBuffer data) { |
| super.writeTo(data); |
| data.writeInt(bufferId); |
| data.writeShort(inPort); |
| data.writeShort(actionsLength); |
| for (OFAction action : actions) { |
| action.writeTo(data); |
| } |
| if (this.packetData != null) |
| data.writeBytes(this.packetData); |
| } |
| |
| @Override |
| public int hashCode() { |
| final int prime = 293; |
| int result = super.hashCode(); |
| result = prime * result + ((actions == null) ? 0 : actions.hashCode()); |
| result = prime * result + actionsLength; |
| result = prime * result + bufferId; |
| result = prime * result + inPort; |
| result = prime * result + Arrays.hashCode(packetData); |
| return result; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (!super.equals(obj)) { |
| return false; |
| } |
| if (!(obj instanceof OFPacketOut)) { |
| return false; |
| } |
| OFPacketOut other = (OFPacketOut) obj; |
| if (actions == null) { |
| if (other.actions != null) { |
| return false; |
| } |
| } else if (!actions.equals(other.actions)) { |
| return false; |
| } |
| if (actionsLength != other.actionsLength) { |
| return false; |
| } |
| if (bufferId != other.bufferId) { |
| return false; |
| } |
| if (inPort != other.inPort) { |
| return false; |
| } |
| if (!Arrays.equals(packetData, other.packetData)) { |
| return false; |
| } |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see java.lang.Object#toString() |
| */ |
| @Override |
| public String toString() { |
| return "OFPacketOut [actionFactory=" + actionFactory + ", actions=" |
| + actions + ", actionsLength=" + actionsLength + ", bufferId=0x" |
| + Integer.toHexString(bufferId) + ", inPort=" + inPort + ", packetData=" |
| + Arrays.toString(packetData) + "]"; |
| } |
| } |