Add power support to the Polatis SNMP driver
Change-Id: I8f80f66df39120d6cd6319f65d4b7528ab03cf2e
diff --git a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisDeviceDescription.java b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisDeviceDescription.java
index 8d7ec4e..82cbb74 100644
--- a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisDeviceDescription.java
+++ b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisDeviceDescription.java
@@ -46,7 +46,7 @@
import static org.slf4j.LoggerFactory.getLogger;
import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
-import static org.onosproject.drivers.polatis.snmp.PolatisSnmpUtility.getOid;
+import static org.onosproject.drivers.polatis.snmp.PolatisSnmpUtility.get;
import static org.onosproject.drivers.polatis.snmp.PolatisSnmpUtility.getTable;
/**
@@ -174,14 +174,14 @@
}
private String hardwareVersion() throws IOException {
- return getOid(handler(), PRODUCT_CODE_OID);
+ return get(handler(), PRODUCT_CODE_OID).toString();
}
private String softwareVersion() throws IOException {
- return getOid(handler(), SOFTWARE_VERSION_OID);
+ return get(handler(), SOFTWARE_VERSION_OID).toString();
}
private String serialNumber() throws IOException {
- return getOid(handler(), SERIAL_NUMBER_OID);
+ return get(handler(), SERIAL_NUMBER_OID).toString();
}
}
diff --git a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisOpticalUtility.java b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisOpticalUtility.java
index bfc0c3e..cffb7f8 100644
--- a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisOpticalUtility.java
+++ b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisOpticalUtility.java
@@ -48,8 +48,6 @@
private static final int DEFAULT_PRIORITY = 88;
private static final String DEFAULT_APP = "org.onosproject.drivers.polatis.snmp";
- public static final int POWER_MULTIPLIER = 100;
- public static final int VOA_MULTIPLIER = 100;
public static final Range<Long> POWER_RANGE = Range.closed(-6000L, 2800L);
private static final String PORT_ENTRY_OID = ".1.3.6.1.4.1.26592.2.2.2.1.2";
diff --git a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisPowerConfig.java b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisPowerConfig.java
new file mode 100644
index 0000000..4de4a88
--- /dev/null
+++ b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisPowerConfig.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2018 Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.polatis.snmp;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Direction;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.PowerConfig;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.UnsignedInteger32;
+import org.snmp4j.smi.Variable;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.TableEvent;
+
+import com.google.common.collect.Range;
+
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static org.onosproject.drivers.polatis.snmp.PolatisOpticalUtility.POWER_RANGE;
+import static org.onosproject.drivers.polatis.snmp.PolatisSnmpUtility.get;
+import static org.onosproject.drivers.polatis.snmp.PolatisSnmpUtility.getTable;
+import static org.onosproject.drivers.polatis.snmp.PolatisSnmpUtility.set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Get current or target port/channel power from a Polatis optical snmp device.
+ * Set target port power or channel attenuation to an optical snmp device.
+ */
+public class PolatisPowerConfig<T> extends AbstractHandlerBehaviour
+ implements PowerConfig<T> {
+
+ private static final int VOA_STATE_ABSOLUTE = 2;
+
+ private static final String OPM_TABLE_OID = ".1.3.6.1.4.1.26592.2.3.2.2.2";
+ private static final String OPM_POWER_OID = "1.1";
+
+ private static final String VOA_TABLE_OID = ".1.3.6.1.4.1.26592.2.4.2.1.2";
+ private static final String VOA_LEVEL_OID = VOA_TABLE_OID + ".1.1";
+ private static final String VOA_STATE_OID = VOA_TABLE_OID + ".1.4";
+
+ private final Logger log = getLogger(getClass());
+
+ @Override
+ public Optional<Long> getTargetPower(PortNumber port, T component) {
+ return Optional.ofNullable(acquireTargetPower(port, component));
+ }
+
+ @Override
+ public void setTargetPower(PortNumber port, T component, long power) {
+ if (component instanceof OchSignal) {
+ log.warn("Channel power is not applicable.");
+ return;
+ }
+ setPortTargetPower(port, power);
+ }
+
+ @Override
+ public Optional<Long> currentPower(PortNumber port, T component) {
+ return Optional.ofNullable(acquireCurrentPower(port, component));
+ }
+
+ @Override
+ public Optional<Range<Long>> getTargetPowerRange(PortNumber port, T component) {
+ return Optional.ofNullable(getTxPowerRange(port, component));
+ }
+
+ @Override
+ public Optional<Range<Long>> getInputPowerRange(PortNumber port, T component) {
+ return Optional.ofNullable(getRxPowerRange(port, component));
+ }
+
+ @Override
+ public List<PortNumber> getPorts(T component) {
+ if (component instanceof OchSignal) {
+ log.warn("Channel component is not applicable.");
+ return new ArrayList<PortNumber>();
+ }
+ log.debug("Get port config ports...");
+ return acquirePorts();
+ }
+
+ private List<PortNumber> acquirePorts() {
+ List<TableEvent> events;
+ DeviceId deviceId = handler().data().deviceId();
+ List<PortNumber> ports = new ArrayList<>();
+
+ try {
+ OID[] columnOIDs = {new OID(OPM_POWER_OID)};
+ events = getTable(handler(), columnOIDs);
+ } catch (IOException e) {
+ log.error("Error reading opm power table for device {} exception {}", deviceId, e);
+ return ports;
+ }
+
+ if (events == null) {
+ log.error("Error reading opm power table for device {}", deviceId);
+ return ports;
+ }
+
+ for (TableEvent event : events) {
+ if (event == null) {
+ log.error("Error reading event for device {}", deviceId);
+ continue;
+ }
+ VariableBinding[] columns = event.getColumns();
+ if (columns == null) {
+ log.error("Error reading columns for device {}", deviceId);
+ continue;
+ }
+
+ VariableBinding opmColumn = columns[0];
+ if (opmColumn == null) {
+ continue;
+ }
+
+ int port = event.getIndex().last();
+ int opm = opmColumn.getVariable().toInt();
+ if (opm == 0) {
+ continue;
+ }
+
+ ports.add(PortNumber.portNumber(port));
+ }
+
+ return ports;
+ }
+
+ private Long acquireTargetPower(PortNumber port, T component) {
+ if (component instanceof OchSignal) {
+ log.warn("Channel power is not applicable.");
+ return null;
+ }
+ log.debug("Get port{} target power...", port);
+
+ DeviceId deviceId = handler().data().deviceId();
+ Long targetPower = 0L;
+ try {
+ targetPower = Long.valueOf(get(handler(), VOA_LEVEL_OID + "." + port.toLong()).toInt());
+ } catch (IOException e) {
+ log.error("Error reading target power for device {} exception {}", deviceId, e);
+ }
+ return targetPower;
+ }
+
+ private Long acquireCurrentPower(PortNumber port, T component) {
+ if (component instanceof OchSignal) {
+ log.warn("Channel power is not applicable.");
+ return null;
+ }
+ log.debug("Get port{} current power...", port);
+
+ DeviceId deviceId = handler().data().deviceId();
+ Long power = 0L;
+ try {
+ power = Long.valueOf(get(handler(), OPM_POWER_OID + "." + port.toLong()).toInt());
+ } catch (IOException e) {
+ log.error("Error reading current power for device {} exception {}", deviceId, e);
+ }
+ return power;
+ }
+
+ private boolean setPortTargetPower(PortNumber port, long power) {
+ log.debug("Set port{} target power...", port);
+ List<VariableBinding> vbs = new ArrayList<>();
+
+ OID voaStateOid = new OID(VOA_STATE_OID + "." + port.toLong());
+ Variable voaStateVar = new UnsignedInteger32(VOA_STATE_ABSOLUTE);
+ VariableBinding voaStateVb = new VariableBinding(voaStateOid, voaStateVar);
+ vbs.add(voaStateVb);
+
+ OID voaLevelOid = new OID(VOA_LEVEL_OID + "." + port.toLong());
+ Variable voaLevelVar = new UnsignedInteger32(power);
+ VariableBinding voaLevelVb = new VariableBinding(voaLevelOid, voaLevelVar);
+ vbs.add(voaLevelVb);
+
+ DeviceId deviceId = handler().data().deviceId();
+ try {
+ set(handler(), vbs);
+ } catch (IOException e) {
+ log.error("Error writing ports table for device {} exception {}", deviceId, e);
+ return false;
+ }
+ return true;
+ }
+
+ private Range<Long> getPowerRange() {
+ return POWER_RANGE;
+ }
+
+ private Range<Long> getTxPowerRange(PortNumber port, T component) {
+ if (component instanceof Direction) {
+ log.debug("Get target port{} power range...", port);
+ return getPowerRange();
+ } else {
+ log.warn("Channel power is not applicable.");
+ return null;
+ }
+ }
+
+ private Range<Long> getRxPowerRange(PortNumber port, T component) {
+ log.debug("Get input port{} power range...", port);
+ return getPowerRange();
+ }
+}
diff --git a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisSnmpUtility.java b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisSnmpUtility.java
index 50bc254..4102a07 100644
--- a/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisSnmpUtility.java
+++ b/drivers/polatis/snmp/src/main/java/org/onosproject/drivers/polatis/snmp/PolatisSnmpUtility.java
@@ -28,6 +28,7 @@
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.OID;
+import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TableEvent;
@@ -99,17 +100,17 @@
*
* @param handler parent driver handler
* @param oid object identifier
- * @return the string value
+ * @return the variable
* @throws IOException if unable to retrieve the object value
*/
- public static String getOid(DriverHandler handler, String oid) throws IOException {
+ public static Variable get(DriverHandler handler, String oid) throws IOException {
List<VariableBinding> vbs = new ArrayList<>();
vbs.add(new VariableBinding(new OID(oid)));
PDU pdu = new PDU(PDU.GET, vbs);
Snmp session = getSession(handler);
CommunityTarget target = getTarget(handler);
ResponseEvent event = session.send(pdu, target);
- return event.getResponse().get(0).getVariable().toString();
+ return event.getResponse().get(0).getVariable();
}
/**
diff --git a/drivers/polatis/snmp/src/main/resources/polatis-snmp-drivers.xml b/drivers/polatis/snmp/src/main/resources/polatis-snmp-drivers.xml
index cf089f3..276c15c 100644
--- a/drivers/polatis/snmp/src/main/resources/polatis-snmp-drivers.xml
+++ b/drivers/polatis/snmp/src/main/resources/polatis-snmp-drivers.xml
@@ -23,6 +23,8 @@
impl="org.onosproject.drivers.polatis.snmp.PolatisDeviceDescription"/>
<behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
impl="org.onosproject.drivers.polatis.snmp.PolatisFlowRuleProgrammable"/>
+ <behaviour api="org.onosproject.net.behaviour.PowerConfig"
+ impl="org.onosproject.drivers.polatis.snmp.PolatisPowerConfig"/>
<property name="uiType">policon</property>
</driver>
</drivers>