ONOS-7867 FlowRuleProgrammable driver for OpenConfig Cassini
* Minor update of Transceiver and DescriptionDiscovery to support newly added Optical-Channel component
* Add OpenConfig config/state sample which can be used for initial value of emulator
Change-Id: I9497ec55965be6f3cc0f5b4b6270c77ebe50b4a8
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/CassiniTransceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/CassiniTransceiver.java
index 0a23450..8f89807 100755
--- a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/CassiniTransceiver.java
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/CassiniTransceiver.java
@@ -36,7 +36,7 @@
import java.util.Collections;
import java.util.List;
-import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_NAME;
+import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_LOGICAL_CHANNEL;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -52,16 +52,15 @@
@Override
public List<CharSequence> enable(PortNumber client, PortNumber line, boolean enable) {
- log.debug("enable() cassini route");
DeviceId did = this.data().deviceId();
Port clientPort = handler().get(DeviceService.class).getPort(did, client);
if (clientPort == null) {
log.warn("{} does not exist on {}", client, did);
return Collections.emptyList();
}
- String clientName = clientPort.annotations().value(OC_NAME);
+ String clientName = clientPort.annotations().value(OC_LOGICAL_CHANNEL);
if (Strings.isNullOrEmpty(clientName)) {
- log.warn("{} annotations not exist on {}@{}", OC_NAME, client, did);
+ log.warn("{} annotations not exist on {}@{}", OC_LOGICAL_CHANNEL, client, did);
return Collections.emptyList();
}
@@ -70,9 +69,9 @@
log.warn("{} does not exist on {}", line, did);
return Collections.emptyList();
}
- String lineName = linePort.annotations().value(OC_NAME);
+ String lineName = linePort.annotations().value(OC_LOGICAL_CHANNEL);
if (Strings.isNullOrEmpty(lineName)) {
- log.warn("{} annotations not exist on {}@{}", OC_NAME, line, did);
+ log.warn("{} annotations not exist on {}@{}", OC_LOGICAL_CHANNEL, line, did);
return Collections.emptyList();
}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java
index 96d3b4e..d511ca0 100644
--- a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java
@@ -48,6 +48,14 @@
String OC_TYPE = "oc-type";
/**
+ * Annotations key intended for a Port, which stores OpenConfig logical channel
+ * associated the port.
+ * <p>
+ * Optional; only for purpose of debugging.
+ */
+ String OC_LOGICAL_CHANNEL = "oc-logical-channel";
+
+ /**
* Annotations key intended for a Port,
* which stores string identifier used to
* logically group Ports corresponding to a transponder, etc.
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniFlowRuleProgrammable.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniFlowRuleProgrammable.java
new file mode 100644
index 0000000..bafa443
--- /dev/null
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniFlowRuleProgrammable.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2018-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 METRO-HAUL (761727).
+ */
+
+package org.onosproject.drivers.odtn;
+
+import com.google.common.collect.ImmutableList;
+import org.onlab.util.Frequency;
+import org.onosproject.drivers.odtn.impl.FlowRuleParser;
+import org.onosproject.drivers.odtn.impl.OpenConfigConnectionCache;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.netconf.DatastoreId;
+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.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_NAME;
+
+/**
+ * Implementation of FlowRuleProgrammable interface for
+ * OpenConfig terminal devices.
+ */
+public class CassiniFlowRuleProgrammable
+ extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+
+ private static final Logger log =
+ LoggerFactory.getLogger(CassiniFlowRuleProgrammable.class);
+
+ /**
+ * Apply the flow entries specified in the collection rules.
+ *
+ * @param rules A collection of Flow Rules to be applied
+ * @return The collection of added Flow Entries
+ */
+ @Override
+ public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+ NetconfSession session = getNetconfSession();
+ if (session == null) {
+ openConfigError("null session");
+ return ImmutableList.of();
+ }
+ List<FlowRule> added = new ArrayList<>();
+ for (FlowRule r : rules) {
+ try {
+ applyFlowRule(session, r);
+ } catch (Exception e) {
+ openConfigError("Error {}", e);
+ continue;
+ }
+ getConnectionCache().add(did(), r);
+ added.add(r);
+ }
+ openConfigLog("applyFlowRules added {}", added.size());
+ return added;
+ }
+
+ /**
+ * Get the flow entries that are present on the device.
+ *
+ * @return A collection of Flow Entries
+ */
+ @Override
+ public Collection<FlowEntry> getFlowEntries() {
+ OpenConfigConnectionCache cache = getConnectionCache();
+ if (cache.get(did()) == null) {
+ return ImmutableList.of();
+ }
+
+ List<FlowEntry> entries = new ArrayList<>();
+ for (FlowRule r : cache.get(did())) {
+ entries.add(
+ new DefaultFlowEntry(r, FlowEntry.FlowEntryState.ADDED, 0, 0, 0));
+ }
+ return entries;
+ }
+
+ /**
+ * Remove the specified flow rules.
+ *
+ * @param rules A collection of Flow Rules to be removed
+ * @return The collection of removed Flow Entries
+ */
+ @Override
+ public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
+ NetconfSession session = getNetconfSession();
+ if (session == null) {
+ openConfigError("null session");
+ return ImmutableList.of();
+ }
+ List<FlowRule> removed = new ArrayList<>();
+ for (FlowRule r : rules) {
+ try {
+ removeFlowRule(session, r);
+ } catch (Exception e) {
+ openConfigError("Error {}", e);
+ continue;
+ }
+ getConnectionCache().add(did(), r);
+ removed.add(r);
+ }
+ openConfigLog("removedFlowRules removed {}", removed.size());
+ return removed;
+ }
+
+ private OpenConfigConnectionCache getConnectionCache() {
+ return OpenConfigConnectionCache.init();
+ }
+
+ /**
+ * Helper method to get the device id.
+ */
+ private DeviceId did() {
+ return data().deviceId();
+ }
+
+ /**
+ * Helper method to log from this class adding DeviceId.
+ */
+ private void openConfigLog(String format, Object... arguments) {
+ log.info("OPENCONFIG {}: " + format, did(), arguments);
+ }
+
+ /**
+ * Helper method to log an error from this class adding DeviceId.
+ */
+ private void openConfigError(String format, Object... arguments) {
+ log.error("OPENCONFIG {}: " + format, did(), arguments);
+ }
+
+
+ /**
+ * Helper method to get the Netconf Session.
+ */
+ private NetconfSession getNetconfSession() {
+ NetconfController controller =
+ checkNotNull(handler().get(NetconfController.class));
+ return controller.getNetconfDevice(did()).getSession();
+ }
+
+ private void setOpticalChannelFrequency(NetconfSession session,
+ String optChannel, Frequency freq)
+ throws NetconfException {
+ StringBuilder sb = new StringBuilder();
+ sb.append(
+ "<components xmlns='http://openconfig.net/yang/platform'>"
+ + "<component operation='merge'>"
+ + "<name>" + optChannel + "</name>"
+ + "<oc-opt-term:optical-channel "
+ +
+ " xmlns:oc-opt-term='http://openconfig.net/yang/terminal-device'>"
+ + " <oc-opt-term:config>"
+ + " <oc-opt-term:frequency>" + (long) freq.asMHz() +
+ "</oc-opt-term:frequency>"
+ + " </oc-opt-term:config>"
+ + " </oc-opt-term:optical-channel>"
+ + "</component>"
+ + "</components>");
+
+ boolean ok =
+ session.editConfig(DatastoreId.RUNNING, null, sb.toString());
+ if (!ok) {
+ throw new NetconfException("error writing channel frequency");
+ }
+ }
+
+ /**
+ * 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
+ */
+ private String getOpticalChannel(PortNumber portNumber) {
+ Port clientPort = handler().get(DeviceService.class).getPort(did(), portNumber);
+ return clientPort.annotations().value(OC_NAME);
+ }
+
+ /**
+ * Apply the flowrule.
+ *
+ * Note: only bidirectional are supported as of now,
+ * given OpenConfig note (below). In consequence, only the
+ * TX rules are actually mapped to netconf ops.
+ * <p>
+ * https://github.com/openconfig/public/blob/master/release/models
+ * /optical-transport/openconfig-terminal-device.yang
+ * <p>
+ * Directionality:
+ * To maintain simplicity in the model, the configuration is
+ * described from client-to-line direction. The assumption is that
+ * equivalent reverse configuration is implicit, resulting in
+ * the same line-to-client configuration.
+ *
+ * @param session The Netconf session.
+ * @param r Flow Rules to be applied.
+ * @throws NetconfException if exchange goes wrong
+ */
+ protected void applyFlowRule(NetconfSession session, FlowRule r) throws NetconfException {
+ FlowRuleParser frp = new FlowRuleParser(r);
+ if (!frp.isReceiver()) {
+ String optChannel = getOpticalChannel(frp.getPortNumber());
+ setOpticalChannelFrequency(session, optChannel, frp.getCentralFrequency());
+ }
+ }
+
+
+ protected void removeFlowRule(NetconfSession session, FlowRule r)
+ throws NetconfException {
+ FlowRuleParser frp = new FlowRuleParser(r);
+ if (!frp.isReceiver()) {
+ String optChannel = getOpticalChannel(frp.getPortNumber());
+ setOpticalChannelFrequency(session, optChannel, Frequency.ofMHz(0));
+ }
+ }
+}
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniTerminalDeviceDiscovery.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniTerminalDeviceDiscovery.java
index acb6c4a..0f08e9c 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniTerminalDeviceDiscovery.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniTerminalDeviceDiscovery.java
@@ -40,6 +40,10 @@
import org.onosproject.netconf.NetconfDevice;
import org.onosproject.netconf.NetconfSession;
import org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.optical.device.OchPortHelper;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.ChannelSpacing;
import org.slf4j.Logger;
import java.util.HashMap;
@@ -244,21 +248,21 @@
HierarchicalConfiguration channel) {
HierarchicalConfiguration config = channel.configurationAt("config");
- String name = config.getString("index");
- String portName = config.getString("description");
+ String logicalChannelIndex = config.getString("index");
+ String description = config.getString("description");
String rateClass = config.getString("rate-class");
- log.info("Parsing Component {} type {} rate {}", name, portName, rateClass);
+ log.info("Parsing Component {} type {} rate {}", logicalChannelIndex, description, rateClass);
Map<String, String> annotations = new HashMap<>();
- annotations.put(OdtnDeviceDescriptionDiscovery.OC_NAME, name);
- annotations.put(OdtnDeviceDescriptionDiscovery.OC_TYPE, portName);
+ annotations.put(OdtnDeviceDescriptionDiscovery.OC_LOGICAL_CHANNEL, logicalChannelIndex);
+ annotations.put(OdtnDeviceDescriptionDiscovery.OC_NAME, description);
// Store all properties as port properties
Pattern clientPattern = Pattern.compile("ce(\\d*)/1"); // e.g. ce1/1
- Pattern linePattern = Pattern.compile("oe(\\d*)"); // e.g. oe1
- Matcher clientMatch = clientPattern.matcher(portName);
- Matcher lineMatch = linePattern.matcher(portName);
+ Pattern linePattern = Pattern.compile("oc(\\d*)/(\\d*)"); // e.g. oe1
+ Matcher clientMatch = clientPattern.matcher(description);
+ Matcher lineMatch = linePattern.matcher(description);
Pattern portSpeedPattern = Pattern.compile("TRIB_RATE_([0-9.]*)G");
Matcher portSpeedMatch = portSpeedPattern.matcher(rateClass);
@@ -266,6 +270,11 @@
Builder builder = DefaultPortDescription.builder();
+ if (portSpeedMatch.find()) {
+ Long speed = Long.parseLong(portSpeedMatch.group(1));
+ builder.portSpeed(speed * 1000);
+ }
+
if (clientMatch.find()) {
Long num = Long.parseLong(clientMatch.group(1));
Long portNum = 100 + num;
@@ -275,10 +284,14 @@
annotations.putIfAbsent(ONOS_PORT_INDEX, portNum.toString());
annotations.putIfAbsent(CONNECTION_ID, connectionId);
- builder.withPortNumber(PortNumber.portNumber(portNum, name));
+ builder.withPortNumber(PortNumber.portNumber(portNum));
builder.type(Type.PACKET);
+
+ builder.annotations(DefaultAnnotations.builder().putAll(annotations).build());
+ return builder.build();
+
} else if (lineMatch.find()) {
- Long num = Long.parseLong(lineMatch.group(1));
+ Long num = (Long.parseLong(lineMatch.group(1)) - 1) * 2 + Long.parseLong(lineMatch.group(2));
Long portNum = 200 + num;
String connectionId = "connection:" + num.toString();
@@ -286,16 +299,19 @@
annotations.putIfAbsent(ONOS_PORT_INDEX, portNum.toString());
annotations.putIfAbsent(CONNECTION_ID, connectionId);
- builder.withPortNumber(PortNumber.portNumber(portNum, name));
- builder.type(Type.OCH);
+ OchSignal signalId = OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1);
+ return OchPortHelper.ochPortDescription(
+ PortNumber.portNumber(portNum),
+ true,
+ OduSignalType.ODU4, // TODO Client signal to be discovered
+ true,
+ signalId,
+ DefaultAnnotations.builder().putAll(annotations).build());
+
+ } else {
+ log.warn("Unexpected component description: {}", description);
+ return null;
}
- if (portSpeedMatch.find()) {
- Long speed = Long.parseLong(portSpeedMatch.group(1));
- builder.portSpeed(speed * 1000);
- }
-
- builder.annotations(DefaultAnnotations.builder().putAll(annotations).build());
- return builder.build();
}
}
diff --git a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
index 60fe17f..2472385 100644
--- a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
+++ b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
@@ -58,6 +58,12 @@
impl="org.onosproject.drivers.odtn.CassiniTerminalDeviceDiscovery"/>
<behaviour api="org.onosproject.odtn.behaviour.ConfigurableTransceiver"
impl="org.onosproject.odtn.behaviour.CassiniTransceiver"/>
+ <behaviour api ="org.onosproject.net.optical.OpticalDevice"
+ impl="org.onosproject.net.optical.DefaultOpticalDevice"/>
+ <behaviour api ="org.onosproject.net.behaviour.LambdaQuery"
+ impl="org.onosproject.drivers.odtn.openconfig.TerminalDeviceLambdaQuery"/>
+ <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
+ impl="org.onosproject.drivers.odtn.CassiniFlowRuleProgrammable"/>
</driver>
<driver name="nokia-1830" manufacturer="nokia" hwVersion="1830" swVersion="R10.1.1">
<behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
diff --git a/drivers/odtn-driver/src/test/resources/cassini-init-device-config.xml b/drivers/odtn-driver/src/test/resources/cassini-init-device-config.xml
new file mode 100644
index 0000000..8ef51a7
--- /dev/null
+++ b/drivers/odtn-driver/src/test/resources/cassini-init-device-config.xml
@@ -0,0 +1,1098 @@
+<config xmlns="http://tail-f.com/ns/config/1.0">
+ <components xmlns="http://openconfig.net/yang/platform">
+ <component>
+ <name>oe1</name>
+ <config>
+ <name>oe1</name> <!-- must be the same as component/name -->
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe2</name>
+ <config>
+ <name>oe2</name> <!-- must be the same as component/name -->
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe3</name>
+ <config>
+ <name>oe3</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe4</name>
+ <config>
+ <name>oe4</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe5</name>
+ <config>
+ <name>oe5</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe6</name>
+ <config>
+ <name>oe6</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe7</name>
+ <config>
+ <name>oe7</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>oe8</name>
+ <config>
+ <name>oe8</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:CFP2_ACO</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+
+ <!-- [NEW] optical channel components :: start -->
+ <component>
+ <name>oc1/1</name>
+ <config>
+ <name>oc1/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe1</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc1/2</name>
+ <config>
+ <name>oc1/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe1</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc2/1</name>
+ <config>
+ <name>oc2/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe2</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc2/2</name>
+ <config>
+ <name>oc2/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe2</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc3/1</name>
+ <config>
+ <name>oc3/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe3</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc3/2</name>
+ <config>
+ <name>oc3/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe3</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc4/1</name>
+ <config>
+ <name>oc4/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe4</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc4/2</name>
+ <config>
+ <name>oc4/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe4</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc5/1</name>
+ <config>
+ <name>oc5/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe5</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc5/2</name>
+ <config>
+ <name>oc5/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe5</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc6/1</name>
+ <config>
+ <name>oc6/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe6</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc6/2</name>
+ <config>
+ <name>oc6/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe6</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc7/1</name>
+ <config>
+ <name>oc7/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe7</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc7/2</name>
+ <config>
+ <name>oc7/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe7</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc8/1</name>
+ <config>
+ <name>oc8/1</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194700000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe8</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <component>
+ <name>oc8/2</name>
+ <config>
+ <name>oc8/2</name>
+ </config>
+ <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+ <config>
+ <frequency>194750000</frequency> <!-- MHz -->
+ <target-output-power>-10.0</target-output-power> <!-- dbm -->
+ <line-port>oe8</line-port> <!-- components/component/name (type:TRANSCEIVER) -->
+ </config>
+ </optical-channel>
+ </component>
+ <!-- [NEW] optical channel components :: end -->
+
+ <component>
+ <name>ce1</name>
+ <config>
+ <name>ce1</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce2</name>
+ <config>
+ <name>ce2</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce3</name>
+ <config>
+ <name>ce3</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce4</name>
+ <config>
+ <name>ce4</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce5</name>
+ <config>
+ <name>ce5</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce6</name>
+ <config>
+ <name>ce6</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce7</name>
+ <config>
+ <name>ce7</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce8</name>
+ <config>
+ <name>ce8</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce9</name>
+ <config>
+ <name>ce9</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce10</name>
+ <config>
+ <name>ce10</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce11</name>
+ <config>
+ <name>ce11</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce12</name>
+ <config>
+ <name>ce12</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce13</name>
+ <config>
+ <name>ce13</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce14</name>
+ <config>
+ <name>ce14</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce15</name>
+ <config>
+ <name>ce15</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ <component>
+ <name>ce16</name>
+ <config>
+ <name>ce16</name>
+ </config>
+ <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+ <config>
+ <enabled>true</enabled>
+ <form-factor-preconf xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:QSFP28</form-factor-preconf>
+ </config>
+ </transceiver>
+ </component>
+ </components>
+ <terminal-device xmlns="http://openconfig.net/yang/terminal-device">
+ <logical-channels>
+ <channel>
+ <index>10101</index> <!-- must be uint32 -->
+ <config>
+ <index>10101</index> <!-- must be the same as logical-channels/channel/index -->
+ <description>ce1/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce1</transceiver>
+ </config>
+ </ingress>
+ <logical-channel-assignments>
+ <assignment>
+ <index>10101</index> <!-- the same value as parent channel's index -->
+ <config>
+ <index>10101</index> <!-- must be the same as logical-channel-assignments/assignment/index -->
+ <assignment-type>LOGICAL_CHANNEL</assignment-type>
+ <logical-channel>20101</logical-channel>
+ <allocation>100.0</allocation>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>10201</index>
+ <config>
+ <index>10201</index>
+ <description>ce2/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce2</transceiver>
+ </config>
+ </ingress>
+ <logical-channel-assignments>
+ <assignment>
+ <index>10201</index> <!-- the same value as parent channel's index -->
+ <config>
+ <index>10201</index>
+ <assignment-type>LOGICAL_CHANNEL</assignment-type>
+ <logical-channel>20102</logical-channel>
+ <allocation>100.0</allocation>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>10301</index>
+ <config>
+ <index>10301</index>
+ <description>ce3/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce3</transceiver>
+ </config>
+ </ingress>
+ <logical-channel-assignments>
+ <assignment>
+ <index>10301</index> <!-- the same value as parent channel's index -->
+ <config>
+ <index>10301</index>
+ <assignment-type>LOGICAL_CHANNEL</assignment-type>
+ <logical-channel>20202</logical-channel>
+ <allocation>100.0</allocation>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>10401</index>
+ <config>
+ <index>10401</index>
+ <description>ce4/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce4</transceiver>
+ </config>
+ </ingress>
+ <logical-channel-assignments>
+ <assignment>
+ <index>10401</index> <!-- the same value as parent channel's index -->
+ <config>
+ <index>10401</index>
+ <assignment-type>LOGICAL_CHANNEL</assignment-type>
+ <logical-channel>20201</logical-channel>
+ <allocation>100.0</allocation>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>10501</index>
+ <config>
+ <index>10501</index>
+ <description>ce5/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce5</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>10601</index>
+ <config>
+ <index>10601</index>
+ <description>ce6/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce6</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>10701</index>
+ <config>
+ <index>10701</index>
+ <description>ce7/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce7</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>10801</index>
+ <config>
+ <index>10801</index>
+ <description>ce8/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce8</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>10901</index>
+ <config>
+ <index>10901</index>
+ <description>ce9/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce9</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11001</index>
+ <config>
+ <index>11001</index>
+ <description>ce10/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce10</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11101</index>
+ <config>
+ <index>11101</index>
+ <description>ce11/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce11</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11201</index>
+ <config>
+ <index>11201</index>
+ <description>ce12/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce12</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11301</index>
+ <config>
+ <index>11301</index>
+ <description>ce13/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce13</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11401</index>
+ <config>
+ <index>11401</index>
+ <description>ce14/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce14</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11501</index>
+ <config>
+ <index>11501</index>
+ <description>ce15/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce15</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>11601</index>
+ <config>
+ <index>11601</index>
+ <description>ce16/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <trib-protocol xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_100GE</trib-protocol>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <ingress>
+ <config>
+ <transceiver>ce16</transceiver>
+ </config>
+ </ingress>
+ </channel>
+ <channel>
+ <index>20101</index>
+ <config>
+ <index>20101</index>
+ <description>oc1/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+
+ <!-- [NEW] association with optical channel component :: start -->
+ <logical-channel-assignments>
+ <assignment>
+ <index>20101</index>
+ <config>
+ <index>20101</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc1/1</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ <!-- [NEW] association with optical channel component :: end -->
+
+ </channel>
+ <channel>
+ <index>20102</index>
+ <config>
+ <index>20102</index>
+ <description>oc1/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <!-- [NEW] association with optical channel component :: start -->
+ <logical-channel-assignments>
+ <assignment>
+ <index>20102</index>
+ <config>
+ <index>20102</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc1/2</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ <!-- [NEW] association with optical channel component :: end -->
+ </channel>
+ <channel>
+ <index>20201</index>
+ <config>
+ <index>20201</index>
+ <description>oc2/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <!-- [NEW] association with optical channel component :: start -->
+ <logical-channel-assignments>
+ <assignment>
+ <index>20201</index>
+ <config>
+ <index>20201</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc2/1</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ <!-- [NEW] association with optical channel component :: end -->
+ </channel>
+ <channel>
+ <index>20202</index>
+ <config>
+ <index>20202</index>
+ <description>oc2/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <!-- [NEW] association with optical channel component :: start -->
+ <logical-channel-assignments>
+ <assignment>
+ <index>20202</index>
+ <config>
+ <index>20202</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc2/2</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ <!-- [NEW] association with optical channel component :: end -->
+ </channel>
+ <channel>
+ <index>20301</index>
+ <config>
+ <index>20301</index>
+ <description>oc3/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ </channel>
+ <channel>
+ <index>20302</index>
+ <config>
+ <index>20302</index>
+ <description>oc3/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ </channel>
+ <channel>
+ <index>20401</index>
+ <config>
+ <index>20401</index>
+ <description>oc4/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ </channel>
+ <channel>
+ <index>20402</index>
+ <config>
+ <index>20402</index>
+ <description>oc4/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ </channel>
+ <channel>
+ <index>20501</index>
+ <config>
+ <index>20501</index>
+ <description>oc5/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20501</index>
+ <config>
+ <index>20501</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc5/1</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20502</index>
+ <config>
+ <index>20502</index>
+ <description>oc5/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20502</index>
+ <config>
+ <index>20502</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc5/2</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20601</index>
+ <config>
+ <index>20601</index>
+ <description>oc6/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20601</index>
+ <config>
+ <index>20601</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc6/1</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20602</index>
+ <config>
+ <index>20602</index>
+ <description>oc6/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20602</index>
+ <config>
+ <index>20602</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc6/2</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20701</index>
+ <config>
+ <index>20701</index>
+ <description>oc7/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20701</index>
+ <config>
+ <index>20701</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc7/1</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20702</index>
+ <config>
+ <index>20702</index>
+ <description>oc7/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20702</index>
+ <config>
+ <index>20702</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc7/2</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20801</index>
+ <config>
+ <index>20801</index>
+ <description>oc8/1</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20801</index>
+ <config>
+ <index>20801</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc8/1</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ <channel>
+ <index>20802</index>
+ <config>
+ <index>20802</index>
+ <description>oc8/2</description>
+ <admin-state>ENABLED</admin-state>
+ <rate-class xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:TRIB_RATE_100G</rate-class>
+ <logical-channel-type xmlns:oc-opt-types="http://openconfig.net/yang/transport-types">oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ </config>
+ <logical-channel-assignments>
+ <assignment>
+ <index>20802</index>
+ <config>
+ <index>20802</index>
+ <assignment-type>OPTICAL_CHANNEL</assignment-type>
+ <optical-channel>oc8/2</optical-channel>
+ </config>
+ </assignment>
+ </logical-channel-assignments>
+ </channel>
+ </logical-channels>
+ </terminal-device>
+</config>
diff --git a/drivers/odtn-driver/src/test/resources/cassini-init-device-state.xml b/drivers/odtn-driver/src/test/resources/cassini-init-device-state.xml
new file mode 100644
index 0000000..4284730
--- /dev/null
+++ b/drivers/odtn-driver/src/test/resources/cassini-init-device-state.xml
@@ -0,0 +1,246 @@
+<components xmlns="http://openconfig.net/yang/platform">
+ <component>
+ <name>oe1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe3</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe4</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe5</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe6</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe7</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>oe8</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+
+ <!-- [NEW] optical channel components :: start -->
+ <component>
+ <name>oc1/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc1/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc2/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc2/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc3/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc3/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc4/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc4/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc5/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc5/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc6/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc6/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc7/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc7/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc8/1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <component>
+ <name>oc8/2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:OPTICAL_CHANNEL</type>
+ </state>
+ </component>
+ <!-- [NEW] optical channel components :: end -->
+
+ <component>
+ <name>xe1</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe2</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe3</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe4</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe5</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe6</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe7</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe8</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe9</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe10</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>xe11</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>ce12</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>ce13</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>ce14</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>ce15</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+ <component>
+ <name>ce16</name>
+ <state>
+ <type xmlns:oc-platform-types="http://openconfig.net/yang/platform-types">oc-platform-types:TRANSCEIVER</type>
+ </state>
+ </component>
+</components>