767b7d183d120b15397751ed9a4032d0aad3e8ed
[controller.git] / third-party / openflowj_netty / src / main / java / org / openflow / protocol / OFMessage.java
1 /**
2 *    Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
3 *    University
4
5 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
6 *    not use this file except in compliance with the License. You may obtain
7 *    a copy of the License at
8 *
9 *         http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *    Unless required by applicable law or agreed to in writing, software
12 *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 *    License for the specific language governing permissions and limitations
15 *    under the License.
16 **/
17
18 package org.openflow.protocol;
19
20 import java.text.DateFormat;
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.concurrent.ConcurrentHashMap;
24
25
26 import org.jboss.netty.buffer.ChannelBuffer;
27 import org.openflow.util.HexString;
28 import org.openflow.util.U16;
29 import org.openflow.util.U32;
30 import org.openflow.util.U8;
31
32 /**
33  * The base class for all OpenFlow protocol messages. This class contains the
34  * equivalent of the ofp_header which is present in all OpenFlow messages.
35  *
36  * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 3, 2010
37  * @author Rob Sherwood (rob.sherwood@stanford.edu) - Feb 3, 2010
38  */
39 public class OFMessage {
40     public static final int MAXIMUM_LENGTH = (1 << 16) - 1;
41     public static byte OFP_VERSION = 0x01;
42     public static int MINIMUM_LENGTH = 8;
43
44     protected byte version;
45     protected OFType type;
46     protected short length;
47     protected int xid;
48
49     private ConcurrentHashMap<String, Object> storage;
50
51     public OFMessage() {
52         storage = null;
53         this.version = OFP_VERSION;
54     }
55
56     protected synchronized ConcurrentHashMap<String, Object> getMessageStore() {
57         if (storage == null) {
58             storage = new ConcurrentHashMap<String, Object>();;
59         }
60         return storage;
61     }
62
63     /**
64      * Get the length of this message
65      *
66      * @return
67      */
68     public short getLength() {
69         return length;
70     }
71
72     /**
73      * Get the length of this message, unsigned
74      *
75      * @return
76      */
77     public int getLengthU() {
78         return U16.f(length);
79     }
80
81     /**
82      * Set the length of this message
83      *
84      * @param length
85      */
86     public OFMessage setLength(short length) {
87         this.length = length;
88         return this;
89     }
90
91     /**
92      * Set the length of this message, unsigned
93      *
94      * @param length
95      */
96     public OFMessage setLengthU(int length) {
97         this.length = U16.t(length);
98         return this;
99     }
100
101     /**
102      * Get the type of this message
103      *
104      * @return
105      */
106     public OFType getType() {
107         return type;
108     }
109
110     /**
111      * Set the type of this message
112      *
113      * @param type
114      */
115     public void setType(OFType type) {
116         this.type = type;
117     }
118
119     /**
120      * Get the OpenFlow version of this message
121      *
122      * @return
123      */
124     public byte getVersion() {
125         return version;
126     }
127
128     /**
129      * Set the OpenFlow version of this message
130      *
131      * @param version
132      */
133     public void setVersion(byte version) {
134         this.version = version;
135     }
136
137     /**
138      * Get the transaction id of this message
139      *
140      * @return
141      */
142     public int getXid() {
143         return xid;
144     }
145
146     /**
147      * Set the transaction id of this message
148      *
149      * @param xid
150      */
151     public void setXid(int xid) {
152         this.xid = xid;
153     }
154
155     /**
156      * Read this message off the wire from the specified ByteBuffer
157      * @param data
158      */
159     public void readFrom(ChannelBuffer data) {
160         this.version = data.readByte();
161         this.type = OFType.valueOf(data.readByte());
162         this.length = data.readShort();
163         this.xid = data.readInt();
164     }
165
166     /**
167      * Write this message's binary format to the specified ByteBuffer
168      * @param data
169      */
170     public void writeTo(ChannelBuffer data) {
171         data.writeByte(version);
172         data.writeByte(type.getTypeValue());
173         data.writeShort(length);
174         data.writeInt(xid);
175     }
176
177     /**
178      * Returns a summary of the message
179      * @return "ofmsg=v=$version;t=$type:l=$len:xid=$xid"
180      */
181     @Override
182     public String toString() {
183         return "ofmsg" +
184             ":v=" + U8.f(this.getVersion()) +
185             ";t=" + this.getType() +
186             ";l=" + this.getLengthU() +
187             ";x=" + U32.f(this.getXid());
188     }
189
190     @Override
191     public int hashCode() {
192         final int prime = 97;
193         int result = 1;
194         result = prime * result + length;
195         result = prime * result + ((type == null) ? 0 : type.hashCode());
196         result = prime * result + version;
197         result = prime * result + xid;
198         return result;
199     }
200
201     @Override
202     public boolean equals(Object obj) {
203         if (this == obj) {
204             return true;
205         }
206         if (obj == null) {
207             return false;
208         }
209         if (!(obj instanceof OFMessage)) {
210             return false;
211         }
212         OFMessage other = (OFMessage) obj;
213         if (length != other.length) {
214             return false;
215         }
216         if (type == null) {
217             if (other.type != null) {
218                 return false;
219             }
220         } else if (!type.equals(other.type)) {
221             return false;
222         }
223         if (version != other.version) {
224             return false;
225         }
226         if (xid != other.xid) {
227             return false;
228         }
229         return true;
230     }
231
232     /*
233     public static String getDataAsString(IOFSwitch sw, OFMessage msg) {
234
235         
236         Ethernet eth;
237         StringBuffer sb =  new StringBuffer("");
238
239         DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
240         Date date = new Date();
241
242         sb.append(dateFormat.format(date));
243         sb.append("      ");
244
245         switch (msg.getType()) {
246             case PACKET_IN:
247                 OFPacketIn pktIn = (OFPacketIn) msg;
248                 sb.append("packet_in          [ ");
249                 sb.append(sw.getStringId());
250                 sb.append(" -> Controller");
251                 sb.append(" ]");
252
253                 sb.append("\ntotal length: ");
254                 sb.append(pktIn.getTotalLength());
255                 sb.append("\nin_port: ");
256                 sb.append(pktIn.getInPort());
257                 sb.append("\ndata_length: ");
258                 sb.append(pktIn.getTotalLength() - OFPacketIn.MINIMUM_LENGTH);
259                 sb.append("\nbuffer: ");
260                 sb.append(pktIn.getBufferId());
261
262                 break;
263
264             case PACKET_OUT:
265                 OFPacketOut pktOut = (OFPacketOut) msg;
266                 sb.append("packet_out         [ ");
267                 sb.append("Controller -> ");
268                 sb.append(HexString.toHexString(sw.getId()));
269                 sb.append(" ]");
270
271                 sb.append("\nin_port: ");
272                 sb.append(pktOut.getInPort());
273                 sb.append("\nactions_len: ");
274                 sb.append(pktOut.getActionsLength());
275                 if (pktOut.getActions() != null) {
276                     sb.append("\nactions: ");
277                     sb.append(pktOut.getActions().toString());
278                 }
279                 break;
280
281             case FLOW_MOD:
282                 OFFlowMod fm = (OFFlowMod) msg;
283                 sb.append("flow_mod           [ ");
284                 sb.append("Controller -> ");
285                 sb.append(HexString.toHexString(sw.getId()));
286                 sb.append(" ]");
287
288
289                 sb.append("\nADD: cookie: ");
290                 sb.append(fm.getCookie());
291                 sb.append(" idle: ");
292                 sb.append(fm.getIdleTimeout());
293                 sb.append(" hard: ");
294                 sb.append(fm.getHardTimeout());
295                 sb.append(" pri: ");
296                 sb.append(fm.getPriority());
297                 sb.append(" buf: ");
298                 sb.append(fm.getBufferId());
299                 sb.append(" flg: ");
300                 sb.append(fm.getFlags());
301                 if (fm.getActions() != null) {
302                     sb.append("\nactions: ");
303                     sb.append(fm.getActions().toString());
304                 }
305                 break;
306
307             default:
308                 sb.append("[Unknown Packet]");
309         }
310
311         sb.append("\n\n");
312         return sb.toString();
313
314     }
315     */
316
317     
318     // Check if this is really required
319     /*
320     public static byte[] getData(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
321         return OFMessage.getDataAsString(sw, msg, cntx).getBytes();
322     }
323     */
324 }