blob: 57b5dc1efe690532e373d7663cfd6bcb4b5dcff9 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
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
18package org.openflow.protocol.action;
19
20
21import org.jboss.netty.buffer.ChannelBuffer;
22import org.openflow.util.U16;
23
24/**
25 * The base class for all OpenFlow Actions.
26 *
27 * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
28 */
29public class OFAction implements Cloneable {
30 /**
31 * Note the true minimum length for this header is 8 including a pad to 64
32 * bit alignment, however as this base class is used for demuxing an
33 * incoming Action, it is only necessary to read the first 4 bytes. All
34 * Actions extending this class are responsible for reading/writing the
35 * first 8 bytes, including the pad if necessary.
36 */
37 public static int MINIMUM_LENGTH = 4;
38 public static int OFFSET_LENGTH = 2;
39 public static int OFFSET_TYPE = 0;
40
41 protected OFActionType type;
42 protected short length;
43
44 /**
45 * Get the length of this message
46 *
47 * @return
48 */
49 public short getLength() {
50 return length;
51 }
52
53 /**
54 * Get the length of this message, unsigned
55 *
56 * @return
57 */
58 public int getLengthU() {
59 return U16.f(length);
60 }
61
62 /**
63 * Set the length of this message
64 *
65 * @param length
66 */
67 public OFAction setLength(short length) {
68 this.length = length;
69 return this;
70 }
71
72 /**
73 * Get the type of this message
74 *
75 * @return OFActionType enum
76 */
77 public OFActionType getType() {
78 return this.type;
79 }
80
81 /**
82 * Set the type of this message
83 *
84 * @param type
85 */
86 public void setType(OFActionType type) {
87 this.type = type;
88 }
89
90 /**
91 * Returns a summary of the message
92 * @return "ofmsg=v=$version;t=$type:l=$len:xid=$xid"
93 */
94 public String toString() {
95 return "ofaction" +
96 ";t=" + this.getType() +
97 ";l=" + this.getLength();
98 }
99
100 /**
101 * Given the output from toString(),
102 * create a new OFAction
103 * @param val
104 * @return
105 */
106 public static OFAction fromString(String val) {
107 String tokens[] = val.split(";");
108 if (!tokens[0].equals("ofaction"))
109 throw new IllegalArgumentException("expected 'ofaction' but got '" +
110 tokens[0] + "'");
111 String type_tokens[] = tokens[1].split("=");
112 String len_tokens[] = tokens[2].split("=");
113 OFAction action = new OFAction();
114 action.setLength(Short.valueOf(len_tokens[1]));
115 action.setType(OFActionType.valueOf(type_tokens[1]));
116 return action;
117 }
118
119 public void readFrom(ChannelBuffer data) {
120 this.type = OFActionType.valueOf(data.readShort());
121 this.length = data.readShort();
122 // Note missing PAD, see MINIMUM_LENGTH comment for details
123 }
124
125 public void writeTo(ChannelBuffer data) {
126 data.writeShort(type.getTypeValue());
127 data.writeShort(length);
128 // Note missing PAD, see MINIMUM_LENGTH comment for details
129 }
130
131 @Override
132 public int hashCode() {
133 final int prime = 347;
134 int result = 1;
135 result = prime * result + length;
136 result = prime * result + ((type == null) ? 0 : type.hashCode());
137 return result;
138 }
139
140 @Override
141 public boolean equals(Object obj) {
142 if (this == obj) {
143 return true;
144 }
145 if (obj == null) {
146 return false;
147 }
148 if (!(obj instanceof OFAction)) {
149 return false;
150 }
151 OFAction other = (OFAction) obj;
152 if (length != other.length) {
153 return false;
154 }
155 if (type == null) {
156 if (other.type != null) {
157 return false;
158 }
159 } else if (!type.equals(other.type)) {
160 return false;
161 }
162 return true;
163 }
164
165 /* (non-Javadoc)
166 * @see java.lang.Object#clone()
167 */
168 @Override
169 public OFAction clone() throws CloneNotSupportedException {
170 return (OFAction) super.clone();
171 }
172
173}