Refactor DpQpsk/DpQam16 100G OFEC support
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / openroadminterface / OpenRoadmInterface710.java
index bdbfeb770061f80277840e7fdd331ad152901888..ecbb6eb7525393b85de93ef622577fbdf799aa08 100644 (file)
@@ -12,6 +12,7 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.stream.IntStream;
 import org.opendaylight.transportpce.common.StringConstants;
@@ -22,11 +23,12 @@ import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfa
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.AEndApiInfo;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.ZEndApiInfo;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220114.mapping.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev200327.TrailTraceOther.TimDetectMode;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev200327.parent.odu.allocation.ParentOduAllocationBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev200327.parent.odu.allocation.parent.odu.allocation.trib.slots.choice.OpucnBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.PowerDBm;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic14;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic24;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic28;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic36;
@@ -35,10 +37,12 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.ty
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.ModulationFormat;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.ProvisionModeType;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R100G;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R100GOtsi;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R200GOtsi;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R300GOtsi;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R400GOtsi;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Ofec;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Off;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Rsfec;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Scfec;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceBuilder;
@@ -71,9 +75,9 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.opu.OpuBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev200529.otu.container.OtuBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otsi.group.interfaces.rev200529.otsi.group.container.OtsiGroupBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If100GE;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOCHOTU4ODU4;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOtsiOtsigroup;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.If100GE;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.IfOCHOTU4ODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.IfOtsiOtsigroup;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.common.Uint8;
@@ -88,13 +92,7 @@ public class OpenRoadmInterface710 {
     private static final String RATE_EXCEPTION_MESSAGE =
         "Unable to get the rate";
     private static final String ODUC = "-ODUC";
-    private static final List<String> SUPPORTED_ODUCN_RATES = new ArrayList<>() {
-        {
-            add("2");
-            add("3");
-            add("4");
-        }
-    };
+    private static final List<String> SUPPORTED_ODUCN_RATES = List.of("1", "2", "3", "4");
     private final PortMapping portMapping;
     private final OpenRoadmInterfaces openRoadmInterfaces;
     private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmInterface710.class);
@@ -118,8 +116,11 @@ public class OpenRoadmInterface710 {
             .setSpeed(Uint32.valueOf(400000));
         // We have to differentiate if-100GE vs if-400GE
         if (portMap.getSupportedInterfaceCapability().contains(If100GE.class)) {
-            ethIfBuilder.setSpeed(Uint32.valueOf(100000));
-
+            ethIfBuilder
+                // There could be different client pluggables on either side QSFP28-LR4 or QSFP28-FR4
+                // LR4-requires FEC to off, while FR4 can accept even when FEC is off
+                .setFec(Off.class) // For 100G OFec mode, the fec is off
+                .setSpeed(Uint32.valueOf(100000));
         }
         InterfaceBuilder ethInterfaceBldr = createGenericInterfaceBuilder(portMap, EthernetCsmacd.class,
             logicalConnPoint + "-ETHERNET");
@@ -209,14 +210,22 @@ public class OpenRoadmInterface710 {
         // Use the rate to switch rather than modulation format
         int serviceRate = getServiceRate(modulationFormat, spectrumInformation);
         switch (serviceRate) {
+            case 100:
+                LOG.info("Given modulation format and spectral width 50GHz {} and thus rate is 100G",
+                    modulationFormat);
+                LOG.info("FOIC is 1.4 for 31.6 Gbaud and rate is 100");
+                flexoBuilder.setFoicType(Foic14.class)
+                    .setIid(new ArrayList<>(Arrays.asList(Uint8.valueOf(1))));
+                otsiBuilder.setOtsiRate(R100GOtsi.class)
+                    .setFlexo(flexoBuilder.build());
+                break;
             case 200:
                 LOG.info("Given modulation format is {} and thus rate is 200G", modulationFormat);
                 if (modulationFormat == ModulationFormat.DpQam16) {
                     LOG.info("FOIC is 2.8 for 31.6 Gbaud and rate is 200");
                     // FOIC rate is different
                     flexoBuilder.setFoicType(Foic28.class)
-                        .setIid(new ArrayList<>(Arrays.asList(Uint8.valueOf(1), Uint8.valueOf(2),
-                            Uint8.valueOf(3), Uint8.valueOf(4))));
+                        .setIid(new ArrayList<>(Arrays.asList(Uint8.valueOf(1), Uint8.valueOf(2))));
                 } else {
                     // default is dp-qpsk for 200G under 63.1 GBaud
                     flexoBuilder.setFoicType(Foic24.class)
@@ -308,6 +317,9 @@ public class OpenRoadmInterface710 {
             .setGroupId(Uint32.valueOf(1));
         boolean rateNotFound = false;
         switch (serviceRate) {
+            case 100:
+                otsiGroupBuilder.setGroupRate(R100GOtsi.class);
+                break;
             case 200:
                 otsiGroupBuilder.setGroupRate(R200GOtsi.class);
                 break;
@@ -365,9 +377,11 @@ public class OpenRoadmInterface710 {
             // create OCH interface
             interfaceOchOtsiOtsigroup = createOpenRoadmOchInterface(nodeId, logicalConnPoint, spectrumInformation);
         } else if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.class)) {
-            // Create OTSi and OTSi-group
+            // Create OTSi and OTSi-group and concat the names of the interface
             String interfaceOtsiName = createOpenRoadmOtsiInterface(nodeId, logicalConnPoint, spectrumInformation);
-            interfaceOchOtsiOtsigroup = createOpenRoadmOtsiGroupInterface(nodeId, logicalConnPoint, interfaceOtsiName,
+            // Concat the two names for this interface
+            interfaceOchOtsiOtsigroup = interfaceOtsiName
+                + "#" + createOpenRoadmOtsiGroupInterface(nodeId, logicalConnPoint, interfaceOtsiName,
                 spectrumInformation);
         }
 
@@ -457,6 +471,10 @@ public class OpenRoadmInterface710 {
         String otucnrate = null;
         boolean rateNotFound = false;
         switch (rate) {
+            case "100G":
+                otuBuilder.setOtucnNRate(Uint16.valueOf(1));
+                otucnrate = "1";
+                break;
             case "200G":
                 otuBuilder.setOtucnNRate(Uint16.valueOf(2));
                 otucnrate = "2";
@@ -736,43 +754,56 @@ public class OpenRoadmInterface710 {
                 String.format(MAPPING_ERROR_EXCEPTION_MESSAGE,
                     nodeId, logicalConnPoint));
         }
-        // OPU payload
-        OpuBuilder opuBuilder = new OpuBuilder()
-            .setExpPayloadType(PayloadTypeDef.getDefaultInstance("32"))
-            .setPayloadType(PayloadTypeDef.getDefaultInstance("32"));
 
         // Parent Odu-allocation
         // Set the trib-slot array
         List<OpucnTribSlotDef> tribslots = new ArrayList<>();
-        IntStream.range(1, 5).forEach(a -> IntStream.range(1, 21).forEach(b -> tribslots.add(
+        // Here the int stream is based on rate
+        // Get the rate, which can be 1, 2, 3 or 4 4=400G, 1=100G
+        String rate = supportingOducn.substring(supportingOducn.length() - 1);
+        IntStream.range(1, Integer.parseInt(rate) + 1).forEach(a -> IntStream.range(1, 21).forEach(b -> tribslots.add(
             OpucnTribSlotDef.getDefaultInstance(a + "." + b))));
 
         ParentOduAllocationBuilder parentOduAllocationBuilder = new ParentOduAllocationBuilder()
             .setTribPortNumber(Uint16.valueOf(1))
             .setTribSlotsChoice(new OpucnBuilder().setOpucnTribSlots(tribslots).build());
 
+        // OPU payload
+        OpuBuilder opuBuilder = new OpuBuilder();
+
         // Create an ODUFlex object
         OduBuilder oduBuilder = new OduBuilder()
-            .setRate(ODUflexCbr.class)
-            .setOduflexCbrService(ODUflexCbr400G.class)
             .setOduFunction(ODUTTPCTP.class)
             .setMonitoringMode(MonitoringMode.Terminated)
             .setTimActEnabled(false)
             .setTimDetectMode(TimDetectMode.Disabled)
             .setDegmIntervals(Uint8.valueOf(2))
             .setDegthrPercentage(Uint16.valueOf(100))
-            .setOpu(opuBuilder.build())
             .setParentOduAllocation(parentOduAllocationBuilder.build());
 
+        if (rate.equals("1")) {
+            opuBuilder.setExpPayloadType(PayloadTypeDef.getDefaultInstance("07"))
+                .setPayloadType(PayloadTypeDef.getDefaultInstance("07"));
+            oduBuilder.setRate(ODU4.class);
+            logicalConnPoint += "-ODU4";
+        } else if (rate.equals("4")) {
+            opuBuilder.setExpPayloadType(PayloadTypeDef.getDefaultInstance("32"))
+                .setPayloadType(PayloadTypeDef.getDefaultInstance("32"));
+            oduBuilder.setRate(ODUflexCbr.class).setOduflexCbrService(ODUflexCbr400G.class);
+            logicalConnPoint += "-ODUFLEX";
+        }
+
+        // Build the OPU container to the ODU builder
+        oduBuilder.setOpu(opuBuilder.build());
+
         InterfaceBuilder oduflexInterfaceBuilder = createGenericInterfaceBuilder(portMap, OtnOdu.class,
-            logicalConnPoint + "-ODUFLEX");
+            logicalConnPoint);
 
         List<String> listSupportingOtucnInterface = new ArrayList<>();
         listSupportingOtucnInterface.add(supportingOducn);
 
         oduflexInterfaceBuilder.setSupportingInterfaceList(listSupportingOtucnInterface);
 
-
         org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder
             oduflexIf1Builder =
             new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder();
@@ -809,40 +840,48 @@ public class OpenRoadmInterface710 {
                     znodeId, zlogicalConnPoint));
 
         }
-        // OPU payload
-        OpuBuilder opuBuilder = new OpuBuilder()
-            .setExpPayloadType(PayloadTypeDef.getDefaultInstance("32"))
-            .setPayloadType(PayloadTypeDef.getDefaultInstance("32"));
-
         // Parent Odu-allocation
         // Set the trib-slot array
         List<OpucnTribSlotDef> tribslots = new ArrayList<>();
-        IntStream.range(1, 5).forEach(a -> IntStream.range(1, 21).forEach(b -> tribslots.add(
+        // Here the int stream is based on rate
+        // Get the rate, which can be 1, 2, 3 or 4 4=400G, 1=100G
+        String rate = supportingOducn.substring(supportingOducn.lastIndexOf('-') + 1);
+        IntStream.range(1, Integer.parseInt(rate) + 1).forEach(a -> IntStream.range(1, 21).forEach(b -> tribslots.add(
             OpucnTribSlotDef.getDefaultInstance(a + "." + b))));
 
         ParentOduAllocationBuilder parentOduAllocationBuilder = new ParentOduAllocationBuilder()
             .setTribPortNumber(Uint16.valueOf(1))
             .setTribSlotsChoice(new OpucnBuilder().setOpucnTribSlots(tribslots).build());
 
+        // OPU payload
+        OpuBuilder opuBuilder = new OpuBuilder();
+
         // Create an ODUFlex object
         OduBuilder oduBuilder = new OduBuilder()
-            .setRate(ODUflexCbr.class)
-            .setOduflexCbrService(ODUflexCbr400G.class)
             .setOduFunction(ODUTTPCTP.class)
             .setMonitoringMode(MonitoringMode.Terminated)
             .setTimActEnabled(false)
             .setTimDetectMode(TimDetectMode.Disabled)
             .setDegmIntervals(Uint8.valueOf(2))
             .setDegthrPercentage(Uint16.valueOf(100))
-            .setTxSapi(portMapA.getLcpHashVal())
-            .setTxDapi(portMapZ.getLcpHashVal())
-            .setExpectedSapi(portMapZ.getLcpHashVal())
-            .setExpectedDapi(portMapA.getLcpHashVal())
             .setOpu(opuBuilder.build())
             .setParentOduAllocation(parentOduAllocationBuilder.build());
 
+        if (rate.equals("1")) {
+            opuBuilder.setExpPayloadType(PayloadTypeDef.getDefaultInstance("07"))
+                .setPayloadType(PayloadTypeDef.getDefaultInstance("07"));
+            oduBuilder.setRate(ODU4.class);
+            alogicalConnPoint += "-ODU4";
+        } else if (rate.equals("4")) {
+            opuBuilder.setExpPayloadType(PayloadTypeDef.getDefaultInstance("32"))
+                .setPayloadType(PayloadTypeDef.getDefaultInstance("32"));
+            oduBuilder.setRate(ODUflexCbr.class).setOduflexCbrService(ODUflexCbr400G.class);
+            alogicalConnPoint += "-ODUFLEX";
+        }
+
         InterfaceBuilder oduflexInterfaceBuilder = createGenericInterfaceBuilder(portMapA, OtnOdu.class,
-            alogicalConnPoint + "-ODUFLEX");
+            alogicalConnPoint);
+
 
         List<String> listSupportingOtucnInterface = new ArrayList<>();
         listSupportingOtucnInterface.add(supportingOducn);
@@ -877,17 +916,18 @@ public class OpenRoadmInterface710 {
         }
         // Depending on OTU4 or OTUCn, supporting interface should
         // reflect that
-        String interfaceOdu4Oducn = null;
+        String interfaceOdu4OducnOduflex = null;
+        // Depending on OTU4 or OTUCn, supporting interface should reflect that
         if (portMap.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.class)) {
             // create OTU4 interface
-            interfaceOdu4Oducn = createOpenRoadmOdu4Interface(nodeId, logicalConnPoint, apiInfoA, apiInfoZ);
+            interfaceOdu4OducnOduflex = createOpenRoadmOdu4Interface(nodeId, logicalConnPoint, apiInfoA, apiInfoZ);
         } else if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.class)) {
             // Create ODUCn and ODUFlex interface.
             String interfaceOducn = createOpenRoadmOducnInterface(nodeId, logicalConnPoint);
-            interfaceOdu4Oducn = createOpenRoadmOduflexInterface(nodeId, logicalConnPoint, interfaceOducn);
+            interfaceOdu4OducnOduflex  = interfaceOducn + "#"
+                + createOpenRoadmOduflexInterface(nodeId, logicalConnPoint, interfaceOducn);
         }
-
-        return interfaceOdu4Oducn;
+        return interfaceOdu4OducnOduflex;
     }
 
     public String createOpenRoadmOtnOducnInterface(String nodeId, String logicalConnPoint,
@@ -1051,34 +1091,41 @@ public class OpenRoadmInterface710 {
         justification = "call in call() method")
     private int getServiceRate(ModulationFormat modulationFormat, SpectrumInformation spectrumInformation) {
 
+        int rate;
         switch (modulationFormat) {
             case DpQpsk:
-                LOG.info("Given modulation format is {} and thus rate is 200G", modulationFormat);
-                return 200;
-            case DpQam8:
-                LOG.info("Given modulation format is {} and thus rate is 300G", modulationFormat);
-                return 300;
             case DpQam16:
-                // DpQam16 is possible for both 31.6 or 63.1 GBaud, for which spectral width is different
+                // DpQpsk and DpQam16 are possible for both 31.6 or 63.1 GBaud, for which spectral width is different
                 // Here take the difference of highest and lowest spectral numbers and determine the width
-                LOG.info("The width with guard band {}", (spectrumInformation.getHigherSpectralSlotNumber()
-                    - spectrumInformation.getLowerSpectralSlotNumber() + 1) * GridConstant.GRANULARITY);
-                if ((spectrumInformation.getHigherSpectralSlotNumber()
-                    - spectrumInformation.getLowerSpectralSlotNumber() + 1) * GridConstant.GRANULARITY == 50.0) {
-                    // Based on roll-of-factor of 0.5, 50 - 12.5 = 37.5GHz translates to 31.6 GBaud
+                double spectralWidth = (spectrumInformation.getHigherSpectralSlotNumber()
+                    - spectrumInformation.getLowerSpectralSlotNumber() + 1) * GridConstant.GRANULARITY;
+                LOG.info("The width with guard band {}", spectralWidth);
+                Map<ModulationFormat, Integer> rateMap;
+                if (spectralWidth == 50.0) {
+                    rateMap = Map.of(
+                            ModulationFormat.DpQpsk , 100,
+                            ModulationFormat.DpQam16 , 200);
+                    // Based on roll-of-factor of 0.2, 50 - 12.5 = 37.5GHz translates to 31.6 GBaud
                     LOG.info("The baud-rate is 31.6 GBaud");
-                    LOG.info("Given modulation format {} with 31.6 Gbaud rate is 200G", modulationFormat);
-                    return 200;
+                    return rateMap.get(modulationFormat);
                 } else {
-                    // Based on roll-of-factor of 0.5, 87.5 - 12.5 = 75GHz translates to 63.1 GBaud
+                    rateMap = Map.of(
+                            ModulationFormat.DpQpsk , 200,
+                            ModulationFormat.DpQam16 , 400);
+                    // Based on roll-of-factor of 0.2, 87.5 - 12.5 = 75GHz translates to 63.1 GBaud
                     LOG.info("The baud-rate is 63.1 GBaud");
-                    return 400;
                 }
+                rate = rateMap.get(modulationFormat);
+                break;
+            case DpQam8:
+                rate = 300;
+                break;
             default:
                 LOG.error("Modulation format is required to select the rate");
-                break;
+                return 0;
         }
-        return 0;
+        LOG.info("Given modulation format {} rate is {}", modulationFormat, rate);
+        return rate;
     }
 
 }