[Emu] Open Flow Optical Port Description
Change-Id: I8da4d7a1e1dea18d56cba9673f70b1ec69a5adcf
diff --git a/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java
index 494273c..e2d3e6d 100644
--- a/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Open Networking Laboratory
+ * Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,12 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
+import org.onlab.util.Frequency;
import org.onosproject.cli.Comparators;
import org.onosproject.net.Device;
+import org.onosproject.net.OchPort;
+import org.onosproject.net.OduCltPort;
+import org.onosproject.net.OmsPort;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
@@ -41,7 +45,10 @@
description = "Lists all ports or all ports of a device")
public class DevicePortsListCommand extends DevicesListCommand {
- private static final String FMT = " port=%s, state=%s, type=%s, speed=%s%s";
+ private static final String FMT = " port=%s, state=%s, type=%s, speed=%s %s";
+ private static final String FMT_OCH = " port=%s, state=%s, type=%s, signalType=%s, isTunable=%s %s";
+ private static final String FMT_ODUCLT = " port=%s, state=%s, type=%s, signalType=%s %s";
+ private static final String FMT_OMS = " port=%s, state=%s, type=%s, Freqs= %s / %s / %s GHz, totalChannels=%s %s";
@Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
required = false, multiValued = false)
@@ -137,13 +144,34 @@
List<Port> ports = new ArrayList<>(service.getPorts(device.id()));
Collections.sort(ports, Comparators.PORT_COMPARATOR);
for (Port port : ports) {
- if (isIncluded(port)) {
- print(FMT, portName(port.number()),
- port.isEnabled() ? "enabled" : "disabled",
- port.type().toString().toLowerCase(), port.portSpeed(),
- annotations(port.annotations()));
+ if (!isIncluded(port)) {
+ continue;
+ }
+ String portName = portName(port.number());
+ Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled";
+ String portType = port.type().toString().toLowerCase();
+ String annotations = annotations(port.annotations());
+ switch (port.type()) {
+ case OCH:
+ print(FMT_OCH, portName, portIsEnabled, portType,
+ ((OchPort) port).signalType().toString(),
+ ((OchPort) port).isTunable() ? "yes" : "no", annotations);
+ break;
+ case ODUCLT:
+ print(FMT_ODUCLT, portName, portIsEnabled, portType,
+ ((OduCltPort) port).signalType().toString(), annotations);
+ break;
+ case OMS:
+ print(FMT_OMS, portName, portIsEnabled, portType,
+ ((OmsPort) port).minFrequency().asHz() / Frequency.ofGHz(1).asHz(),
+ ((OmsPort) port).maxFrequency().asHz() / Frequency.ofGHz(1).asHz(),
+ ((OmsPort) port).grid().asHz() / Frequency.ofGHz(1).asHz(),
+ ((OmsPort) port).totalChannels(), annotations);
+ break;
+ default:
+ print(FMT, portName, portIsEnabled, portType, port.portSpeed(), annotations);
+ break;
}
}
}
-
}
diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
index b0b3abe..e35dc0c 100644
--- a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
@@ -15,8 +15,26 @@
*/
package org.onosproject.net.device.impl;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.NONE;
+import static org.onosproject.net.MastershipRole.STANDBY;
+import static org.onosproject.security.AppGuard.checkPermission;
+import static org.onosproject.security.AppPermission.Type.DEVICE_READ;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -26,12 +44,6 @@
import org.apache.felix.scr.annotations.Service;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
-import org.onosproject.net.provider.AbstractListenerProviderRegistry;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.basics.BasicDeviceConfig;
-import org.onosproject.net.config.basics.OpticalPortConfig;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
@@ -44,6 +56,11 @@
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.BasicDeviceConfig;
+import org.onosproject.net.config.basics.OpticalPortConfig;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceAdminService;
@@ -58,27 +75,11 @@
import org.onosproject.net.device.DeviceStoreDelegate;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.slf4j.Logger;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.MastershipRole.*;
-import static org.onosproject.security.AppGuard.checkPermission;
-import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.security.AppPermission.Type.*;
+import com.google.common.util.concurrent.Futures;
/**
* Provides implementation of the device SB & NB APIs.
@@ -347,11 +348,15 @@
log.info("Device {} disconnected from this node", deviceId);
List<Port> ports = store.getPorts(deviceId);
- List<PortDescription> descs = Lists.newArrayList();
- ports.forEach(port ->
- descs.add(new DefaultPortDescription(port.number(),
- false, port.type(),
- port.portSpeed())));
+ final Device device = getDevice(deviceId);
+
+ List<PortDescription> descs = ports.stream().map(
+ port -> (!(Device.Type.ROADM.equals(device.type()))) ?
+ new DefaultPortDescription(port.number(), false,
+ port.type(), port.portSpeed()) :
+ OpticalPortOperator.descriptionOf(port, false)
+ ).collect(Collectors.toList());
+
store.updatePorts(this.provider().id(), deviceId, descs);
try {
if (mastershipService.isLocalMaster(deviceId)) {
@@ -430,6 +435,12 @@
portDescription);
return;
}
+ final Device device = getDevice(deviceId);
+ if ((Device.Type.ROADM.equals(device.type()))) {
+ Port port = getPort(deviceId, portDescription.portNumber());
+ portDescription = OpticalPortOperator.descriptionOf(port, portDescription.isEnabled());
+ }
+
portDescription = consolidate(deviceId, portDescription);
final DeviceEvent event = store.updatePortStatus(this.provider().id(),
deviceId, portDescription);
diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java b/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java
index b2fd02c..8f2bda0 100644
--- a/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java
+++ b/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java
@@ -151,8 +151,25 @@
*/
public static PortDescription descriptionOf(Port port) {
checkNotNull(port, "Must supply non-null Port");
+ final boolean isUp = port.isEnabled();
+ return descriptionOfPort(port, isUp);
+ }
+
+ /**
+ * Returns a description built from an existing port and reported status.
+ *
+ * @param port
+ * @param isEnabled
+ * @return a PortDescription based on the port
+ */
+ static PortDescription descriptionOf(Port port, boolean isEnabled) {
+ checkNotNull(port, "Must supply non-null Port");
+ final boolean isup = isEnabled;
+ return descriptionOfPort(port, isup);
+ }
+
+ private static PortDescription descriptionOfPort(Port port, final boolean isup) {
final PortNumber ptn = port.number();
- final boolean isup = port.isEnabled();
final SparseAnnotations an = (SparseAnnotations) port.annotations();
switch (port.type()) {
case OMS:
diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java b/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java
new file mode 100644
index 0000000..a62b93c
--- /dev/null
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.driver.handshaker;
+
+import org.projectfloodlight.openflow.protocol.OFExpPort;
+import org.projectfloodlight.openflow.protocol.OFExpPortDescReply;
+import org.projectfloodlight.openflow.protocol.OFExpPortDescRequest;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFStatsReply;
+import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
+import org.projectfloodlight.openflow.protocol.OFStatsType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+import org.onosproject.net.Device;
+import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
+import org.onosproject.openflow.controller.PortDescPropertyType;
+import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
+import org.projectfloodlight.openflow.protocol.OFObject;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+
+/**
+ * Open Flow Optical Switch handshaker - for Open Flow 13.
+ */
+public class OFOpticalSwitch13 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
+
+ private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
+ private List<OFExpPort> expPortDes = new ArrayList<>();
+
+ @Override
+ public Boolean supportNxRole() {
+ return false;
+ }
+
+ @Override
+ public void startDriverHandshake() {
+ log.info("Starting driver handshake for sw {}", getStringId());
+ if (startDriverHandshakeCalled) {
+ throw new SwitchDriverSubHandshakeAlreadyStarted();
+ }
+ startDriverHandshakeCalled = true;
+
+ log.debug("sendHandshakeOFExperimenterPortDescRequest for sw {}", getStringId());
+
+ try {
+ sendHandshakeOFExperimenterPortDescRequest();
+ } catch (IOException e) {
+ log.error("Failed to send handshaker message OFExperimenterPortDescRequestfor sw {}, {}",
+ getStringId(), e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void processDriverHandshakeMessage(OFMessage m) {
+ if (!startDriverHandshakeCalled) {
+ throw new SwitchDriverSubHandshakeNotStarted();
+ }
+ if (driverHandshakeComplete.get()) {
+ throw new SwitchDriverSubHandshakeCompleted(m);
+ }
+
+ log.debug("processDriverHandshakeMessage for sw {}", getStringId());
+
+ switch (m.getType()) {
+ case STATS_REPLY: // multipart message is reported as STAT
+ processOFMultipartReply((OFStatsReply) m);
+ break;
+ default:
+ log.warn("Received message {} during switch-driver " +
+ "subhandshake " + "from switch {} ... " +
+ "Ignoring message", m,
+ getStringId());
+ }
+ }
+
+ private void processOFMultipartReply(OFStatsReply stats) {
+ log.debug("Received message {} during switch-driver " +
+ "subhandshake " + "from switch {} ... " +
+ stats,
+ getStringId());
+
+ if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
+ try {
+ OFExpPortDescReply expPortDescReply = (OFExpPortDescReply) stats;
+ expPortDes.addAll(expPortDescReply.getEntries());
+ if (!expPortDescReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
+ driverHandshakeComplete.set(true);
+ return;
+ }
+ } catch (ClassCastException e) {
+ log.error("Unexspected Experimenter Multipart message type {} "
+ , stats.getClass().getName());
+ }
+ }
+ }
+
+
+ @Override
+ public boolean isDriverHandshakeComplete() {
+ return driverHandshakeComplete.get();
+ }
+
+ private void sendHandshakeOFExperimenterPortDescRequest() throws
+ IOException {
+
+ OFExpPortDescRequest preq = factory()
+ .buildExpPortDescRequest()
+ .setXid(getNextTransactionId())
+ .build();
+
+ log.debug("Sending experimented port description " +
+ "message " +
+ "{}",
+ preq.toString());
+
+ this.sendHandshakeMessage(preq);
+ }
+
+ @Override
+ public Device.Type deviceType() {
+ return Device.Type.ROADM;
+ }
+
+ /*
+ * OduClt ports are reported as regular ETH ports.
+ */
+ @Override
+ public List<OFPortDesc> getPorts() {
+ return ImmutableList.copyOf(
+ ports.stream().flatMap(p -> p.getEntries().stream())
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
+ return ImmutableList.copyOf(expPortDes);
+ }
+
+ @Override
+ public Set<PortDescPropertyType> getPortTypes() {
+ return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
+ }
+
+}
diff --git a/drivers/src/main/resources/onos-drivers.xml b/drivers/src/main/resources/onos-drivers.xml
index ac307c2..aea743f 100644
--- a/drivers/src/main/resources/onos-drivers.xml
+++ b/drivers/src/main/resources/onos-drivers.xml
@@ -120,5 +120,10 @@
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/>
</driver>
+ <driver name="eci" extends="default"
+ manufacturer="ECI Telecom" hwVersion="optical" swVersion="V_1_0">
+ <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
+ impl="org.onosproject.driver.handshaker.OFOpticalSwitch13"/>
+ </driver>
</drivers>
diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index cb19dc5..0aea805 100644
--- a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -15,10 +15,24 @@
*/
package org.onosproject.provider.of.device.impl;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onlab.util.Tools.get;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.Port.Type.COPPER;
+import static org.onosproject.net.Port.Type.FIBER;
+import static org.onosproject.openflow.controller.Dpid.dpid;
+import static org.onosproject.openflow.controller.Dpid.uri;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -28,15 +42,17 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onlab.util.Frequency;
-import org.onosproject.cfg.ComponentConfigService;
import org.onlab.util.Spectrum;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduCltPort;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
@@ -49,6 +65,7 @@
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.OchPortDescription;
+import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
@@ -64,13 +81,19 @@
import org.onosproject.openflow.controller.RoleState;
import org.osgi.service.component.ComponentContext;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFExpPort;
+import org.projectfloodlight.openflow.protocol.OFExpPortDescPropOpticalTransport;
+import org.projectfloodlight.openflow.protocol.OFExpPortOpticalTransportLayerEntry;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFObject;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
import org.projectfloodlight.openflow.protocol.OFPortFeatures;
import org.projectfloodlight.openflow.protocol.OFPortOptical;
+import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportLayerClass;
+import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportSignalType;
import org.projectfloodlight.openflow.protocol.OFPortReason;
import org.projectfloodlight.openflow.protocol.OFPortState;
import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
@@ -83,23 +106,10 @@
import org.projectfloodlight.openflow.types.PortSpeed;
import org.slf4j.Logger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onlab.util.Tools.get;
-import static org.onosproject.net.DeviceId.deviceId;
-import static org.onosproject.net.Port.Type.COPPER;
-import static org.onosproject.net.Port.Type.FIBER;
-import static org.onosproject.openflow.controller.Dpid.dpid;
-import static org.onosproject.openflow.controller.Dpid.uri;
-import static org.slf4j.LoggerFactory.getLogger;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
/**
* Provider which uses an OpenFlow controller to detect network
@@ -110,6 +120,9 @@
private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class);
private static final long MBPS = 1_000 * 1_000;
+ private static final Frequency FREQ100 = Frequency.ofGHz(100);
+ private static final Frequency FREQ193_1 = Frequency.ofTHz(193.1);
+ private static final Frequency FREQ4_4 = Frequency.ofTHz(4.4);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceProviderRegistry providerRegistry;
@@ -386,18 +399,27 @@
*/
private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) {
final List<PortDescription> portDescs = new ArrayList<>(sw.getPorts().size());
- sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
+ if (!(Device.Type.ROADM.equals(sw.deviceType()))) {
+ sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
+ }
OpenFlowOpticalSwitch opsw;
switch (sw.deviceType()) {
case ROADM:
opsw = (OpenFlowOpticalSwitch) sw;
+ List<OFPortDesc> ports = opsw.getPorts();
+ LOG.debug("SW ID {} , ETH- ODU CLT Ports {}", opsw.getId(), ports);
+ // ODU client ports are reported as ETH
+ ports.forEach(port -> portDescs.add(buildOduCltPortDescription(port)));
+
opsw.getPortTypes().forEach(type -> {
- opsw.getPortsOf(type).forEach(
- op -> {
- portDescs.add(buildPortDescription(type, (OFPortOptical) op));
- }
- );
+ List<? extends OFObject> portsOf = opsw.getPortsOf(type);
+ LOG.debug("Ports Of{}", portsOf);
+ portsOf.forEach(
+ op -> {
+ portDescs.add(buildPortDescription(type, (OFObject) op));
+ }
+ );
});
break;
case FIBER_SWITCH:
@@ -417,6 +439,105 @@
return portDescs;
}
+ private PortDescription buildOduCltPortDescription(OFPortDesc port) {
+ PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
+ boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
+ !port.getConfig().contains(OFPortConfig.PORT_DOWN);
+ Long portSpeed = portSpeed(port);
+ OduCltPort.SignalType sigType = null;
+
+ switch (portSpeed.toString()) {
+ case "1":
+ sigType = OduCltPort.SignalType.CLT_1GBE;
+ break;
+ case "10":
+ sigType = OduCltPort.SignalType.CLT_10GBE;
+ break;
+ case "40":
+ sigType = OduCltPort.SignalType.CLT_40GBE;
+ break;
+ case "100":
+ sigType = OduCltPort.SignalType.CLT_100GBE;
+ break;
+ default:
+ throw new RuntimeException("Un recognize OduClt speed: " + portSpeed.toString());
+ }
+
+ SparseAnnotations annotations = buildOduCltAnnotation(port);
+ return new OduCltPortDescription(portNo, enabled, sigType, annotations);
+ }
+
+ private SparseAnnotations buildOduCltAnnotation(OFPortDesc port) {
+ SparseAnnotations annotations = null;
+ String portName = Strings.emptyToNull(port.getName());
+ if (portName != null) {
+ annotations = DefaultAnnotations.builder()
+ .set(AnnotationKeys.PORT_NAME, portName)
+ .set(AnnotationKeys.STATIC_PORT, Boolean.TRUE.toString()).build();
+ }
+ return annotations;
+ }
+
+ private PortDescription buildPortDescription(PortDescPropertyType ptype, OFObject port) {
+ if (port instanceof OFPortOptical) {
+ return buildPortDescription(ptype, (OFPortOptical) port);
+ }
+ return buildPortDescription(ptype, (OFExpPort) port);
+ }
+
+ /**
+ * Build a portDescription from a given a port description describing some
+ * Optical port.
+ *
+ * @param ptype description property type.
+ * @param port the port to build from.
+ * @return portDescription for the port.
+ */
+ private PortDescription buildPortDescription(PortDescPropertyType ptype, OFExpPort port) {
+ PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
+ boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
+ && !port.getConfig().contains(OFPortConfig.PORT_DOWN);
+ SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+
+ OFExpPortDescPropOpticalTransport firstProp = port.getProperties().get(0);
+ OFPortOpticalTransportSignalType sigType = firstProp.getPortSignalType();
+
+ DefaultPortDescription portDes = null;
+ switch (sigType) {
+ case OMSN:
+ portDes = new OmsPortDescription(portNo, enabled, FREQ193_1, FREQ193_1.add(FREQ4_4),
+ FREQ100, annotations);
+ break;
+ case OCH:
+ OFExpPortOpticalTransportLayerEntry entry = firstProp.getFeatures().get(0).getValue().get(0);
+ OFPortOpticalTransportLayerClass layerClass = entry.getLayerClass();
+ if (!OFPortOpticalTransportLayerClass.ODU.equals(layerClass)) {
+ LOG.error("Unsupported layer Class {} ", layerClass);
+ return null;
+ }
+
+ // convert to ONOS OduSignalType
+ OduSignalType oduSignalType = OpenFlowDeviceValueMapper.
+ lookupOduSignalType((byte) entry.getSignalType());
+ //OchSignal is needed for OchPortDescription constructor,
+ //yet not relevant for tunable OCH port, creating with default parameters
+ OchSignal signalId = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 1, 1);
+
+ portDes = new OchPortDescription(portNo, enabled,
+ oduSignalType, true, signalId, annotations);
+
+ break;
+ case OTU2:
+ case OTU4:
+ LOG.error("Signal tpye OTU2/4 not supported yet ", port.toString());
+ break;
+ default:
+ break;
+ }
+
+ return portDes;
+ }
+
/**
* Creates an annotation for the port name if one is available.
*
@@ -565,5 +686,4 @@
}
}
}
-
}
diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java
new file mode 100644
index 0000000..7bdf06f
--- /dev/null
+++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.provider.of.device.impl;
+
+import org.onosproject.net.OduSignalType;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.EnumHashBiMap;
+
+/**
+ * Collection of helper methods to convert protocol agnostic models to values used in OpenFlow spec.
+ */
+final class OpenFlowDeviceValueMapper {
+
+ // prohibit instantiation
+ private OpenFlowDeviceValueMapper() {}
+
+ private static final BiMap<OduSignalType, Byte> ODU_SIGNAL_TYPES = EnumHashBiMap.create(OduSignalType.class);
+ static {
+ // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU1, (byte) 1); // OFPODUT_ODU1 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU2, (byte) 2); // OFPODUT_ODU2 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU3, (byte) 3); // OFPODUT_ODU3 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU4, (byte) 4); // OFPODUT_ODU4 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU0, (byte) 10); // OFPODUT_ODU0 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU2e, (byte) 11); // OFPODUT_ODU2E of enum ofp_odu_signal_type
+ }
+
+ /**
+ * Looks up the specified input value to the corresponding value with the specified map.
+ *
+ * @param map bidirectional mapping
+ * @param input input value
+ * @param cls class of output value
+ * @param <I> type of input value
+ * @param <O> type of output value
+ * @return the corresponding value stored in the specified map
+ */
+ private static <I, O> O lookup(BiMap<I, O> map, I input, Class<O> cls) {
+ if (!map.containsKey(input)) {
+ throw new RuntimeException(
+ String.format("No mapping found for %s when converting to %s", input, cls.getName()));
+ }
+
+ return map.get(input);
+ }
+
+ /**
+ * Looks up the the corresponding {@link OduSignalType} instance
+ * from the specified byte value for ODU signal type defined in
+ * ONF "Optical Transport Protocol Extensions Version 1.0".
+ *
+ * @param signalType byte value as ODU (Optical channel Data Unit) signal type defined the spec
+ * @return the corresponding OchSignalType instance
+ */
+ static OduSignalType lookupOduSignalType(byte signalType) {
+ return lookup(ODU_SIGNAL_TYPES.inverse(), signalType, OduSignalType.class);
+ }
+
+}