blob: de87becd432c7ff403049ea8a6476e0300a74c7e [file] [log] [blame]
/*
* Copyright 2022-present 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.
*
* This work was partially supported by EC H2020 project B5G-OPEN (101016663).
*/
package org.onosproject.drivers.odtn;
import org.apache.commons.configuration.XMLConfiguration;
import org.onosproject.drivers.odtn.util.NetconfSessionUtility;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.BitErrorRateState;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_OPTICAL_CHANNEL_NAME;
/**
* Implementation of BitErrorRateState interface for Cassini device running Ocnos v5.
*/
public class CassiniOcnos5BitErrorRate
extends AbstractHandlerBehaviour implements BitErrorRateState {
private static final Logger log = LoggerFactory.getLogger(CassiniOcnos5BitErrorRate.class);
private static final String RPC_TAG_NETCONF_BASE =
"<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
private static final String RPC_CLOSE_TAG = "</rpc>";
private static final String PRE_FEC_BER_TAG = "current-pre-fec-ber";
private static final String POST_FEC_BER_TAG = "current-post-fec-ber";
private static final String PRE_FEC_BER_FILTER =
"data.terminal-device.coherent-module.network-interfaces.interface.ber.state." + PRE_FEC_BER_TAG;
private static final String POST_FEC_BER_FILTER =
"data..terminal-device.coherent-module.network-interfaces.interface.ber.state." + POST_FEC_BER_TAG;
/*
* This method returns the instance of NetconfController from DriverHandler.
*/
private NetconfController getController() {
return handler().get(NetconfController.class);
}
/**
* Get the BER value pre FEC.
*
* @param deviceId the device identifier
* @param port the port identifier
* @return the decimal value of BER
*/
@Override
public Optional<Double> getPreFecBer(DeviceId deviceId, PortNumber port) {
NetconfSession session = NetconfSessionUtility
.getNetconfSession(deviceId, getController());
checkNotNull(session);
String slotIndex = getOpticalChannel(port);
if (slotIndex != null) {
String reply;
try {
reply = session.get(getBerFilter(slotIndex, PRE_FEC_BER_TAG));
} catch (Exception e) {
throw new IllegalStateException(new NetconfException("Failed to retrieve getPreFecBer info.", e));
}
log.debug("REPLY from device: {}", reply);
XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(reply);
if (xconf == null) {
log.error("Error in executing RPC");
return Optional.empty();
}
String powerString = xconf.getString((PRE_FEC_BER_FILTER));
log.debug("currentPreFecBer from device: {}", powerString);
if (powerString == null) {
return Optional.empty();
}
Double rational = 1e18;
return Optional.of(Double.valueOf(powerString) / rational);
}
return Optional.empty();
}
/**
* Get the OpenConfig component name for the OpticalChannel component.
*
* @param portNumber ONOS port number of the Line port ().
* @return the channel component name or null
*/
protected String getOpticalChannel(PortNumber portNumber) {
Port clientPort = handler().get(DeviceService.class).getPort(did(), portNumber);
return clientPort.annotations().value(OC_OPTICAL_CHANNEL_NAME);
}
/**
* Get the deviceId for which the methods apply.
*
* @return The deviceId as contained in the handler data
*/
private DeviceId did() {
return handler().data().deviceId();
}
/**
* Get the BER value post FEC.
*
* @param deviceId the device identifier
* @param port the port identifier
* @return the decimal value of BER
*/
@Override
public Optional<Double> getPostFecBer(DeviceId deviceId, PortNumber port) {
NetconfSession session = NetconfSessionUtility
.getNetconfSession(deviceId, getController());
checkNotNull(session);
String slotIndex = getOpticalChannel(port);
if (slotIndex != null) {
String reply;
try {
reply = session.get(getBerFilter(slotIndex, POST_FEC_BER_TAG));
} catch (Exception e) {
throw new IllegalStateException(new NetconfException("Failed to retrieve getPostFecBer info.", e));
}
log.debug("REPLY from device: {}", reply);
XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(reply);
if (xconf == null) {
log.error("Error in executing RPC");
return Optional.empty();
}
String powerString = xconf.getString(POST_FEC_BER_FILTER);
log.debug("currentPostFecBer from device: {}", powerString);
if (powerString == null) {
return Optional.empty();
}
Double rational = 1e18;
return Optional.of(Double.valueOf(powerString) / rational);
}
return Optional.empty();
}
private String getBerFilter(String slotNumber, String filterBer) {
StringBuilder filter = new StringBuilder();
filter.append("<terminal-device xmlns='http://www.ipinfusion.com/yang/ocnos/ipi-platform-terminal-device'>"
+ "<coherent-module>"
+ " <slot-index>" + slotNumber + "</slot-index>"
+ "<network-interfaces>"
+ "<interface>"
+ " <net-index>0</net-index>"
+ " <ber>"
+ " <state>"
+ " <" + filterBer + "/>"
+ " </state>"
+ " </ber>"
+ "</interface>"
+ "</network-interfaces>"
+ "</coherent-module>"
+ "</terminal-device>");
return filteredGetBuilder(filter.toString());
}
private String filteredGetBuilder(String filter) {
StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
rpc.append("<get>");
rpc.append("<filter type='subtree'>");
rpc.append(filter);
rpc.append("</filter>");
rpc.append("</get>");
rpc.append(RPC_CLOSE_TAG);
return rpc.toString();
}
}