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);
139 * Write this offending message into the payload of the Error message
141 * @param offendingMsg
144 public void setOffendingMsg(OFMessage offendingMsg) {
145 if (offendingMsg == null) {
146 super.setLengthU(MINIMUM_LENGTH);
148 this.error = new byte[offendingMsg.getLengthU()];
149 ByteBuffer data = ByteBuffer.wrap(this.error);
150 offendingMsg.writeTo(data);
151 super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
155 public OFMessageFactory getFactory() {
160 public void setMessageFactory(OFMessageFactory factory) {
161 this.factory = factory;
167 public byte[] getError() {
175 public void setError(byte[] error) {
180 * @return the errorIsAscii
182 public boolean isErrorIsAscii() {
187 * @param errorIsAscii
188 * the errorIsAscii to set
190 public void setErrorIsAscii(boolean errorIsAscii) {
191 this.errorIsAscii = errorIsAscii;
195 public void readFrom(ByteBuffer data) {
196 super.readFrom(data);
197 this.errorType = data.getShort();
198 this.errorCode = data.getShort();
199 int dataLength = this.getLengthU() - MINIMUM_LENGTH;
200 if (dataLength > 0) {
201 this.error = new byte[dataLength];
202 data.get(this.error);
203 if (this.errorType == OFErrorType.OFPET_HELLO_FAILED.ordinal())
204 this.errorIsAscii = true;
209 public void writeTo(ByteBuffer data) {
211 data.putShort(errorType);
212 data.putShort(errorCode);
220 * @see java.lang.Object#hashCode()
223 public int hashCode() {
224 final int prime = 31;
225 int result = super.hashCode();
226 result = prime * result + Arrays.hashCode(error);
227 result = prime * result + errorCode;
228 result = prime * result + (errorIsAscii ? 1231 : 1237);
229 result = prime * result + errorType;
236 * @see java.lang.Object#equals(java.lang.Object)
239 public boolean equals(Object obj) {
242 if (!super.equals(obj))
244 if (getClass() != obj.getClass())
246 OFError other = (OFError) obj;
247 if (!Arrays.equals(error, other.error))
249 if (errorCode != other.errorCode)
251 if (errorIsAscii != other.errorIsAscii)
253 if (errorType != other.errorType)