1 package org.openflow.protocol;
3 import java.nio.ByteBuffer;
4 import java.util.Arrays;
7 import org.openflow.protocol.factory.OFMessageFactory;
8 import org.openflow.protocol.factory.OFMessageFactoryAware;
9 import org.openflow.util.U16;
12 * Represents an ofp_error_msg
14 * @author David Erickson (daviderickson@cs.stanford.edu)
15 * @author Rob Sherwood (rob.sherwood@stanford.edu)
17 public class OFError extends OFMessage implements OFMessageFactoryAware {
18 public static int MINIMUM_LENGTH = 12;
20 public enum OFErrorType {
21 OFPET_HELLO_FAILED, OFPET_BAD_REQUEST, OFPET_BAD_ACTION, OFPET_FLOW_MOD_FAILED, OFPET_PORT_MOD_FAILED, OFPET_QUEUE_OP_FAILED
24 public enum OFHelloFailedCode {
25 OFPHFC_INCOMPATIBLE, OFPHFC_EPERM
28 public enum OFBadRequestCode {
29 OFPBRC_BAD_VERSION, OFPBRC_BAD_TYPE, OFPBRC_BAD_STAT, OFPBRC_BAD_VENDOR, OFPBRC_BAD_SUBTYPE, OFPBRC_EPERM, OFPBRC_BAD_LEN, OFPBRC_BUFFER_EMPTY, OFPBRC_BUFFER_UNKNOWN
32 public enum OFBadActionCode {
33 OFPBAC_BAD_TYPE, OFPBAC_BAD_LEN, OFPBAC_BAD_VENDOR, OFPBAC_BAD_VENDOR_TYPE, OFPBAC_BAD_OUT_PORT, OFPBAC_BAD_ARGUMENT, OFPBAC_EPERM, OFPBAC_TOO_MANY, OFPBAC_BAD_QUEUE
36 public enum OFFlowModFailedCode {
37 OFPFMFC_ALL_TABLES_FULL, OFPFMFC_OVERLAP, OFPFMFC_EPERM, OFPFMFC_BAD_EMERG_TIMEOUT, OFPFMFC_BAD_COMMAND, OFPFMFC_UNSUPPORTED
40 public enum OFPortModFailedCode {
41 OFPPMFC_BAD_PORT, OFPPMFC_BAD_HW_ADDR
44 public enum OFQueueOpFailedCode {
45 OFPQOFC_BAD_PORT, OFPQOFC_BAD_QUEUE, OFPQOFC_EPERM
48 protected short errorType;
49 protected short errorCode;
50 protected OFMessageFactory factory;
51 protected byte[] error;
52 protected boolean errorIsAscii;
56 this.type = OFType.ERROR;
57 this.length = U16.t(MINIMUM_LENGTH);
61 * @return the errorType
63 public short getErrorType() {
69 * the errorType to set
71 public void setErrorType(short errorType) {
72 this.errorType = errorType;
75 public void setErrorType(OFErrorType type) {
76 this.errorType = (short) type.ordinal();
80 * @return the errorCode
82 public short getErrorCode() {
88 * the errorCode to set
90 public void setErrorCode(OFHelloFailedCode code) {
91 this.errorCode = (short) code.ordinal();
94 public void setErrorCode(short errorCode) {
95 this.errorCode = errorCode;
98 public void setErrorCode(OFBadRequestCode code) {
99 this.errorCode = (short) code.ordinal();
102 public void setErrorCode(OFBadActionCode code) {
103 this.errorCode = (short) code.ordinal();
106 public void setErrorCode(OFFlowModFailedCode code) {
107 this.errorCode = (short) code.ordinal();
110 public void setErrorCode(OFPortModFailedCode code) {
111 this.errorCode = (short) code.ordinal();
114 public void setErrorCode(OFQueueOpFailedCode code) {
115 this.errorCode = (short) code.ordinal();
118 public OFMessage getOffendingMsg() {
119 // should only have one message embedded; if more than one, just
121 if (this.error == null)
123 ByteBuffer errorMsg = ByteBuffer.wrap(this.error);
125 throw new RuntimeException("MessageFactory not set");
126 List<OFMessage> messages = this.factory.parseMessages(errorMsg,
128 // OVS apparently sends partial messages in errors
129 // need to be careful of that AND can't use data.limit() as
130 // a packet boundary because there could be more data queued
131 if (messages.size() > 0)
132 return messages.get(0);
138 * Write this offending message into the payload of the Error message
140 * @param offendingMsg
143 public void setOffendingMsg(OFMessage offendingMsg) {
144 if (offendingMsg == null) {
145 super.setLengthU(MINIMUM_LENGTH);
147 this.error = new byte[offendingMsg.getLengthU()];
148 ByteBuffer data = ByteBuffer.wrap(this.error);
149 offendingMsg.writeTo(data);
150 super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
154 public OFMessageFactory getFactory() {
159 public void setMessageFactory(OFMessageFactory factory) {
160 this.factory = factory;
166 public byte[] getError() {
174 public void setError(byte[] error) {
179 * @return the errorIsAscii
181 public boolean isErrorIsAscii() {
186 * @param errorIsAscii
187 * the errorIsAscii to set
189 public void setErrorIsAscii(boolean errorIsAscii) {
190 this.errorIsAscii = errorIsAscii;
194 public void readFrom(ByteBuffer data) {
195 super.readFrom(data);
196 this.errorType = data.getShort();
197 this.errorCode = data.getShort();
198 int dataLength = this.getLengthU() - MINIMUM_LENGTH;
199 if (dataLength > 0) {
200 this.error = new byte[dataLength];
201 data.get(this.error);
202 if (this.errorType == OFErrorType.OFPET_HELLO_FAILED.ordinal())
203 this.errorIsAscii = true;
208 public void writeTo(ByteBuffer data) {
210 data.putShort(errorType);
211 data.putShort(errorCode);
219 * @see java.lang.Object#hashCode()
222 public int hashCode() {
223 final int prime = 31;
224 int result = super.hashCode();
225 result = prime * result + Arrays.hashCode(error);
226 result = prime * result + errorCode;
227 result = prime * result + (errorIsAscii ? 1231 : 1237);
228 result = prime * result + errorType;
235 * @see java.lang.Object#equals(java.lang.Object)
238 public boolean equals(Object obj) {
241 if (!super.equals(obj))
243 if (getClass() != obj.getClass())
245 OFError other = (OFError) obj;
246 if (!Arrays.equals(error, other.error))
248 if (errorCode != other.errorCode)
250 if (errorIsAscii != other.errorIsAscii)
252 if (errorType != other.errorType)