Repository: kytos/python-openflow

Issue:
OF 1.3 Compliance: Missing class ofp_meter_features
Class `ofp_meter_features` is missing.
Page 74 of 1.3 Spec.
```
struct ofp_meter_features {
    uint32_t    max_meter;    
    uint32_t    band_types;   
    uint32_t    capabilities; 
    uint8_t     max_bands;    
    uint8_t     max_color;    
    uint8_t     pad[2];
};
OFP_ASSERT(sizeof(struct ofp_meter_features) == 16);
```

Comments:

Patch:
diff --git a/pyof/v0x04/controller2switch/common.py b/pyof/v0x04/controller2switch/common.py
index 048d5f2..eb546cb 100644
--- a/pyof/v0x04/controller2switch/common.py
+++ b/pyof/v0x04/controller2switch/common.py
@@ -8,6 +8,7 @@ from pyof.foundation.base import GenericBitMask, GenericMessage, GenericStruct
 from pyof.foundation.basic_types import (Char, FixedTypeList, Pad, UBInt8,
                                          UBInt16, UBInt32, UBInt64)
 from pyof.foundation.constants import DESC_STR_LEN, SERIAL_NUM_LEN
+from pyof.v0x04.controller2switch.meter_mod import MeterBandType, MeterFlags
 from pyof.v0x04.asynchronous.flow_removed import FlowRemovedReason
 from pyof.v0x04.asynchronous.packet_in import PacketInReason
 from pyof.v0x04.asynchronous.port_status import PortReason
@@ -26,8 +27,8 @@ __all__ = ('AggregateStatsReply', 'AggregateStatsRequest', 'Bucket',
            'GroupDescStats', 'GroupFeatures', 'GroupStats',
            'GroupStatsRequest', 'ListOfActions', 'MultipartTypes', 'PortStats',
            'PortStatsRequest', 'QueueStats', 'QueueStatsRequest', 'StatsTypes',
-           'TableStats', 'MeterMultipartRequest', 'MeterConfig')
-
+           'TableStats', 'MeterMultipartRequest', 'MeterConfig',
+           'MeterFeatures')
 
 # Enums
 
@@ -947,3 +948,31 @@ class MeterConfig(GenericStruct):
         length.unpack(buff,offset)
 
         super().unpack(buff[:offset+length.value],offset)
+
+
+class MeterFeatures(GenericStruct):
+    """Body of reply to OFPMP_METER_FEATURES request. Meter features."""
+
+    max_meter = UBInt32()
+    band_types = UBInt32(enum_ref=MeterBandType)
+    capabilities = UBInt32(enum_ref=MeterFlags)
+    max_bands = UBInt8()
+    max_color = UBInt8()
+    pad = Pad(2)
+
+    def __init__(self, max_meter=None, band_types=None, capabilities=None,
+                 max_bands=None, max_color=None):
+         """The Constructor of MeterFeatures receives the parameters below.
+
+         Args:
+             max_meter(int):           Maximum number of meters.
+             band_types(Meter):        Bitmaps of OFPMBT_* values supported.
+             capabilities(MeterFlags): Bitmaps of "ofp_meter_flags".
+             max_bands(int):           Maximum bands per meters
+             max_color(int):           Maximum color value
+         """
+         self.max_meter = max_meter
+         self.band_types = band_types
+         self.capabilities = capabilities
+         self.max_bands = max_bands
+         self.max_color = max_color


Test patch:
diff --git a/tests/v0x04/test_controller2switch/test_meter_features.py b/tests/v0x04/test_controller2switch/test_meter_features.py
new file mode 100644
index 0000000..db5a08b
--- /dev/null
+++ b/tests/v0x04/test_controller2switch/test_meter_features.py
@@ -0,0 +1,28 @@
+"""Test of v0x04 meter features module."""
+
+from pyof.v0x04.controller2switch.common import MeterFeatures, MultipartTypes
+from pyof.v0x04.controller2switch.meter_mod import MeterBandType, MeterFlags
+from pyof.v0x04.controller2switch.multipart_reply import (MultipartReply,
+                                                          MultipartReplyFlags)
+
+from tests.v0x04.test_struct import TestStruct
+
+class TestMeterFeatures(TestStruct):
+    """Class to test MeterFeatures structures."""
+
+    @classmethod
+    def setUpClass(cls):
+        """Configure raw file and its object in parent class (TestDump)."""
+        super().setUpClass()
+        super().set_message(MultipartReply, xid=17,
+                            multipart_type=MultipartTypes.OFPMP_METER_FEATURES,
+                            flags=MultipartReplyFlags.OFPMPF_REPLY_MORE,
+                            body=cls.meter_feature_instance())
+        super().set_minimum_size(16)
+
+    @classmethod
+    def meter_feature_instance(cls):
+        """Method used to create a MeterFeature instance."""
+        return MeterFeatures(max_meter=200,max_bands=20, max_color=4,
+                             band_types=MeterBandType.OFPMBT_DROP,
+                             capabilities=MeterFlags.OFPMF_KBPS)