733: Insert the description of the change.Need to support Error Checking for consistency – if Meter Reference made then need Meter to exist first before reference.

If Flow Table ID does not resolve to a Technology Profile in KV Store generate an error – initial approach to simplify implementation - the Technology for the Profile will not be used to qualify the lookup.

Initially just do OF agent checks which do not need knowledge available in the adapter i.e. Meter Band Reference requires Meter Band definition first. Any Forward References need error checks (OF Error messages).

OF Agent needs to pass through the Meter/Meter Band programming and the Flow Table ID used to reference the Technology Profile.

The VOLTHA core needs to be able to receive meters from the OFAgent and store them in the appropriate logical device. A new northbound API needs to be added to the core to support this.

Change-Id: Ide776dbcbc04232c1d929a85707fec09e3dedf6f
diff --git a/ofagent/of_protocol_handler.py b/ofagent/of_protocol_handler.py
index 8d09461..984802e 100644
--- a/ofagent/of_protocol_handler.py
+++ b/ofagent/of_protocol_handler.py
@@ -128,6 +128,29 @@
         elif self.role == ofp.OFPCR_ROLE_SLAVE:
            self.cxn.send(ofp.message.bad_request_error_msg(code=ofp.OFPBRC_IS_SLAVE))
 
+
+    def handle_meter_mod_request(self, req):
+        if self.role == ofp.OFPCR_ROLE_MASTER or self.role == ofp.OFPCR_ROLE_EQUAL:
+            try:
+                grpc_req = to_grpc(req)
+            except Exception, e:
+                log.exception('failed-to-convert-meter-mod-request', e=e)
+            else:
+                return self.rpc.update_meter_mod_table(self.device_id, grpc_req)
+
+        elif self.role == ofp.OFPCR_ROLE_SLAVE:
+            self.cxn.send(ofp.message.bad_request_error_msg(code=ofp.OFPBRC_IS_SLAVE))
+
+    @inlineCallbacks
+    def handle_meter_stats_request(self, req):
+        try:
+            meter_stats = yield self.rpc.get_meter_stats(self.device_id)
+            meter_stats = [to_loxi(m) for m in meter_stats]
+            of_message = ofp.message.meter_stats_reply(xid=req.xid, entries=meter_stats)
+            self.cxn.send(of_message)
+        except Exception, e:
+            log.exception("failed-meter-stats-request", req=req, e=e)
+
     def handle_get_async_request(self, req):
         raise NotImplementedError()
 
@@ -144,10 +167,6 @@
         elif self.role == ofp.OFPCR_ROLE_SLAVE:
            self.cxn.send(ofp.message.bad_request_error_msg(code=ofp.OFPBRC_IS_SLAVE))
 
-
-    def handle_meter_mod_request(self, req):
-        raise NotImplementedError()
-
     def handle_role_request(self, req):
         if req.role == ofp.OFPCR_ROLE_MASTER or req.role == ofp.OFPCR_ROLE_SLAVE:
             if self.agent.generation_is_defined and (
@@ -238,11 +257,6 @@
     def handle_group_features_request(self, req):
         raise NotImplementedError()
 
-    def handle_meter_stats_request(self, req):
-        meter_stats = []  # see https://jira.opencord.org/browse/CORD-825
-        self.cxn.send(ofp.message.meter_stats_reply(
-            xid=req.xid, entries=meter_stats))
-
     def handle_meter_config_request(self, req):
         raise NotImplementedError()