import OpenFlow 1.2 protocol module and basic test cases from CPqD/oftest12

For now these tests will live in a separate directory. The goal is to merge
them where possible but this has to wait for an OpenFlow protocol module that
supports all versions of OpenFlow.
diff --git a/src/python/of12/error.py b/src/python/of12/error.py
new file mode 100644
index 0000000..0a1244a
--- /dev/null
+++ b/src/python/of12/error.py
@@ -0,0 +1,556 @@
+
+# Python OpenFlow error wrapper classes
+
+from cstruct import *
+
+
+
+class hello_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for hello_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_HELLO_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "hello_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class bad_request_error_msg(ofp_error_msg):
+    """
+    Wrapper class for bad_request error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_BAD_REQUEST
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "bad_request_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class bad_action_error_msg(ofp_error_msg):
+    """
+    Wrapper class for bad_action error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_BAD_ACTION
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "bad_action_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class bad_instruction_error_msg(ofp_error_msg):
+    """
+    Wrapper class for bad_instruction error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_BAD_INSTRUCTION
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "bad_instruction_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class bad_match_error_msg(ofp_error_msg):
+    """
+    Wrapper class for bad_match error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_BAD_MATCH
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "bad_match_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class flow_mod_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for flow_mod_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_FLOW_MOD_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "flow_mod_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class group_mod_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for group_mod_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_GROUP_MOD_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "group_mod_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class port_mod_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for port_mod_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_PORT_MOD_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "port_mod_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class table_mod_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for table_mod_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_TABLE_MOD_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "table_mod_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class queue_op_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for queue_op_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_QUEUE_OP_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "queue_op_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+
+
+class switch_config_failed_error_msg(ofp_error_msg):
+    """
+    Wrapper class for switch_config_failed error message class
+
+    Data members inherited from ofp_error_msg:
+    @arg type
+    @arg code
+    @arg data: Binary string following message members
+    
+    """
+    def __init__(self):
+        ofp_error_msg.__init__(self)
+        self.header = ofp_header()
+        self.header.type = OFPT_ERROR
+        self.type = OFPET_SWITCH_CONFIG_FAILED
+        self.data = ""
+
+    def pack(self, assertstruct=True):
+        self.header.length = self.__len__()
+        packed = self.header.pack()
+        packed += ofp_error_msg.pack(self)
+        packed += self.data
+        return packed
+
+    def unpack(self, binary_string):
+        binary_string = self.header.unpack(binary_string)
+        binary_string = ofp_error_msg.unpack(self, binary_string)
+        self.data = binary_string
+        return ""
+
+    def __len__(self):
+        return OFP_HEADER_BYTES + OFP_ERROR_MSG_BYTES + len(self.data)
+
+    def show(self, prefix=''):
+        outstr = prefix + "switch_config_failed_error_msg\m"
+        outstr += self.header.show(prefix + '  ')
+        outstr += ofp_error_msg.show(self, prefix + '  ')
+        outstr += prefix + "data is of length " + str(len(self.data)) + '\n'
+        ##@todo Consider trying to parse the string
+        return outstr
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return (self.header == other.header and
+                ofp_error_msg.__eq__(self, other) and
+                self.data == other.data)
+
+    def __ne__(self, other): return not self.__eq__(other)
+