Introduce driver property to suppress meter feature

Piggybacked in this commit:
- Fix CLI output of driver properties
- Fix mfr matching pattern in onos-drivers.xml
- Add driver support for Accton OFDPA 3

Change-Id: Ia350bd52f4e88e53565ff491d68bce5e4894bbb9
diff --git a/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java b/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java
index 9c4ccab..5f1a543 100644
--- a/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java
+++ b/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java
@@ -29,6 +29,8 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onosproject.core.CoreService;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
 import org.onosproject.net.meter.Band;
 import org.onosproject.net.meter.DefaultBand;
 import org.onosproject.net.meter.DefaultMeter;
@@ -87,7 +89,6 @@
 @Component(immediate = true, enabled = true)
 public class OpenFlowMeterProvider extends AbstractProvider implements MeterProvider {
 
-
     private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -99,6 +100,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
     private MeterProviderService providerService;
 
     private static final AtomicLong XID_COUNTER = new AtomicLong(1);
@@ -251,13 +255,25 @@
                 sw.factory().getVersion() == OFVersion.OF_11 ||
                 sw.factory().getVersion() == OFVersion.OF_12 ||
                 NO_METER_SUPPORT.contains(sw.deviceType()) ||
-                sw.softwareDescription().equals("OF-DPA 2.0")) {
+                !isMeterCapable(sw)) {
             return false;
         }
 
         return true;
     }
 
+    /**
+     * Determine whether the given switch is meter-capable.
+     *
+     * @param sw switch
+     * @return the boolean value of meterCapable property, or true if it is not configured.
+     */
+    private boolean isMeterCapable(OpenFlowSwitch sw) {
+        Driver driver = driverService.getDriver(DeviceId.deviceId(Dpid.uri(sw.getDpid())));
+        String isMeterCapable = driver.getProperty(METER_CAPABLE);
+        return isMeterCapable == null || Boolean.parseBoolean(isMeterCapable);
+    }
+
     private void pushMeterStats(Dpid dpid, OFStatsReply msg) {
         DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));