From 0487fce00ace36769d799c6185199f9c969e6f0c Mon Sep 17 00:00:00 2001 From: Balagangadhar Bathula Date: Wed, 27 Apr 2022 06:56:30 -0400 Subject: [PATCH] Add support for 100G OFEC - Interface hierarchy follows B100G model (OTSI-OTSIGROUP-OTUC1-ODUC1-ODU4) - Update the device renderer delete operation - Add the if-OTU4-ODU4 capability class JIRA: TRNSPRTPCE-636 Signed-off-by: Balagangadhar Bathula Change-Id: Id51f6680eca30d4a544f94d3d814b18c9e781484 --- .../common/mapping/MappingUtilsImpl.java | 2 + .../OpenRoadmInterface710.java | 127 +++++++++++++----- .../DeviceRendererServiceImpl.java | 6 +- 3 files changed, 95 insertions(+), 40 deletions(-) diff --git a/common/src/main/java/org/opendaylight/transportpce/common/mapping/MappingUtilsImpl.java b/common/src/main/java/org/opendaylight/transportpce/common/mapping/MappingUtilsImpl.java index d3b6df0ff..552d387e7 100644 --- a/common/src/main/java/org/opendaylight/transportpce/common/mapping/MappingUtilsImpl.java +++ b/common/src/main/java/org/opendaylight/transportpce/common/mapping/MappingUtilsImpl.java @@ -34,6 +34,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOC import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOCHOTU2EODU2E; import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOCHOTU2ODU2; 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.IfOTU4ODU4; import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOTUCnODUCn; import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.SupportedIfCapability; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -50,6 +51,7 @@ public class MappingUtilsImpl implements MappingUtils { { put("IfOTUCnODUCn", IfOTUCnODUCn.class); put("IfOCHOTU4ODU4", IfOCHOTU4ODU4.class); + put("IfOTU4ODU4", IfOTU4ODU4.class); put("IfOCH", IfOCH.class); put("If100GEODU4", If100GEODU4.class); put("If10GEODU2e", If10GEODU2e.class); diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterface710.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterface710.java index e0a0956e4..d34294e5f 100644 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterface710.java +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterface710.java @@ -27,6 +27,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev2003 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 +36,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; @@ -88,7 +91,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 SUPPORTED_ODUCN_RATES = List.of("2", "3", "4"); + private static final List 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); @@ -112,8 +115,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"); @@ -203,6 +209,15 @@ 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) { @@ -302,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; @@ -453,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"; @@ -732,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 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 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(); @@ -805,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 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 listSupportingOtucnInterface = new ArrayList<>(); listSupportingOtucnInterface.add(supportingOducn); @@ -874,17 +917,16 @@ public class OpenRoadmInterface710 { // Depending on OTU4 or OTUCn, supporting interface should // reflect that String interfaceOdu4OducnOduflex = null; + // Depending on OTU4 or OTUCn, supporting interface should reflect that if (portMap.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.class)) { // create OTU4 interface interfaceOdu4OducnOduflex = createOpenRoadmOdu4Interface(nodeId, logicalConnPoint, apiInfoA, apiInfoZ); } else if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.class)) { // Create ODUCn and ODUFlex interface. String interfaceOducn = createOpenRoadmOducnInterface(nodeId, logicalConnPoint); - // Here we concat the two interfaces - interfaceOdu4OducnOduflex = interfaceOducn + "#" + interfaceOdu4OducnOduflex = interfaceOducn + "#" + createOpenRoadmOduflexInterface(nodeId, logicalConnPoint, interfaceOducn); } - return interfaceOdu4OducnOduflex; } @@ -1049,26 +1091,37 @@ public class OpenRoadmInterface710 { justification = "call in call() method") private int getServiceRate(ModulationFormat modulationFormat, SpectrumInformation spectrumInformation) { + double spectralWidth = (spectrumInformation.getHigherSpectralSlotNumber() + - spectrumInformation.getLowerSpectralSlotNumber() + 1) * GridConstant.GRANULARITY; switch (modulationFormat) { case DpQpsk: - LOG.info("Given modulation format is {} and thus rate is 200G", modulationFormat); - return 200; + // DpQpsk is 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 {}", spectralWidth); + if (spectralWidth == 50.0) { + // 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 100G", modulationFormat); + return 100; + } else { + // 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 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 // 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 + LOG.info("The width with guard band {}", spectralWidth); + if (spectralWidth == 50.0) { + // 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; } else { - // Based on roll-of-factor of 0.5, 87.5 - 12.5 = 75GHz translates to 63.1 GBaud + // 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; } diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRendererServiceImpl.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRendererServiceImpl.java index 76481d289..41d175e29 100644 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRendererServiceImpl.java +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRendererServiceImpl.java @@ -399,11 +399,11 @@ public class DeviceRendererServiceImpl implements DeviceRendererService { ? Map.of( // We don't need ODUC2, ODUC3 here, since they are handled in OTN service-path // This has to be in an order of deletion - "ODU", List.of("ODU4", "ODUFLEX", "ODUC4"), + "ODU", List.of("ODU4", "ODUFLEX", "ODUC4", "ODUC1"), // Add intermediate OTUCn rates (OTUC2, OTUC3) // OTU4 is used in 100G service on 7.1 model - "other", List.of("OTU4", "OTUC2", "OTUC3", "OTUC4", - "OTSIGROUP-400G", "OTSIGROUP-300G", "OTSIGROUP-200G", + "other", List.of("OTU4", "OTUC1", "OTUC2", "OTUC3", "OTUC4", + "OTSIGROUP-400G", "OTSIGROUP-300G", "OTSIGROUP-200G", "OTSIGROUP-100G", spectralSlotName)) : Map.of( "ODU", List.of("ODU", "ODU4"), -- 2.36.6