7f946a687d9f1f066ea3c803538af70a54337e14
[openflowjava.git] / third-party / openflow-codec / src / main / java / org / openflow / codec / protocol / OFPPacketOut.java
1 package org.openflow.codec.protocol;
2
3 import java.util.Arrays;
4 import java.util.List;
5
6 import org.openflow.codec.io.IDataBuffer;
7 import org.openflow.codec.protocol.action.OFPAction;
8 import org.openflow.codec.protocol.factory.OFPActionFactory;
9 import org.openflow.codec.protocol.factory.OFPActionFactoryAware;
10 import org.openflow.codec.util.U16;
11
12 /**
13  * Represents an ofp_packet_out message
14  *
15  * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 12, 2010
16  */
17 public class OFPPacketOut extends OFPMessage implements OFPActionFactoryAware {
18     public static int MINIMUM_LENGTH = 24;
19     public static int BUFFER_ID_NONE = 0xffffffff;
20
21     protected OFPActionFactory actionFactory;
22     protected int bufferId;
23     protected int inPort;
24     protected short actionsLength;
25     protected List<OFPAction> actions;
26     protected byte[] packetData;
27
28     public OFPPacketOut() {
29         super();
30         this.type = OFPType.PACKET_OUT;
31         this.length = U16.t(MINIMUM_LENGTH);
32     }
33
34     /**
35      * Get buffer_id
36      *
37      * @return
38      */
39     public int getBufferId() {
40         return this.bufferId;
41     }
42
43     /**
44      * Set buffer_id
45      *
46      * @param bufferId
47      */
48     public OFPPacketOut setBufferId(int bufferId) {
49         this.bufferId = bufferId;
50         return this;
51     }
52
53     /**
54      * Returns the packet data
55      *
56      * @return
57      */
58     public byte[] getPacketData() {
59         return this.packetData;
60     }
61
62     /**
63      * Sets the packet data
64      *
65      * @param packetData
66      */
67     public OFPPacketOut setPacketData(byte[] packetData) {
68         this.packetData = packetData;
69         updateLength();
70         return this;
71     }
72
73     private void updateLength() {
74         short newLength = (short) ((packetData == null) ? 0 : packetData.length);
75         this.length = newLength;
76     }
77
78     /**
79      * Get in_port
80      *
81      * @return
82      */
83     public int getInPort() {
84         return this.inPort;
85     }
86
87     /**
88      * Set in_port
89      *
90      * @param inPort
91      */
92     public OFPPacketOut setInPort(int inPort) {
93         this.inPort = inPort;
94         return this;
95     }
96
97     /**
98      * Set in_port. Convenience method using OFPPort enum.
99      *
100      * @param inPort
101      */
102     public OFPPacketOut setInPort(OFPPortNo inPort) {
103         this.inPort = inPort.getValue();
104         return this;
105     }
106
107     /**
108      * Get actions_len
109      *
110      * @return
111      */
112     public short getActionsLength() {
113         return this.actionsLength;
114     }
115
116     /**
117      * Get actions_len, unsigned
118      *
119      * @return
120      */
121     public int getActionsLengthU() {
122         return U16.f(this.actionsLength);
123     }
124
125     /**
126      * Set actions_len
127      *
128      * @param actionsLength
129      */
130     public OFPPacketOut setActionsLength(short actionsLength) {
131         this.actionsLength = actionsLength;
132         return this;
133     }
134
135     /**
136      * Returns the actions contained in this message
137      *
138      * @return a list of ordered OFPAction objects
139      */
140     public List<OFPAction> getActions() {
141         return this.actions;
142     }
143
144     /**
145      * Sets the list of actions on this message
146      *
147      * @param actions
148      *            a list of ordered OFPAction objects
149      */
150     public OFPPacketOut setActions(List<OFPAction> actions) {
151         this.actions = actions;
152         return this;
153     }
154
155     @Override
156     public void setActionFactory(OFPActionFactory actionFactory) {
157         this.actionFactory = actionFactory;
158     }
159
160     @Override
161     public void readFrom(IDataBuffer data) {
162         super.readFrom(data);
163         this.bufferId = data.getInt();
164         this.inPort = data.getInt();
165         this.actionsLength = data.getShort();
166         data.getInt(); // pad
167         data.getShort(); // pad
168         if (this.actionFactory == null)
169             throw new RuntimeException("ActionFactory not set");
170         this.actions = this.actionFactory.parseActions(data, getActionsLengthU());
171         this.packetData = new byte[getLengthU() - MINIMUM_LENGTH - getActionsLengthU()];
172         data.get(this.packetData);
173     }
174
175     @Override
176     public void writeTo(IDataBuffer data) {
177         super.writeTo(data);
178         data.putInt(bufferId);
179         data.putInt(inPort);
180         data.putShort(actionsLength);
181         data.putInt(0); // pad
182         data.putShort((short) 0); // pad
183         for (OFPAction action : actions) {
184             action.writeTo(data);
185         }
186         if (this.packetData != null)
187             data.put(this.packetData);
188     }
189
190     @Override
191     public int hashCode() {
192         final int prime = 293;
193         int result = super.hashCode();
194         result = prime * result + ((actions == null) ? 0 : actions.hashCode());
195         result = prime * result + actionsLength;
196         result = prime * result + bufferId;
197         result = prime * result + inPort;
198         result = prime * result + Arrays.hashCode(packetData);
199         return result;
200     }
201
202     @Override
203     public boolean equals(Object obj) {
204         if (this == obj) {
205             return true;
206         }
207         if (!super.equals(obj)) {
208             return false;
209         }
210         if (!(obj instanceof OFPPacketOut)) {
211             return false;
212         }
213         OFPPacketOut other = (OFPPacketOut) obj;
214         if (actions == null) {
215             if (other.actions != null) {
216                 return false;
217             }
218         } else if (!actions.equals(other.actions)) {
219             return false;
220         }
221         if (actionsLength != other.actionsLength) {
222             return false;
223         }
224         if (bufferId != other.bufferId) {
225             return false;
226         }
227         if (inPort != other.inPort) {
228             return false;
229         }
230         if (!Arrays.equals(packetData, other.packetData)) {
231             return false;
232         }
233         return true;
234     }
235
236     /*
237      * (non-Javadoc)
238      *
239      * @see java.lang.Object#toString()
240      */
241     @Override
242     public String toString() {
243         return "OFPPacketOut [actionFactory=" + actionFactory + ", actions=" + actions + ", actionsLength="
244                 + actionsLength + ", bufferId=0x" + Integer.toHexString(bufferId) + ", inPort=" + inPort
245                 + ", packetData=" + Arrays.toString(packetData) + "]";
246     }
247 }