057461304c99c8fa19c5d28308620a7827428930
[openflowjava.git] / third-party / openflow-codec / src / main / java / org / openflow / codec / protocol / OFPPacketIn.java
1 package org.openflow.codec.protocol;
2
3 import java.util.Arrays;
4
5 import org.openflow.codec.io.IDataBuffer;
6 import org.openflow.codec.util.U16;
7 import org.openflow.codec.util.U8;
8
9 /**
10  * Represents an ofp_packet_in
11  *
12  * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 8, 2010
13  * @author AnilGujele
14  */
15 public class OFPPacketIn extends OFPMessage {
16     public static int MINIMUM_LENGTH = 32;
17     public static int MINIMUM_LENGTH_WITHOUT_MATCH = MINIMUM_LENGTH - 8;
18
19     public enum OFPacketInReason {
20         NO_MATCH, ACTION, INVALID_TTL
21     }
22
23     protected int bufferId;
24     protected short totalLength;
25     protected OFPacketInReason reason;
26     protected byte tableId;
27     protected long cookie;
28     protected OFPMatch match;
29     protected byte[] packetData;
30
31     public OFPPacketIn() {
32         super();
33         this.type = OFPType.PACKET_IN;
34         this.length = U16.t(MINIMUM_LENGTH);
35     }
36
37     /**
38      * Get buffer_id
39      *
40      * @return
41      */
42     public int getBufferId() {
43         return this.bufferId;
44     }
45
46     /**
47      * Set buffer_id
48      *
49      * @param bufferId
50      */
51     public OFPPacketIn setBufferId(int bufferId) {
52         this.bufferId = bufferId;
53         return this;
54     }
55
56     /**
57      * Returns the packet data
58      *
59      * @return
60      */
61     public byte[] getPacketData() {
62         return this.packetData;
63     }
64
65     /**
66      * Sets the packet data, and updates the length of this message
67      *
68      * @param packetData
69      */
70     public OFPPacketIn setPacketData(byte[] packetData) {
71         this.packetData = packetData;
72         updateLength();
73         return this;
74     }
75
76     private void updateLength() {
77         short matchLength = (null == match) ? 0 : match.getLengthWithPadding();
78         int packetDataLength = (null == packetData) ? 0 : packetData.length;
79         int len = OFPPacketIn.MINIMUM_LENGTH_WITHOUT_MATCH + matchLength + packetDataLength;
80         this.length = (short) len;
81     }
82
83     /**
84      * Get reason
85      *
86      * @return
87      */
88     public OFPacketInReason getReason() {
89         return this.reason;
90     }
91
92     /**
93      * Set reason
94      *
95      * @param reason
96      */
97     public OFPPacketIn setReason(OFPacketInReason reason) {
98         this.reason = reason;
99         return this;
100     }
101
102     /**
103      * get table id
104      *
105      * @return
106      */
107     public byte getTableId() {
108         return tableId;
109     }
110
111     /**
112      * set table id
113      *
114      * @param tableId
115      */
116     public void setTableId(byte tableId) {
117         this.tableId = tableId;
118     }
119
120     /**
121      * get cookie
122      *
123      * @return
124      */
125     public long getCookie() {
126         return cookie;
127     }
128
129     /**
130      * set cookie
131      *
132      * @param cookie
133      */
134     public void setCookie(long cookie) {
135         this.cookie = cookie;
136     }
137
138     /**
139      * get match
140      *
141      * @return
142      */
143     public OFPMatch getMatch() {
144         return match;
145     }
146
147     /**
148      * set match
149      *
150      * @param match
151      */
152     public void setMatch(OFPMatch match) {
153         this.match = match;
154         updateLength();
155     }
156
157     /**
158      * Get total_len
159      *
160      * @return
161      */
162     public short getTotalLength() {
163         return this.totalLength;
164     }
165
166     /**
167      * Set total_len
168      *
169      * @param totalLength
170      */
171     public OFPPacketIn setTotalLength(short totalLength) {
172         this.totalLength = totalLength;
173         return this;
174     }
175
176     @Override
177     public void readFrom(IDataBuffer data) {
178         super.readFrom(data);
179         this.bufferId = data.getInt();
180         this.totalLength = data.getShort();
181         this.reason = OFPacketInReason.values()[U8.f(data.get())];
182         this.tableId = data.get();
183         this.cookie = data.getLong();
184         this.match = new OFPMatch();
185         match.readFrom(data);
186         // TBD - how to handle the padding here
187         data.getShort(); // pad
188         this.packetData = new byte[getLengthU() - OFPPacketIn.MINIMUM_LENGTH_WITHOUT_MATCH
189                 - match.getLengthWithPadding()];
190         data.get(this.packetData);
191     }
192
193     @Override
194     public void writeTo(IDataBuffer data) {
195         super.writeTo(data);
196         data.putInt(bufferId);
197         data.putShort(totalLength);
198         data.put((byte) reason.ordinal());
199         data.put(tableId);
200         data.putLong(cookie);
201         if (null != match) {
202             match.writeTo(data);
203         }
204         data.putShort((short) 0); // pad
205         data.put(this.packetData);
206     }
207
208     @Override
209     public int hashCode() {
210         final int prime = 283;
211         int result = super.hashCode();
212         result = prime * result + bufferId;
213         result = prime * result + tableId;
214         result = prime * result + (int) (cookie ^ (cookie >>> 32));
215         result = prime * result + ((null == match) ? 0 : match.hashCode());
216         result = prime * result + Arrays.hashCode(packetData);
217         result = prime * result + ((reason == null) ? 0 : reason.hashCode());
218         result = prime * result + totalLength;
219         return result;
220     }
221
222     @Override
223     public boolean equals(Object obj) {
224         if (this == obj) {
225             return true;
226         }
227         if (!super.equals(obj)) {
228             return false;
229         }
230         if (!(obj instanceof OFPPacketIn)) {
231             return false;
232         }
233         OFPPacketIn other = (OFPPacketIn) obj;
234         if (bufferId != other.bufferId) {
235             return false;
236         }
237         if (tableId != other.tableId) {
238             return false;
239         }
240         if (match == null) {
241             if (other.match != null) {
242                 return false;
243             }
244         } else if (!match.equals(other.match)) {
245             return false;
246         }
247         if (!Arrays.equals(packetData, other.packetData)) {
248             return false;
249         }
250         if (reason == null) {
251             if (other.reason != null) {
252                 return false;
253             }
254         } else if (!reason.equals(other.reason)) {
255             return false;
256         }
257         if (totalLength != other.totalLength) {
258             return false;
259         }
260         return true;
261     }
262 }