Flow decomposer support for Tech Profile Reference in metadata instead of using Flow Table ID as reference in Table 1.

Also in this patch:
 - Update flow count field of meter stats
 - ONU root field was True and because of this flow decomposer was not working properly - it is fixed (now onu root field is false) - related to VOL-1354
 - Meter & write metadata support is added to vcli
 - No-action (drop) flow support is added.
 - Removed broken wildcard inport support and in-band control support
 - Meter functions (meter stats reply, meter modify etc.) are fixed
 - Metadata information  passed on to the OLT and ONU Adapters.
 - Meter Reference in all Flow Tables passed on to the OLT and ONU Adapters.
 - Fixed unit tests and added more unit tests
 - Fixed ponsim (partially) to deal with changes to flow decomposer

Change-Id: Id4b16fc05a6740a3f521b2cc4f6fdbff88da4fa5
diff --git a/cli/utils.py b/cli/utils.py
index 544c764..82d6a12 100644
--- a/cli/utils.py
+++ b/cli/utils.py
@@ -132,8 +132,6 @@
         for field in flow['match']['oxm_fields']:
             assert field['oxm_class'].endswith('OPENFLOW_BASIC')
             ofb = field['ofb_field']
-            # see CORD-816 (https://jira.opencord.org/browse/CORD-816)
-            assert not ofb['has_mask'], 'masked match not handled yet'
             type = ofb['type'][len('OFPXMT_OFB_'):]
             table.add_cell(i, *field_printers[type](ofb))
 
@@ -146,8 +144,14 @@
             elif itype == 1:
                 table.add_cell(i, 10000, 'goto-table',
                                instruction['goto_table']['table_id'])
+            elif itype == 2:
+                table.add_cell(i, 10001, 'write-metadata',
+                               instruction['write_metadata']['metadata'])
             elif itype == 5:
-                table.add_cell(i, 10000, 'clear-actions', [])
+                table.add_cell(i, 10002, 'clear-actions', [])
+            elif itype == 6:
+                table.add_cell(i, 10003, 'meter',
+                               instruction['meter']['meter_id'])
             else:
                 raise NotImplementedError(
                     'not handling instruction type {}'.format(itype))
@@ -176,6 +180,26 @@
 
     table.print_table(header, printfn)
 
+
+def print_meters(what, id, type, meters, printfn=_printfn):
+    header = ''.join([
+        '{} '.format(what),
+        colored(id, color='green', attrs=['bold']),
+        ' (type: ',
+        colored(type, color='blue'),
+        ')'
+    ]) + '\nMeters ({}):'.format(len(meters))
+
+    table = TablePrinter()
+    for i, meter in enumerate(meters):
+        bands = []
+        for meter_band in meter['config']['bands']:
+            bands.append(meter_band)
+        table.add_cell(i, 0, 'meter_id', value=str(meter['config']['meter_id']))
+        table.add_cell(i, 1, 'meter_bands', value=str(dict(bands=bands)))
+
+    table.print_table(header, printfn)
+
 def dict2line(d):
     assert isinstance(d, dict)
     return ', '.join('{}: {}'.format(k, v) for k, v in sorted(d.items()))