From 95ee0d5f2b5ea882aed5684416cb63ef11e3910d Mon Sep 17 00:00:00 2001
From: massifben <105049157+massifben@users.noreply.github.com>
Date: Wed, 6 Dec 2023 11:58:21 +0100
Subject: [PATCH] feat(#362): RSR-812 - Use generated JAXB class for
 configuration of Communication of Control Blocks

Signed-off-by: massifben <105049157+massifben@users.noreply.github.com>
---
 .../SclAutomationServiceIntegrationTest.java  |   5 +-
 sct-commons/pom.xml                           |  19 +-
 .../commons/ControlBlockEditorService.java    | 430 ++++++++++++++++++
 .../sct/commons/ControlBlockService.java      | 159 -------
 .../sct/commons/api/ControlBlockEditor.java   |  16 +-
 .../dto/ControlBlockNetworkSettings.java      |  71 ---
 .../sct/commons/scl/ControlService.java       |  26 ++
 .../commons/scl/ied/ControlBlockAdapter.java  |  80 ----
 .../sct/commons/util/ControlBlockEnum.java    |  24 +-
 .../ControlBlockNetworkSettingsCsvHelper.java | 204 ---------
 .../src/main/resources/xsd/GSE_SMV_CB_COM.xsd | 152 +++++++
 .../{LDEPF_Config_file_v2.xsd => LDEPF.xsd}   |   0
 ...ava => ControlBlockEditorServiceTest.java} | 416 ++++++++++++-----
 .../dto/ControlBlockNetworkSettingsTest.java  | 235 ----------
 .../scl/ied/ControlBlockAdapterTest.java      |  87 +---
 .../commons/util/ControlBlockEnumTest.java    |  41 +-
 .../ControlBlockCommunicationTemplates.csv    |   9 -
 17 files changed, 995 insertions(+), 979 deletions(-)
 create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockEditorService.java
 delete mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java
 delete mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettings.java
 create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ControlService.java
 delete mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockNetworkSettingsCsvHelper.java
 create mode 100644 sct-commons/src/main/resources/xsd/GSE_SMV_CB_COM.xsd
 rename sct-commons/src/main/resources/xsd/{LDEPF_Config_file_v2.xsd => LDEPF.xsd} (100%)
 rename sct-commons/src/test/java/org/lfenergy/compas/sct/commons/{ControlBlockServiceTest.java => ControlBlockEditorServiceTest.java} (52%)
 delete mode 100644 sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java
 delete mode 100644 sct-commons/src/test/resources/ControlBlockCommunicationTemplates.csv

diff --git a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java
index d4aaea1ca..d2e8bd735 100644
--- a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java
+++ b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java
@@ -8,7 +8,7 @@
 import org.junit.jupiter.api.Test;
 import org.lfenergy.compas.scl2007b4.model.LN0;
 import org.lfenergy.compas.scl2007b4.model.SCL;
-import org.lfenergy.compas.sct.commons.ControlBlockService;
+import org.lfenergy.compas.sct.commons.ControlBlockEditorService;
 import org.lfenergy.compas.sct.commons.SclService;
 import org.lfenergy.compas.sct.commons.SubstationService;
 import org.lfenergy.compas.sct.commons.api.ControlBlockEditor;
@@ -16,6 +16,7 @@
 import org.lfenergy.compas.sct.commons.api.SubstationEditor;
 import org.lfenergy.compas.sct.commons.dto.HeaderDTO;
 import org.lfenergy.compas.sct.commons.exception.ScdException;
+import org.lfenergy.compas.sct.commons.scl.ControlService;
 import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
 import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
 import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
@@ -33,7 +34,7 @@ class SclAutomationServiceIntegrationTest {
     private SclAutomationService sclAutomationService ;
     private static final SclEditor sclEditor = new SclService() ;
     private static final SubstationEditor substationEditor = new SubstationService() ;
-    private static final ControlBlockEditor controlBlockEditor = new ControlBlockService() ;
+    private static final ControlBlockEditor controlBlockEditor = new ControlBlockEditorService(new ControlService()) ;
 
     private HeaderDTO headerDTO;
 
diff --git a/sct-commons/pom.xml b/sct-commons/pom.xml
index c807d1237..285b507b1 100644
--- a/sct-commons/pom.xml
+++ b/sct-commons/pom.xml
@@ -185,7 +185,7 @@
                         </goals>
                         <configuration>
                             <sources>
-                                <source>${project.basedir}/src/main/resources/xsd/LDEPF_Config_file_v2.xsd</source>
+                                <source>${project.basedir}/src/main/resources/xsd/LDEPF.xsd</source>
                             </sources>
                             <xjbSources>
                                 <xjbSource>${project.basedir}/src/main/resources/binding_configuration.xjb</xjbSource>
@@ -214,6 +214,23 @@
                             <clearOutputDir>false</clearOutputDir>
                         </configuration>
                     </execution>
+                    <execution>
+                        <id>cbcom</id>
+                        <goals>
+                            <goal>xjc</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.basedir}/src/main/resources/xsd/GSE_SMV_CB_COM.xsd</source>
+                            </sources>
+                            <xjbSources>
+                                <xjbSource>${project.basedir}/src/main/resources/binding_configuration.xjb</xjbSource>
+                            </xjbSources>
+                            <packageName>org.lfenergy.compas.sct.commons.model.cbcom</packageName>
+                            <noPackageLevelAnnotations>true</noPackageLevelAnnotations>
+                            <clearOutputDir>false</clearOutputDir>
+                        </configuration>
+                    </execution>
                 </executions>
             </plugin>
             <plugin>
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockEditorService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockEditorService.java
new file mode 100644
index 000000000..9f01aa8ec
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockEditorService.java
@@ -0,0 +1,430 @@
+// SPDX-FileCopyrightText: 2022 2023 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.lfenergy.compas.scl2007b4.model.*;
+import org.lfenergy.compas.sct.commons.api.ControlBlockEditor;
+import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.exception.ScdException;
+import org.lfenergy.compas.sct.commons.model.cbcom.*;
+import org.lfenergy.compas.sct.commons.scl.ControlService;
+import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
+import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
+import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
+import org.lfenergy.compas.sct.commons.scl.ln.LNAdapter;
+import org.lfenergy.compas.sct.commons.util.ControlBlockEnum;
+import org.lfenergy.compas.sct.commons.util.PrivateUtils;
+import org.lfenergy.compas.sct.commons.util.SclConstructorHelper;
+import org.lfenergy.compas.sct.commons.util.Utils;
+
+import java.math.BigInteger;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newAddress;
+import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newP;
+
+@RequiredArgsConstructor
+public class ControlBlockEditorService implements ControlBlockEditor {
+
+    private static final int MAX_VLAN_ID = 0x0FFF;
+    private static final int MAX_VLAN_PRIORITY = 7;
+    private static final String NONE = "none";
+    private static final String APPID_P_TYPE = "APPID";
+    private static final String MAC_ADDRESS_P_TYPE = "MAC-Address";
+    private static final String VLAN_ID_P_TYPE = "VLAN-ID";
+    private static final String VLAN_PRIORITY_P_TYPE = "VLAN-PRIORITY";
+    private static final int APPID_LENGTH = 4;
+    private static final int VLAN_ID_LENGTH = 3;
+    private static final String MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM = "Error in Control Block communication setting file: vlan is missing attribute ";
+    private final ControlService controlService;
+
+    @Override
+    public List<SclReportItem> analyzeDataGroups(SCL scd) {
+        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+        return sclRootAdapter.streamIEDAdapters()
+                .map(iedAdapter -> {
+                    List<SclReportItem> list = new ArrayList<>();
+                    list.addAll(iedAdapter.checkDataGroupCoherence());
+                    list.addAll(iedAdapter.checkBindingDataGroupCoherence());
+                    return list;
+                }).flatMap(Collection::stream).toList();
+    }
+
+    @Override
+    public List<SclReportItem> createDataSetAndControlBlocks(SCL scd, Set<FcdaForDataSetsCreation> allowedFcdas) {
+        checkFcdaInitDataPresence(allowedFcdas);
+        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+        Stream<LDeviceAdapter> lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters);
+        return createDataSetAndControlBlocks(lDeviceAdapters, allowedFcdas);
+    }
+
+    @Override
+    public List<SclReportItem> createDataSetAndControlBlocks(SCL scd, String targetIedName, Set<FcdaForDataSetsCreation> allowedFcdas) {
+        checkFcdaInitDataPresence(allowedFcdas);
+        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+        IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName);
+        return createDataSetAndControlBlocks(iedAdapter.streamLDeviceAdapters(), allowedFcdas);
+
+    }
+
+    @Override
+    public List<SclReportItem> createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst, Set<FcdaForDataSetsCreation> allowedFcdas) {
+        requireNotBlank(targetIedName, "IED.name parameter is missing");
+        checkFcdaInitDataPresence(allowedFcdas);
+        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+        IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName);
+        LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst);
+        return createDataSetAndControlBlocks(Stream.of(lDeviceAdapter), allowedFcdas);
+    }
+
+    private void checkFcdaInitDataPresence(Set<FcdaForDataSetsCreation> allowedFcdas) {
+        if (allowedFcdas == null || allowedFcdas.isEmpty()) {
+            throw new ScdException("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before");
+        }
+    }
+
+    private List<SclReportItem> createDataSetAndControlBlocks(Stream<LDeviceAdapter> lDeviceAdapters, Set<FcdaForDataSetsCreation> allowedFcdas) {
+        return lDeviceAdapters
+                .map(lDeviceAdapter -> lDeviceAdapter.createDataSetAndControlBlocks(allowedFcdas))
+                .flatMap(List::stream)
+                .toList();
+    }
+
+    @Override
+    public void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final SCL scl) {
+        SclRootAdapter sclRootAdapter = new SclRootAdapter(scl);
+        List<LDeviceAdapter> lDeviceAdapters = sclRootAdapter.streamIEDAdapters()
+                .flatMap(IEDAdapter::streamLDeviceAdapters).toList();
+        // LN0
+        lDeviceAdapters.stream()
+                .map(LDeviceAdapter::getLN0Adapter)
+                .forEach(ln0 -> {
+                    ln0.removeAllControlBlocksAndDatasets();
+                    ln0.removeAllExtRefSourceBindings();
+                });
+        // Other LN
+        lDeviceAdapters.stream()
+                .map(LDeviceAdapter::getLNAdapters).flatMap(List::stream)
+                .forEach(LNAdapter::removeAllControlBlocksAndDatasets);
+    }
+
+    @Override
+    public List<SclReportItem> configureNetworkForAllControlBlocks(SCL scd, CBCom cbCom) {
+        return Stream.concat(
+                        configureNetworkForControlBlocks(scd, cbCom, TCBType.GOOSE),
+                        configureNetworkForControlBlocks(scd, cbCom, TCBType.SV))
+                .toList();
+    }
+
+    private Stream<SclReportItem> configureNetworkForControlBlocks(SCL scl, CBCom cbCom, TCBType tcbType) {
+        CbComSettings cbComSettings;
+        try {
+            cbComSettings = parseCbCom(cbCom, tcbType);
+        } catch (ScdException ex) {
+            return Stream.of(SclReportItem.error("Control Block Communication setting files", ex.getMessage()));
+        }
+        return scl.getIED().stream()
+                .flatMap(tied ->
+                        tied.getAccessPoint()
+                                .stream()
+                                .filter(tAccessPoint -> tAccessPoint.isSetServer() && tAccessPoint.getServer().isSetLDevice())
+                                .flatMap(tAccessPoint -> tAccessPoint.getServer().getLDevice().stream()
+                                        .map(tlDevice -> new IedApLd(tied, tAccessPoint.getName(), tlDevice))
+                                )
+                )
+                .flatMap(iedApLd -> Optional.ofNullable(iedApLd.lDevice().getLN0()).stream()
+                        .flatMap(ln0 -> controlService.getControls(ln0, ControlBlockEnum.from(tcbType).getControlBlockClass()))
+                        .map(tControl -> {
+                            CriteriaOrError criteriaOrError = getCriteria(iedApLd.ied(), tcbType, tControl.getName());
+                            if (criteriaOrError.errorMessage != null) {
+                                return Optional.of(SclReportItem.error(iedApLd.getXPath(), criteriaOrError.errorMessage));
+                            }
+                            Settings settings = cbComSettings.settingsByCriteria.get(criteriaOrError.criteria);
+                            if (settings == null) {
+                                return newError(iedApLd, tControl, "Cannot configure communication for this ControlBlock because: No controlBlock communication settings found with these " + criteriaOrError.criteria);
+                            }
+                            return configureControlBlockNetwork(scl.getCommunication(), settings, cbComSettings.appIdIterator, cbComSettings.macAddressIterator, tControl, iedApLd);
+                        })
+                        .flatMap(Optional::stream)
+                );
+    }
+
+    private CbComSettings parseCbCom(CBCom cbCom, TCBType tcbType) {
+        TRange appIdRange = Optional.ofNullable(cbCom.getAppIdRanges()).map(AppIdRanges::getAppIdRange).stream()
+                .flatMap(Collection::stream)
+                .filter(tRange -> tcbType.equals(tRange.getCBType()))
+                .findFirst()
+                .orElseThrow(() -> new ScdException("Control Block Communication setting files does not contain AppIdRange for cbType " + tcbType.value()));
+        PrimitiveIterator.OfLong appIdIterator = Utils.sequence(Long.parseLong(appIdRange.getStart(), 16), Long.parseLong(appIdRange.getEnd(), 16));
+
+        TRange macRange = Optional.ofNullable(cbCom.getMacRanges()).map(MacRanges::getMacRange).stream()
+                .flatMap(Collection::stream)
+                .filter(tRange -> tcbType.equals(tRange.getCBType()))
+                .findFirst()
+                .orElseThrow(() -> new ScdException("Control Block Communication setting files does not contain MacRange for cbType " + tcbType.value()));
+        Iterator<String> macAddressIterator = Utils.macAddressSequence(macRange.getStart(), macRange.getEnd());
+
+        Map<Criteria, Settings> settingsByCriteria = Optional.ofNullable(cbCom.getVlans()).map(Vlans::getVlan).stream()
+                .flatMap(Collection::stream)
+                .filter(vlan -> tcbType.equals(vlan.getCBType()))
+                .collect(Collectors.toMap(this::vlanToCriteria, this::vlanToSetting));
+
+        return new CbComSettings(appIdIterator, macAddressIterator, settingsByCriteria);
+    }
+
+    private Optional<SclReportItem> configureControlBlockNetwork(TCommunication tCommunication, Settings settings, PrimitiveIterator.OfLong appIdIterator, Iterator<String> macAddressIterator, TControl tControl, IedApLd iedApLd) {
+        if (settings.vlanId() == null) {
+            return newError(iedApLd, tControl, "Cannot configure communication for this ControlBlock because no Vlan Id was provided in the settings");
+        }
+        if (!appIdIterator.hasNext()) {
+            return newError(iedApLd, tControl, "Cannot configure communication for this ControlBlock because range of appId is exhausted");
+        }
+        if (!macAddressIterator.hasNext()) {
+            return newError(iedApLd, tControl, "Cannot configure communication for this ControlBlock because range of MAC Address is exhausted");
+        }
+
+        Optional<TConnectedAP> optConApAdapter = findConnectedAp(tCommunication, iedApLd.ied.getName(), iedApLd.apName);
+        if (optConApAdapter.isEmpty()) {
+            return newError(iedApLd, tControl, "Cannot configure communication for ControlBlock because no ConnectedAP found for AccessPoint");
+        }
+        TConnectedAP tConnectedAP = optConApAdapter.get();
+        List<TP> listOfPs = new ArrayList<>();
+        listOfPs.add(newP(APPID_P_TYPE, Utils.toHex(appIdIterator.nextLong(), APPID_LENGTH)));
+        listOfPs.add(newP(MAC_ADDRESS_P_TYPE, macAddressIterator.next()));
+        listOfPs.add(newP(VLAN_ID_P_TYPE, Utils.toHex(settings.vlanId(), VLAN_ID_LENGTH)));
+        if (settings.vlanPriority() != null) {
+            listOfPs.add(newP(VLAN_PRIORITY_P_TYPE, String.valueOf(settings.vlanPriority())));
+        }
+
+        switch (tControl) {
+            case TGSEControl ignored -> updateGseOrCreateIfNotExists(tConnectedAP, iedApLd.lDevice().getInst(), tControl.getName(), listOfPs, SclConstructorHelper.newDurationInMilliSec(settings.minTime), SclConstructorHelper.newDurationInMilliSec(settings.maxTime));
+            case TSampledValueControl ignored -> updateSmvOrCreateIfNotExists(tConnectedAP, iedApLd.lDevice().getInst(), tControl.getName(), listOfPs);
+            default -> throw new ScdException("Unsupported Control Block type for communication configuration : " + tControl.getClass().getName());
+        }
+        return Optional.empty();
+    }
+
+    private Optional<TConnectedAP> findConnectedAp(TCommunication tCommunication, String iedName, String apName) {
+        if (tCommunication == null || !tCommunication.isSetSubNetwork()) {
+            return Optional.empty();
+        }
+        return tCommunication.getSubNetwork().stream()
+                .filter(TSubNetwork::isSetConnectedAP)
+                .flatMap(tSubNetwork -> tSubNetwork.getConnectedAP().stream())
+                .filter(tConnectedAP -> iedName.equals(tConnectedAP.getIedName()) && apName.equals(tConnectedAP.getApName()))
+                .findFirst();
+    }
+
+    private void updateGseOrCreateIfNotExists(TConnectedAP tConnectedAP, String ldInst, String cbName, List<TP> listOfP, TDurationInMilliSec minTime, TDurationInMilliSec maxTime) {
+        Optional<TGSE> optGse = tConnectedAP.isSetGSE() ?
+                tConnectedAP.getGSE().stream().filter(gse1 -> Objects.equals(ldInst, gse1.getLdInst()) && Objects.equals(cbName, gse1.getCbName())).findFirst()
+                : Optional.empty();
+        TGSE gse = optGse
+                .orElseGet(() -> {
+                            TGSE newGse = new TGSE();
+                            newGse.setLdInst(ldInst);
+                            newGse.setCbName(cbName);
+                            tConnectedAP.getGSE().add(newGse);
+                            return newGse;
+                        }
+                );
+        gse.setAddress(newAddress(listOfP));
+        gse.setMinTime(minTime);
+        gse.setMaxTime(maxTime);
+    }
+
+    /**
+     * Create A SMV Section or update an existing SMV Section (the network configuration of a SampledValueControl block)..
+     */
+    private void updateSmvOrCreateIfNotExists(TConnectedAP tConnectedAP, String ldInst, String cbName, List<TP> listOfP) {
+        Optional<TSMV> optSmv = tConnectedAP.isSetSMV() ?
+                tConnectedAP.getSMV().stream().filter(smv1 -> Objects.equals(ldInst, smv1.getLdInst()) && Objects.equals(cbName, smv1.getCbName())).findFirst()
+                : Optional.empty();
+        TSMV smv = optSmv
+                .orElseGet(() -> {
+                            TSMV newSmv = new TSMV();
+                            newSmv.setLdInst(ldInst);
+                            newSmv.setCbName(cbName);
+                            tConnectedAP.getSMV().add(newSmv);
+                            return newSmv;
+                        }
+                );
+        smv.setAddress(newAddress(listOfP));
+    }
+
+    private static Optional<SclReportItem> newError(IedApLd iedApLd, TControl tControl, String message) {
+        return Optional.of(SclReportItem.error(iedApLd.getXPath() + "/LN0/" + controlBlockXPath(tControl),
+                message));
+    }
+
+    private static String controlBlockXPath(TControl tControl) {
+        return ControlBlockEnum.from(tControl.getClass()).getElementName() + "[@name=\"" + tControl.getName() + "\"]";
+    }
+
+    public CriteriaOrError getCriteria(TIED tied, TCBType cbType, String cbName) {
+        Optional<TCompasSystemVersion> compasSystemVersion = PrivateUtils.extractCompasPrivate(tied, TCompasSystemVersion.class);
+        if (compasSystemVersion.isEmpty()) {
+            return new CriteriaOrError(null, "No private COMPAS-SystemVersion found in this IED");
+        }
+        if (StringUtils.isBlank(compasSystemVersion.get().getMainSystemVersion())
+                || (StringUtils.isBlank(compasSystemVersion.get().getMinorSystemVersion()))) {
+            return new CriteriaOrError(null, "Missing MainSystemVersion or MinorSystemVersion attribute in COMPAS-SystemVersion private of IED");
+        }
+        String systemVersionWithoutV = removeVFromSystemVersion(compasSystemVersion.get());
+        Optional<TCompasICDHeader> compasICDHeader = PrivateUtils.extractCompasPrivate(tied, TCompasICDHeader.class);
+        if (compasICDHeader.isEmpty()) {
+            return new CriteriaOrError(null, "No private COMPAS-ICDHeader found in this IED");
+        }
+        if (compasICDHeader.get().getIEDSystemVersioninstance() == null) {
+            return new CriteriaOrError(null, "No IEDSystemVersioninstance in the COMPAS-ICDHeader of this IED");
+        }
+        TBayIntOrExt bayIntOrExt = cbName.endsWith("I") ? TBayIntOrExt.BAY_INTERNAL : TBayIntOrExt.BAY_EXTERNAL;
+
+        return new CriteriaOrError(
+                new Criteria(cbType,
+                        systemVersionWithoutV,
+                        TIEDType.fromValue(compasICDHeader.get().getIEDType().value()),
+                        TIEDRedundancy.fromValue(compasICDHeader.get().getIEDredundancy().value()),
+                        compasICDHeader.get().getIEDSystemVersioninstance(),
+                        bayIntOrExt), null);
+    }
+
+    private String removeVFromSystemVersion(TCompasSystemVersion compasSystemVersion) {
+        String[] minorVersionParts = compasSystemVersion.getMinorSystemVersion().split("\\.");
+        return (minorVersionParts.length == 3) ?
+                compasSystemVersion.getMainSystemVersion() + "." + minorVersionParts[0] + "." + minorVersionParts[1]
+                : null;
+    }
+
+    private Criteria vlanToCriteria(TVlan vlan) {
+        requireNotNull(vlan.getCBType(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "CBType");
+        requireNotBlank(vlan.getXY(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "XY");
+        requireNotBlank(vlan.getZW(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "ZW");
+        requireNotNull(vlan.getIEDType(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "IEDType");
+        requireNotNull(vlan.getIEDRedundancy(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "IEDRedundancy");
+        requireNotBlank(vlan.getIEDSystemVersionInstance(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "IEDSystemVersionInstance");
+        requireNotNull(vlan.getBayIntOrExt(), MISSING_ATTRIBUTE_IN_GSE_SMV_CB_COM + "BayIntOrExt");
+
+        return new Criteria(
+                vlan.getCBType(),
+                vlan.getXY() + "." + vlan.getZW(),
+                vlan.getIEDType(),
+                vlan.getIEDRedundancy(),
+                toIedSystemVersionInstance(vlan.getIEDSystemVersionInstance()),
+                vlan.getBayIntOrExt()
+        );
+    }
+
+    private Settings vlanToSetting(TVlan vlan) {
+        return new Settings(toVLanId(vlan.getVlanId()), toVlanPriority(vlan.getVlanPriority()), toDurationInMilliSec(vlan.getMinTime()), toDurationInMilliSec(vlan.getMaxTime()));
+    }
+
+    private void requireNotBlank(String str, String message) {
+        if (StringUtils.isBlank(str)) {
+            throw new ScdException(message);
+        }
+    }
+
+    private void requireNotNull(Object o, String message) {
+        if (Objects.isNull(o)) {
+            throw new ScdException(message);
+        }
+    }
+
+    private BigInteger toIedSystemVersionInstance(String strIedSystemVersionInstance) {
+        if (StringUtils.isBlank(strIedSystemVersionInstance)) {
+            return null;
+        }
+        BigInteger iedSystemVersionInstance;
+        try {
+            iedSystemVersionInstance = new BigInteger(strIedSystemVersionInstance);
+        } catch (NumberFormatException e) {
+            throw new ScdException("Error in Control Block communication setting file: IED System Version Instance must be an integer, but got : %s".formatted(strIedSystemVersionInstance));
+        }
+        return iedSystemVersionInstance;
+    }
+
+    private Integer toVLanId(String strVlanId) {
+        if (StringUtils.isBlank(strVlanId) || NONE.equalsIgnoreCase(strVlanId)) {
+            return null;
+        }
+        int vlanId;
+        try {
+            vlanId = Integer.parseInt(strVlanId);
+        } catch (NumberFormatException e) {
+            throw new ScdException("Error in Control Block communication setting file: VLAN ID must be an integer or '%s', but got : %s".formatted(NONE, strVlanId));
+        }
+        if (vlanId < 0 || vlanId > MAX_VLAN_ID) {
+            throw new ScdException("Error in Control Block communication setting file: VLAN ID must be between 0 and %d, but got : %s".formatted(MAX_VLAN_ID, strVlanId));
+        }
+        return vlanId;
+    }
+
+    private static Byte toVlanPriority(String strVlanPriority) {
+        if (StringUtils.isBlank(strVlanPriority) || NONE.equalsIgnoreCase(strVlanPriority)) {
+            return null;
+        }
+        byte vlanPriority;
+        try {
+            vlanPriority = Byte.parseByte(strVlanPriority);
+        } catch (NumberFormatException e) {
+            throw new ScdException("Error in Control Block communication setting file: VLAN Priority must be an integer or '%s', but got : %s".formatted(NONE, strVlanPriority));
+        }
+        if (vlanPriority < 0 || vlanPriority > MAX_VLAN_PRIORITY) {
+            throw new ScdException("Error in Control Block communication setting file: VLAN PRIORITY must be between 0 and %d, but got : %s".formatted(MAX_VLAN_PRIORITY, strVlanPriority));
+        }
+        return vlanPriority;
+    }
+
+    private TDurationInMilliSec toDurationInMilliSec(String strDuration) {
+        if (StringUtils.isBlank(strDuration) || NONE.equalsIgnoreCase(strDuration)) {
+            return null;
+        }
+        long duration;
+        try {
+            duration = Long.parseLong(strDuration);
+        } catch (NumberFormatException e) {
+            throw new ScdException("Error in Control Block communication setting file: VLAN MinTime and MaxTime must be an integer or '%s', but got : %s".formatted(NONE, strDuration));
+        }
+        return SclConstructorHelper.newDurationInMilliSec(duration);
+    }
+
+    /**
+     * Key to search for a control block communication setting
+     */
+    public record Criteria(TCBType cbType, String systemVersionWithoutV, TIEDType iedType, TIEDRedundancy iedRedundancy, BigInteger iedSystemVersionInstance, TBayIntOrExt bayIntOrExt) {
+    }
+
+    /**
+     * Communication settings for ControlBlock or Error message
+     */
+    public record CriteriaOrError(Criteria criteria, String errorMessage) {
+    }
+
+    /**
+     * Communication settings for ControlBlock
+     */
+    public record Settings(Integer vlanId, Byte vlanPriority, TDurationInMilliSec minTime, TDurationInMilliSec maxTime) {
+    }
+
+    /**
+     * All settings of CbCom in a useful format
+     */
+    record CbComSettings(PrimitiveIterator.OfLong appIdIterator, Iterator<String> macAddressIterator, Map<Criteria, Settings> settingsByCriteria) {
+    }
+
+    record IedApLd(TIED ied, String apName, TLDevice lDevice) {
+        String getXPath() {
+            return """
+                    /SCL/IED[@name="%s"]/AccessPoint[@name="%s"]/Server/LDevice[@inst="%s"]""".formatted(ied.getName(), apName, lDevice.getInst());
+        }
+
+    }
+}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java
deleted file mode 100644
index 5f28d9e61..000000000
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ControlBlockService.java
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-FileCopyrightText: 2022 2023 RTE FRANCE
-//
-// SPDX-License-Identifier: Apache-2.0
-
-package org.lfenergy.compas.sct.commons;
-
-import org.apache.commons.lang3.StringUtils;
-import org.lfenergy.compas.scl2007b4.model.SCL;
-import org.lfenergy.compas.sct.commons.api.ControlBlockEditor;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.NetworkRanges;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.RangesPerCbType;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.Settings;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.SettingsOrError;
-import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation;
-import org.lfenergy.compas.sct.commons.dto.SclReportItem;
-import org.lfenergy.compas.sct.commons.exception.ScdException;
-import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
-import org.lfenergy.compas.sct.commons.scl.ied.ControlBlockAdapter;
-import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
-import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
-import org.lfenergy.compas.sct.commons.scl.ln.LNAdapter;
-import org.lfenergy.compas.sct.commons.util.ControlBlockEnum;
-import org.lfenergy.compas.sct.commons.util.Utils;
-
-import java.util.*;
-import java.util.stream.Stream;
-
-public class ControlBlockService implements ControlBlockEditor {
-
-
-    @Override
-    public List<SclReportItem> analyzeDataGroups(SCL scd) {
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        return sclRootAdapter.streamIEDAdapters()
-                .map(iedAdapter -> {
-                    List<SclReportItem> list = new ArrayList<>();
-                    list.addAll(iedAdapter.checkDataGroupCoherence());
-                    list.addAll(iedAdapter.checkBindingDataGroupCoherence());
-                    return list;
-                }).flatMap(Collection::stream).toList();
-    }
-
-    @Override
-    public List<SclReportItem> createDataSetAndControlBlocks(SCL scd, Set<FcdaForDataSetsCreation> allowedFcdas) {
-        checkFcdaInitDataPresence(allowedFcdas);
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        Stream<LDeviceAdapter> lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters);
-        return createDataSetAndControlBlocks(lDeviceAdapters, allowedFcdas);
-    }
-
-    @Override
-    public List<SclReportItem> createDataSetAndControlBlocks(SCL scd, String targetIedName, Set<FcdaForDataSetsCreation> allowedFcdas) {
-        checkFcdaInitDataPresence(allowedFcdas);
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName);
-        return createDataSetAndControlBlocks(iedAdapter.streamLDeviceAdapters(), allowedFcdas);
-
-    }
-
-    @Override
-    public List<SclReportItem> createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst, Set<FcdaForDataSetsCreation> allowedFcdas) {
-        if (StringUtils.isBlank(targetIedName)) {
-            throw new ScdException("IED.name parameter is missing");
-        }
-        checkFcdaInitDataPresence(allowedFcdas);
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName);
-        LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst);
-        return createDataSetAndControlBlocks(Stream.of(lDeviceAdapter), allowedFcdas);
-    }
-
-    private void checkFcdaInitDataPresence(Set<FcdaForDataSetsCreation> allowedFcdas) {
-        if (allowedFcdas == null || allowedFcdas.isEmpty()) {
-            throw new ScdException("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before");
-        }
-    }
-
-    private List<SclReportItem> createDataSetAndControlBlocks(Stream<LDeviceAdapter> lDeviceAdapters, Set<FcdaForDataSetsCreation> allowedFcdas) {
-        return lDeviceAdapters
-                .map(lDeviceAdapter -> lDeviceAdapter.createDataSetAndControlBlocks(allowedFcdas))
-                .flatMap(List::stream)
-                .toList();
-    }
-
-    @Override
-    public List<SclReportItem> configureNetworkForAllControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings,
-                                                                   RangesPerCbType rangesPerCbType) {
-        List<SclReportItem> sclReportItems = new ArrayList<>();
-        sclReportItems.addAll(configureNetworkForControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType.gse(), ControlBlockEnum.GSE));
-        sclReportItems.addAll(configureNetworkForControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType.sampledValue(), ControlBlockEnum.SAMPLED_VALUE));
-        return sclReportItems;
-    }
-
-    @Override
-    public void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final SCL scl) {
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scl);
-        List<LDeviceAdapter> lDeviceAdapters = sclRootAdapter.streamIEDAdapters()
-                .flatMap(IEDAdapter::streamLDeviceAdapters).toList();
-        // LN0
-        lDeviceAdapters.stream()
-                .map(LDeviceAdapter::getLN0Adapter)
-                .forEach(ln0 -> {
-                    ln0.removeAllControlBlocksAndDatasets();
-                    ln0.removeAllExtRefSourceBindings();
-                });
-        // Other LN
-        lDeviceAdapters.stream()
-                .map(LDeviceAdapter::getLNAdapters).flatMap(List::stream)
-                .forEach(LNAdapter::removeAllControlBlocksAndDatasets);
-    }
-
-
-    private List<SclReportItem> configureNetworkForControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings,
-                                                                 NetworkRanges networkRanges, ControlBlockEnum controlBlockEnum) {
-        PrimitiveIterator.OfLong appIdIterator = Utils.sequence(networkRanges.appIdStart(), networkRanges.appIdEnd());
-        Iterator<String> macAddressIterator = Utils.macAddressSequence(networkRanges.macAddressStart(), networkRanges.macAddressEnd());
-
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        return sclRootAdapter.streamIEDAdapters()
-                .flatMap(iedAdapter ->
-                        iedAdapter.streamLDeviceAdapters()
-                                .filter(LDeviceAdapter::hasLN0)
-                                .map(LDeviceAdapter::getLN0Adapter)
-                                .flatMap(ln0Adapter -> ln0Adapter.streamControlBlocks(controlBlockEnum))
-                                .map(controlBlockAdapter -> configureControlBlockNetwork(controlBlockNetworkSettings, appIdIterator, macAddressIterator, controlBlockAdapter)))
-                .flatMap(Optional::stream)
-                .toList();
-    }
-
-    private Optional<SclReportItem> configureControlBlockNetwork(ControlBlockNetworkSettings controlBlockNetworkSettings, PrimitiveIterator.OfLong appIdIterator, Iterator<String> macAddressIterator, ControlBlockAdapter controlBlockAdapter) {
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-        if (settingsOrError.errorMessage() != null) {
-            return Optional.of(controlBlockAdapter.buildFatalReportItem(
-                    "Cannot configure network for this ControlBlock because: " + settingsOrError.errorMessage()));
-        }
-        Settings settings = settingsOrError.settings();
-        if (settings == null) {
-            return Optional.of(controlBlockAdapter.buildFatalReportItem(
-                    "Cannot configure network for this ControlBlock because no settings was provided"));
-        }
-        if (settings.vlanId() == null) {
-            return Optional.of(controlBlockAdapter.buildFatalReportItem(
-                    "Cannot configure network for this ControlBlock because no Vlan Id was provided in the settings"));
-        }
-        if (!appIdIterator.hasNext()) {
-            return Optional.of(controlBlockAdapter.buildFatalReportItem(
-                    "Cannot configure network for this ControlBlock because range of appId is exhausted"));
-        }
-        if (!macAddressIterator.hasNext()) {
-            return Optional.of(controlBlockAdapter.buildFatalReportItem(
-                    "Cannot configure network for this ControlBlock because range of MAC Address is exhausted"));
-        }
-
-        return controlBlockAdapter.configureNetwork(appIdIterator.nextLong(), macAddressIterator.next(), settings.vlanId(), settings.vlanPriority(),
-                settings.minTime(), settings.maxTime());
-    }
-
-}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java
index 7406c23c3..8235dd5ea 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ControlBlockEditor.java
@@ -6,9 +6,9 @@
 
 import org.lfenergy.compas.scl2007b4.model.SCL;
 import org.lfenergy.compas.scl2007b4.model.TExtRef;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings;
 import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation;
 import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.model.cbcom.CBCom;
 import org.lfenergy.compas.sct.commons.util.Utils;
 
 import java.util.List;
@@ -22,7 +22,7 @@
  *   <ol>
  *      <li>{@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, Set) <em>Create DataSet and ControlBlock based on the <b>TExtRef</b></em>}</li>
  *      <li>{@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, String, Set) <em>Create DataSet and ControlBlock based on the <b>TExtRef</b> in given <b>IED</b></em>}</li>
- *      <li>{@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, String,String, Set) <em>Create DataSet and ControlBlock based on the <b>TExtRef</b> in given <b>IED</b> and <b>LDevice</b></em>}</li>
+ *      <li>{@link ControlBlockEditor#createDataSetAndControlBlocks(SCL, String, String, Set) <em>Create DataSet and ControlBlock based on the <b>TExtRef</b> in given <b>IED</b> and <b>LDevice</b></em>}</li>
  *      <li>{@link ControlBlockEditor#configureNetworkForAllControlBlocks <em>Configure the network for the <b>ControlBlocks</b></em>}</li>
  *      <li>{@link ControlBlockEditor#removeAllControlBlocksAndDatasetsAndExtRefSrcBindings <em>Removes all ControlBlocks and DataSets for all LNs in <b>SCL</b></em>}</li>
  *      <li>{@link ControlBlockEditor#analyzeDataGroups(SCL)} <em>Checks Control Blocks, DataSets and FCDA number limitation into Access Points </em>}</li>
@@ -85,17 +85,11 @@ public interface ControlBlockEditor {
      * - the Communication/SubNetwork/ConnectedAP/GSE element, for the GSEControl blocks
      * - the Communication/SubNetwork/ConnectedAP/SMV element, for the SampledValueControl blocks
      *
-     * @param scd                         input SCD object. The object will be modified with the new DataGSESet and SMV elements
-     * @param controlBlockNetworkSettings a method tha gives the network configuration information for a given ControlBlock
-     * @param rangesPerCbType             provide NetworkRanges for GSEControl and SampledValueControl. NetworkRanges contains :
-     *                                    start-end app APPID range (long value), start-end MAC-Addresses (Mac-Addresses values: Ex: "01-0C-CD-01-01-FF")
+     * @param scd   input SCD object. The object will be modified with the new GSE and SMV elements
+     * @param cbCom communication settings to configure Control Block Communication
      * @return list of encountered errors
      * @see Utils#macAddressToLong(String) for the expected MAC address format
-     * @see ControlBlockNetworkSettings
-     * @see ControlBlockNetworkSettings.RangesPerCbType
-     * @see ControlBlockNetworkSettings.NetworkRanges
      */
-    List<SclReportItem> configureNetworkForAllControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings,
-                                                            ControlBlockNetworkSettings.RangesPerCbType rangesPerCbType);
+    List<SclReportItem> configureNetworkForAllControlBlocks(SCL scd, CBCom cbCom);
 
 }
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettings.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettings.java
deleted file mode 100644
index 65fcb11f3..000000000
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettings.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// SPDX-FileCopyrightText: 2023 RTE FRANCE
-//
-// SPDX-License-Identifier: Apache-2.0
-
-package org.lfenergy.compas.sct.commons.dto;
-
-import org.lfenergy.compas.scl2007b4.model.TDurationInMilliSec;
-import org.lfenergy.compas.sct.commons.scl.ied.ControlBlockAdapter;
-
-/**
- * This interface has a single method which provides network settings for a ControlBlock.
- * These are used to create:
- * - the Communication/SubNetwork/ConnectedAP/GSE element, which is the network configuration of a GSEControl block
- * - the Communication/SubNetwork/ConnectedAP/SMV element, which is the network configuration  of a SampledValueControl block
- * It is a FunctionalInterface, so it can be implemented with a lambda expression.
- *
- * @see org.lfenergy.compas.sct.commons.util.ControlBlockNetworkSettingsCsvHelper
- */
-@FunctionalInterface
-public interface ControlBlockNetworkSettings {
-
-    /**
-     * This method provides a vlanId, vlanPriority, minTime, maxTime for this ControlBlock.
-     * vlanPriority will be ignored when vlanId is null.
-     *
-     * @param controlBlockAdapter ControlBlock for which we want to configure the communication section
-     * @return network settings to use for configuring Communication section for this ControlBlock.
-     * An error message can be provided (i.e. errorMessage not null) or a null settings, in order to avoid configuring the ControlBlock.
-     */
-    SettingsOrError getNetworkSettings(ControlBlockAdapter controlBlockAdapter);
-
-    /**
-     * Network settings for ControlBlock communication
-     *
-     * @param vlanId       id of the vlan
-     * @param vlanPriority priority for the vlan
-     * @param minTime      minTime for GSE communication element
-     * @param maxTime      maxTime for GSE communication element
-     */
-    record Settings(Integer vlanId, Byte vlanPriority, TDurationInMilliSec minTime, TDurationInMilliSec maxTime) {
-    }
-
-    /**
-     * Network settings for ControlBlock communication or Error message
-     *
-     * @param settings     Network settings for ControlBlock communication. Can be null when errorMessage is provided
-     * @param errorMessage should be null if settings is provided
-     */
-    record SettingsOrError(Settings settings, String errorMessage) {
-    }
-
-    /**
-     * NetworkRanges for GSEControl and SampledValueControl
-     *
-     * @param gse          NetworkRanges for GSEControl
-     * @param sampledValue NetworkRanges for SampledValueControl
-     */
-    record RangesPerCbType(NetworkRanges gse, NetworkRanges sampledValue) {
-    }
-
-    /**
-     * Range of APPID and range of MAC-Address
-     *
-     * @param appIdStart      range start for APPID (inclusive)
-     * @param appIdEnd        range end for APPID (inclusive)
-     * @param macAddressStart range start for MAC-Addresses (inclusive). Ex: "01-0C-CD-01-00-00"
-     * @param macAddressEnd   range end for MAC-Addresses (inclusive). Ex: "01-0C-CD-01-01-FF"
-     */
-    record NetworkRanges(long appIdStart, long appIdEnd, String macAddressStart, String macAddressEnd) {
-    }
-}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ControlService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ControlService.java
new file mode 100644
index 000000000..c1904d913
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ControlService.java
@@ -0,0 +1,26 @@
+// SPDX-FileCopyrightText: 2023 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons.scl;
+
+import org.lfenergy.compas.scl2007b4.model.*;
+
+import java.util.stream.Stream;
+
+public class ControlService {
+
+    public <T extends TControl> Stream<T> getControls(TAnyLN tAnyLN, Class<T> tControlClass){
+        if (tControlClass == TGSEControl.class && tAnyLN instanceof TLN0 tln0 && tln0.isSetGSEControl()){
+            return tln0.getGSEControl().stream().map(tControlClass::cast);
+        } else if (tControlClass == TSampledValueControl.class && tAnyLN instanceof TLN0 tln0 && tln0.isSetSampledValueControl()){
+            return tln0.getSampledValueControl().stream().map(tControlClass::cast);
+        } else if (tControlClass == TReportControl.class && tAnyLN.isSetReportControl()){
+            return tAnyLN.getReportControl().stream().map(tControlClass::cast);
+        } else if (tControlClass == TLogControl.class){
+            return tAnyLN.getLogControl().stream().map(tControlClass::cast);
+        }
+        return Stream.empty();
+    }
+
+}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapter.java
index 6902f2f5e..f6c539def 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapter.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapter.java
@@ -7,21 +7,10 @@
 
 import org.lfenergy.compas.scl2007b4.model.*;
 import org.lfenergy.compas.sct.commons.dto.ControlBlockTarget;
-import org.lfenergy.compas.sct.commons.dto.SclReportItem;
 import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
-import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
-import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter;
-import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
 import org.lfenergy.compas.sct.commons.scl.ln.AbstractLNAdapter;
 import org.lfenergy.compas.sct.commons.util.ControlBlockEnum;
-import org.lfenergy.compas.sct.commons.util.Utils;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newDurationInMilliSec;
-import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newP;
 import static org.lfenergy.compas.sct.commons.util.Utils.xpathAttributeFilter;
 
 /**
@@ -52,12 +41,6 @@
 public class ControlBlockAdapter extends SclElementAdapter<AbstractLNAdapter<? extends TAnyLN>, TControl> {
 
     private static final long RPT_ENABLED_MAX_DEFAULT = 1L;
-    private static final String APPID_P_TYPE = "APPID";
-    private static final String MAC_ADDRESS_P_TYPE = "MAC-Address";
-    private static final String VLAN_ID_P_TYPE = "VLAN-ID";
-    private static final String VLAN_PRIORITY_P_TYPE = "VLAN-PRIORITY";
-    private static final int APPID_LENGTH = 4;
-    private static final int VLAN_ID_LENGTH = 3;
 
     public ControlBlockAdapter(AbstractLNAdapter<? extends TAnyLN> parentAdapter, TControl tControl) {
         super(parentAdapter, tControl);
@@ -128,67 +111,4 @@ public void addTargetIfNotExists(AbstractLNAdapter<?> targetLn) {
         }
     }
 
-    /**
-     * Configure the Communication section for this ControlBlock
-     *  - Communication/SubNetwork/ConnectedAP/GSE for GSEControl block
-     *  - Communication/SubNetwork/ConnectedAP/SMV for SampledValueControl block
-     * @param appId value for P type APPID
-     * @param macAddress value for P type MAC-Address
-     * @param vlanId value for P type VLAN-ID
-     * @param vlanPriority value for P type VLAN-PRIORITY
-     * @param minTime MinTime Element
-     * @param maxTime MaxTime Element
-     * @return An empty Optional if network have been configured, else a SclReportItem.
-     */
-    public Optional<SclReportItem> configureNetwork(long appId, String macAddress, Integer vlanId, Byte vlanPriority, TDurationInMilliSec minTime,
-                                                    TDurationInMilliSec maxTime) {
-        String accessPointName = getParentLDeviceAdapter().getAccessPoint().getName();
-
-        Optional<ConnectedAPAdapter> optConApAdapter = getSclRootAdapter().findConnectedApAdapter(getParentIedAdapter().getName(), accessPointName);
-        if (optConApAdapter.isEmpty()) {
-            return Optional.of(buildFatalReportItem("Cannot configure network for ControlBlock because no ConnectAP found for parent AccessPoint"));
-        }
-        ConnectedAPAdapter connectedAPAdapter = optConApAdapter.get();
-        List<TP> listOfPs = new ArrayList<>();
-        listOfPs.add(newP(APPID_P_TYPE, Utils.toHex(appId, APPID_LENGTH)));
-        listOfPs.add(newP(MAC_ADDRESS_P_TYPE, macAddress));
-        if (vlanId != null) {
-            listOfPs.add(newP(VLAN_ID_P_TYPE, Utils.toHex(vlanId, VLAN_ID_LENGTH)));
-            if (vlanPriority != null) {
-                listOfPs.add(newP(VLAN_PRIORITY_P_TYPE, String.valueOf(vlanPriority)));
-            }
-        }
-        switch (getControlBlockEnum()) {
-            case GSE -> connectedAPAdapter.updateGseOrCreateIfNotExists(getParentLDeviceAdapter().getInst(), currentElem.getName(), listOfPs, newDurationInMilliSec(minTime), newDurationInMilliSec(maxTime));
-            case SAMPLED_VALUE -> connectedAPAdapter.updateSmvOrCreateIfNotExists(getParentLDeviceAdapter().getInst(), currentElem.getName(), listOfPs);
-            default -> {
-                return Optional.of(buildFatalReportItem("configureNetwork not yet implemented for %s ControlBlocks".formatted(getControlBlockEnum())));
-            }
-        }
-        return Optional.empty();
-    }
-
-    /**
-     * Get parent LDevice
-     * @return ControlBlock's parent lDeviceAdapter
-     */
-    private LDeviceAdapter getParentLDeviceAdapter() {
-        return getParentAdapter().getParentAdapter();
-    }
-
-    /**
-     * Get parent IED
-     * @return ControlBlock's parent IEDAdapter
-     */
-    public IEDAdapter getParentIedAdapter() {
-        return getParentAdapter().getParentIed();
-    }
-
-    /**
-     * Get SCL Root
-     * @return sclRootAdapter
-     */
-    private SclRootAdapter getSclRootAdapter() {
-        return getParentIedAdapter().getParentAdapter();
-    }
 }
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnum.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnum.java
index 23cb0bbcb..025b14992 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnum.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnum.java
@@ -5,23 +5,23 @@
 package org.lfenergy.compas.sct.commons.util;
 
 import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import org.lfenergy.compas.scl2007b4.model.*;
+import org.lfenergy.compas.sct.commons.model.cbcom.TCBType;
 
 import java.util.Arrays;
 import java.util.Objects;
 
 @Getter
+@RequiredArgsConstructor
 public enum ControlBlockEnum {
-    GSE(TGSEControl.class),
-    SAMPLED_VALUE(TSampledValueControl.class),
-    REPORT(TReportControl.class),
-    LOG(TLogControl.class);
+    GSE(TGSEControl.class, "GSEControl"),
+    SAMPLED_VALUE(TSampledValueControl.class, "SampledValueControl"),
+    REPORT(TReportControl.class, "ReportControl"),
+    LOG(TLogControl.class, "LogControl");
 
     private final Class<? extends TControl> controlBlockClass;
-
-    ControlBlockEnum(Class<? extends TControl> controlBlockClass) {
-        this.controlBlockClass = controlBlockClass;
-    }
+    private final String elementName;
 
     public static ControlBlockEnum from(TServiceType tServiceType) {
         Objects.requireNonNull(tServiceType);
@@ -40,4 +40,12 @@ public static ControlBlockEnum from(Class<? extends TControl> tControlClass) {
             .orElseThrow(() -> new IllegalArgumentException("Unsupported TControl class : " + tControlClass.getSimpleName()));
     }
 
+    public static ControlBlockEnum from(TCBType tcbType) {
+        return switch (tcbType){
+            case GOOSE -> GSE;
+            case SV -> SAMPLED_VALUE;
+            default -> throw new IllegalArgumentException("Unsupported TCBType: " + tcbType);
+        };
+    }
+
 }
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockNetworkSettingsCsvHelper.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockNetworkSettingsCsvHelper.java
deleted file mode 100644
index dc4b2ff6a..000000000
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ControlBlockNetworkSettingsCsvHelper.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// SPDX-FileCopyrightText: 2023 RTE FRANCE
-//
-// SPDX-License-Identifier: Apache-2.0
-
-package org.lfenergy.compas.sct.commons.util;
-
-import com.opencsv.bean.CsvBindByPosition;
-import lombok.ToString;
-import org.apache.commons.lang3.StringUtils;
-import org.lfenergy.compas.scl2007b4.model.*;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings;
-import org.lfenergy.compas.sct.commons.scl.ied.ControlBlockAdapter;
-import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
-
-import java.io.Reader;
-import java.math.BigInteger;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-/**
- * This class is an implementation example for interface ControlBlockNetworkSettings.
- * It relies on a CSV file.
- * The first columns of the CSV file are the criteria to match the ControlBlock (controlBlockEnum, systemVersionWithoutV, iedType, iedRedundancy,
- * isBayInternal),
- * The last columns are the network settings for the matched ControlBlock (as described in {@link ControlBlockNetworkSettings.Settings}).
- *
- * @see CsvUtils
- */
-public class ControlBlockNetworkSettingsCsvHelper implements ControlBlockNetworkSettings {
-
-    private static final int MAX_VLAN_ID = 0x0FFF;
-    private static final int MAX_VLAN_PRIORITY = 7;
-    private static final String NONE = "none";
-
-    private final Map<Criteria, Settings> allSettings;
-
-    /**
-     * Constructor
-     * Provide the CSV file as a Reader. For example, you can create a reader like this :
-     * <code>new InputStreamReader(getClass().getClassLoader().getResourceAsStream(fileName), StandardCharsets.UTF_8);</code>
-     *
-     * @param csvSource a reader that provides the data as CSV. For example :
-     */
-    public ControlBlockNetworkSettingsCsvHelper(Reader csvSource) {
-        allSettings = readCsvFile(csvSource);
-    }
-
-    private Map<Criteria, Settings> readCsvFile(Reader csvSource) {
-        return CsvUtils.parseRows(csvSource, Row.class).stream()
-                .distinct()
-                .collect(Collectors.toMap(
-                        ControlBlockNetworkSettingsCsvHelper::rowToCriteria,
-                        ControlBlockNetworkSettingsCsvHelper::rowToSetting
-                ));
-    }
-
-    @Override
-    public SettingsOrError getNetworkSettings(ControlBlockAdapter controlBlockAdapter) {
-        ControlBlockEnum controlBlockEnum = controlBlockAdapter.getControlBlockEnum();
-        IEDAdapter iedAdapter = controlBlockAdapter.getParentIedAdapter();
-        Optional<TCompasSystemVersion> compasSystemVersion = iedAdapter.getCompasSystemVersion();
-        if (compasSystemVersion.isEmpty()) {
-            return new SettingsOrError(null, "No private COMPAS-SystemVersion found in this IED");
-        }
-        String systemVersionWithoutV = removeVFromSystemVersion(compasSystemVersion.get());
-        Optional<TCompasICDHeader> compasICDHeader = iedAdapter.getCompasICDHeader();
-        if (compasICDHeader.isEmpty()) {
-            return new SettingsOrError(null, "No private COMPAS-ICDHeader found in this IED");
-        }
-        TCompasIEDType iedType = compasICDHeader.get().getIEDType();
-        TCompasIEDRedundancy iedRedundancy = compasICDHeader.get().getIEDredundancy();
-        BigInteger iedSystemVersionInstance = compasICDHeader.get().getIEDSystemVersioninstance();
-        boolean isBayInternal = controlBlockAdapter.getName().endsWith("I");
-
-        Criteria criteria = new Criteria(controlBlockEnum, systemVersionWithoutV, iedType, iedRedundancy, iedSystemVersionInstance, isBayInternal);
-        Settings settings = findSettings(criteria);
-        return settings != null ?
-                new SettingsOrError(settings, null) :
-                new SettingsOrError(null, "No row found with these criteria " + criteria);
-    }
-
-    private Settings findSettings(Criteria criteria) {
-        Objects.requireNonNull(criteria);
-        if (criteria.systemVersionWithoutV() == null
-                || criteria.iedType() == null
-                || criteria.iedRedundancy() == null
-                || criteria.iedSystemVersionInstance == null) {
-            return null;
-        }
-        return allSettings.get(criteria);
-    }
-
-    private static String removeVFromSystemVersion(TCompasSystemVersion compasSystemVersion) {
-        if (StringUtils.isBlank(compasSystemVersion.getMainSystemVersion())
-                || (StringUtils.isBlank(compasSystemVersion.getMinorSystemVersion()))) {
-            return null;
-        }
-        String[] minorVersionParts = compasSystemVersion.getMinorSystemVersion().split("\\.");
-        return (minorVersionParts.length == 3) ?
-                compasSystemVersion.getMainSystemVersion() + "." + minorVersionParts[0] + "." + minorVersionParts[1]
-                : null;
-    }
-
-    private static Criteria rowToCriteria(Row row) {
-        if (StringUtils.isBlank(row.cbType)
-                || StringUtils.isBlank(row.xy)
-                || StringUtils.isBlank(row.zw)
-                || StringUtils.isBlank(row.iedType)
-                || StringUtils.isBlank(row.iedRedundancy)
-                || StringUtils.isBlank(row.iedSystemVersionInstance)
-                || StringUtils.isBlank(row.bindingType)
-        ) {
-            throw new IllegalArgumentException("At least one criteria is null in row " + row);
-        }
-        ControlBlockEnum controlBlockEnum = switch (row.cbType) {
-            case "GOOSE" -> ControlBlockEnum.GSE;
-            case "SV" -> ControlBlockEnum.SAMPLED_VALUE;
-            default -> throw new IllegalArgumentException("Unsupported Control Block Type : " + row.cbType);
-        };
-        return new Criteria(
-                controlBlockEnum,
-                row.xy + "." + row.zw,
-                TCompasIEDType.fromValue(row.iedType),
-                TCompasIEDRedundancy.fromValue(row.iedRedundancy),
-                new BigInteger(row.iedSystemVersionInstance),
-                row.bindingType.equals("BAY_INTERNAL")
-        );
-    }
-
-    private static Settings rowToSetting(Row row) {
-        Integer vlanId = toVLanId(row.vlanId);
-        Byte vlanPriority = toVlanPriority(row.vlanPriority);
-        TDurationInMilliSec minTime = toDurationInMilliSec(row.minTime);
-        TDurationInMilliSec maxTime = toDurationInMilliSec(row.maxTime);
-        return new Settings(vlanId, vlanPriority, minTime, maxTime);
-    }
-
-    private static Byte toVlanPriority(String strVlanPriority) {
-        if (StringUtils.isBlank(strVlanPriority) || NONE.equalsIgnoreCase(strVlanPriority)) {
-            return null;
-        }
-        byte vlanPriority = Byte.parseByte(strVlanPriority);
-        if (vlanPriority < 0 || vlanPriority > MAX_VLAN_PRIORITY) {
-            throw new IllegalArgumentException("VLAN PRIORITY must be between 0 and %d, but got : %d".formatted(MAX_VLAN_PRIORITY, vlanPriority));
-        }
-        return vlanPriority;
-    }
-
-    private static Integer toVLanId(String strVlanId) {
-        if (StringUtils.isBlank(strVlanId) || NONE.equalsIgnoreCase(strVlanId)) {
-            return null;
-        }
-        int vlanId = Integer.parseInt(strVlanId);
-        if (vlanId < 0 || vlanId > MAX_VLAN_ID) {
-            throw new IllegalArgumentException("VLAN ID must be between 0 and %d, but got : %d".formatted(MAX_VLAN_ID, vlanId));
-        }
-        return vlanId;
-    }
-
-    private static TDurationInMilliSec toDurationInMilliSec(String duration) {
-        if (StringUtils.isBlank(duration) || NONE.equalsIgnoreCase(duration)) {
-            return null;
-        }
-        return SclConstructorHelper.newDurationInMilliSec(Long.parseLong(duration));
-    }
-
-    private record Criteria(
-            ControlBlockEnum controlBlockEnum,
-            String systemVersionWithoutV,
-            TCompasIEDType iedType,
-            TCompasIEDRedundancy iedRedundancy,
-            BigInteger iedSystemVersionInstance,
-            boolean isBayInternal) {
-    }
-
-    @ToString
-    public static class Row {
-        @CsvBindByPosition(position = 0)
-        private String cbType;
-        @CsvBindByPosition(position = 1)
-        private String xy;
-        @CsvBindByPosition(position = 2)
-        private String zw;
-        @CsvBindByPosition(position = 3)
-        private String iedType;
-        @CsvBindByPosition(position = 4)
-        private String iedRedundancy;
-        @CsvBindByPosition(position = 5)
-        private String iedSystemVersionInstance;
-        @CsvBindByPosition(position = 6)
-        private String bindingType;
-        @CsvBindByPosition(position = 7)
-        private String vlanId;
-        @CsvBindByPosition(position = 8)
-        private String vlanPriority;
-        @CsvBindByPosition(position = 9)
-        private String minTime;
-        @CsvBindByPosition(position = 10)
-        private String maxTime;
-    }
-
-}
diff --git a/sct-commons/src/main/resources/xsd/GSE_SMV_CB_COM.xsd b/sct-commons/src/main/resources/xsd/GSE_SMV_CB_COM.xsd
new file mode 100644
index 000000000..dbc9bbe3c
--- /dev/null
+++ b/sct-commons/src/main/resources/xsd/GSE_SMV_CB_COM.xsd
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-FileCopyrightText: 2023 RTE FRANCE -->
+<!-- -->
+<!-- SPDX-License-Identifier: Apache-2.0 -->
+
+<xs:schema xmlns="http://www.rte-france.com/cbcom"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           targetNamespace="http://www.rte-france.com/cbcom" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1">
+
+    <xs:element name="CBCom">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element ref="History"/>
+                <xs:element ref="Version"/>
+                <xs:element ref="AppIdRanges"/>
+                <xs:element ref="MacRanges"/>
+                <xs:element ref="Vlans"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="History">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="Hitem" type="tHitem" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:complexType name="tHitem" mixed="true">
+        <xs:attribute name="Version" type="xs:normalizedString" use="required"/>
+        <xs:attribute name="When" type="xs:normalizedString" use="required"/>
+        <xs:attribute name="Who" type="xs:normalizedString"/>
+        <xs:attribute name="What" type="xs:normalizedString"/>
+    </xs:complexType>
+
+    <xs:element name="Version">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="SystemVersion" type="tSystemVersion" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:complexType name="tSystemVersion" mixed="true">
+        <xs:attribute name="MainSystemVersion" type="xs:normalizedString" use="required"/>
+    </xs:complexType>
+
+    <xs:element name="Vlans">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="Vlan" type="tVlan" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:complexType name="tVlan">
+        <xs:attribute name="CBType" type="tCBType" use="required"/>
+        <xs:attribute name="XY" type="xs:string" use="required"/>
+        <xs:attribute name="ZW" type="xs:string" use="required"/>
+        <xs:attribute name="IEDType" type="tIEDType" use="required"/>
+        <xs:attribute name="IEDRedundancy" type="tIEDRedundancy" use="required"/>
+        <xs:attribute name="IEDSystemVersionInstance" type="xs:string" use="required"/>
+        <xs:attribute name="BayIntOrExt" type="tBayIntOrExt" use="required"/>
+        <xs:attribute name="VlanId" type="xs:string" use="required"/>
+        <xs:attribute name="VlanPriority" type="xs:string" use="optional"/>
+        <xs:attribute name="MinTime" type="xs:string" use="optional"/>
+        <xs:attribute name="MaxTime" type="xs:string" use="optional"/>
+    </xs:complexType>
+
+    <xs:simpleType name="tCBType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="SV"/>
+            <xs:enumeration value="GOOSE"/>
+            <xs:enumeration value="GOOSE-TRIP"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="tIEDRedundancy">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="A"/>
+            <xs:enumeration value="B"/>
+            <xs:enumeration value="C"/>
+            <xs:enumeration value="D"/>
+            <xs:enumeration value="None"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="tBayIntOrExt">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="BAY_INTERNAL"/>
+            <xs:enumeration value="BAY_EXTERNAL"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:element name="MacRanges">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="MacRange" type="tRange" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:complexType name="tRange">
+        <xs:attribute name="CBType" type="tCBType" use="required"/>
+        <xs:attribute name="Start" type="xs:string" use="required"/>
+        <xs:attribute name="End" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:element name="AppIdRanges">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="AppIdRange" type="tRange" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:simpleType name="tIEDType">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                IED type to be used to identity the set of LDevice.inst handled by the IED
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="SCU"/>
+            <xs:enumeration value="SCU-MCB"/>
+            <xs:enumeration value="SCU-TG"/>
+            <xs:enumeration value="SCU-ORG"/>
+            <xs:enumeration value="STD"/>
+            <xs:enumeration value="BCU"/>
+            <xs:enumeration value="BCU-LIGNE"/>
+            <xs:enumeration value="BCU-CBO"/>
+            <xs:enumeration value="BPU"/>
+            <xs:enumeration value="MU"/>
+            <xs:enumeration value="SAMU"/>
+            <xs:enumeration value="PROT"/>
+            <xs:enumeration value="TAC"/>
+            <xs:enumeration value="PX"/>
+            <xs:enumeration value="PDIS"/>
+            <xs:enumeration value="PDB"/>
+            <xs:enumeration value="AUT"/>
+            <xs:enumeration value="PDIF"/>
+            <xs:enumeration value="GRP"/>
+            <xs:enumeration value="GW"/>
+            <xs:enumeration value="TG"/>
+            <xs:enumeration value="TOPO"/>
+            <xs:enumeration value="ADEFINIR"/>
+            <xs:enumeration value="IEDTEST"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+</xs:schema>
diff --git a/sct-commons/src/main/resources/xsd/LDEPF_Config_file_v2.xsd b/sct-commons/src/main/resources/xsd/LDEPF.xsd
similarity index 100%
rename from sct-commons/src/main/resources/xsd/LDEPF_Config_file_v2.xsd
rename to sct-commons/src/main/resources/xsd/LDEPF.xsd
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockEditorServiceTest.java
similarity index 52%
rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockServiceTest.java
rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockEditorServiceTest.java
index 9045762fa..3a720f6de 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockServiceTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockEditorServiceTest.java
@@ -7,16 +7,16 @@
 import org.assertj.core.groups.Tuple;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.lfenergy.compas.scl2007b4.model.*;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings;
 import org.lfenergy.compas.sct.commons.dto.ControlBlockTarget;
 import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation;
 import org.lfenergy.compas.sct.commons.dto.SclReportItem;
 import org.lfenergy.compas.sct.commons.exception.ScdException;
+import org.lfenergy.compas.sct.commons.model.cbcom.*;
+import org.lfenergy.compas.sct.commons.scl.ControlService;
 import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
 import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
 import org.lfenergy.compas.sct.commons.scl.ied.DataSetAdapter;
@@ -29,45 +29,33 @@
 import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper;
 import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
 import org.lfenergy.compas.sct.commons.util.CsvUtils;
-import org.mockito.InjectMocks;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.lfenergy.compas.sct.commons.util.PrivateEnum;
+import org.lfenergy.compas.sct.commons.util.PrivateUtils;
 
-import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static org.assertj.core.api.Assertions.*;
 import static org.lfenergy.compas.scl2007b4.model.TFCEnum.ST;
-import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.*;
 import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*;
 import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable;
 import static org.lfenergy.compas.sct.commons.util.ControlBlockEnum.*;
-import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newDurationInMilliSec;
 
-@ExtendWith(MockitoExtension.class)
-class ControlBlockServiceTest {
+class ControlBlockEditorServiceTest {
 
-    @InjectMocks
-    ControlBlockService controlBlockService;
+    ControlBlockEditorService controlBlockEditorService;
 
     private Set<FcdaForDataSetsCreation> allowedFcdas;
 
-    private static final long GSE_APP_ID_MIN = 0x9;
-    private static final long SMV_APP_ID_MIN = 0x400A;
-    private static final String GSE_MAC_ADDRESS_PREFIX = "01-02-03-04-";
-    private static final String SMV_MAC_ADDRESS_PREFIX = "0A-0B-0C-0D-";
-    private static final NetworkRanges GSE_NETWORK_RANGES = new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN + 10, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "01-AA");
-    private static final NetworkRanges SMV_NETWORK_RANGES = new NetworkRanges(SMV_APP_ID_MIN, SMV_APP_ID_MIN + 10, SMV_MAC_ADDRESS_PREFIX + "00-FF", SMV_MAC_ADDRESS_PREFIX + "01-AA");
-    private static final RangesPerCbType RANGES_PER_CB_TYPE = new RangesPerCbType(GSE_NETWORK_RANGES, SMV_NETWORK_RANGES);
-
-
     @BeforeEach
     void init() {
+        controlBlockEditorService = new ControlBlockEditorService(new ControlService());
         allowedFcdas = new HashSet<>(CsvUtils.parseRows("FcdaCandidates.csv", StandardCharsets.UTF_8, FcdaForDataSetsCreation.class));
     }
 
@@ -82,7 +70,7 @@ void analyzeDataGroups_should_success() {
         iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxSMV(2L);
         iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxReports(1L);
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.analyzeDataGroups(scd);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.analyzeDataGroups(scd);
         //Then
         assertThat(sclReportItems).isEmpty();
 
@@ -100,7 +88,7 @@ void analyzeDataGroups_should_return_errors_messages() {
         iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getGOOSE().setMax(2L);
         iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfReportControl().setMax(0L);
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.analyzeDataGroups(scd);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.analyzeDataGroups(scd);
         //Then
         assertThat(sclReportItems).hasSize(11)
                 .extracting(SclReportItem::message)
@@ -118,13 +106,12 @@ void analyzeDataGroups_should_return_errors_messages() {
                         "There are too much SMV Control Blocks for the IED IED_NAME2: 3 > 1 max");
     }
 
-
     @Test
     void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_srcXXX_attributes_on_ExtRef() {
         // Given
         SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml");
         // When
-        controlBlockService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
+        controlBlockEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
         // Then
         SclRootAdapter scdRootAdapter = new SclRootAdapter(scl);
         List<TExtRef> extRefs = scdRootAdapter
@@ -157,7 +144,7 @@ void createDataSetAndControlBlocks_should_Throw_Exception_when_list_allowed_fcda
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When Then
-        assertThatCode(() -> controlBlockService.createDataSetAndControlBlocks(scd, fcdaForDataSets))
+        assertThatCode(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, fcdaForDataSets))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before");
     }
@@ -167,7 +154,7 @@ void createDataSetAndControlBlocks_should_create_DataSet() {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
         assertThat(streamAllDataSets(scd)).hasSize(6);
@@ -198,7 +185,7 @@ void createDataSetAndControlBlocks_should_create_ControlBlocks() {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
 
@@ -231,7 +218,7 @@ void createDataSetAndControlBlocks_should_set_ExtRef_srcXXX_attributes() {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
 
@@ -261,7 +248,7 @@ void createDataSetAndControlBlocks_with_targetIedName_should_Throw_Exception_whe
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When Then
-        assertThatCode(() -> controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", fcdaForDataSets))
+        assertThatCode(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, "IED_NAME1", fcdaForDataSets))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before");
     }
@@ -271,7 +258,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_provided_should_succeed
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, "IED_NAME1", allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
         assertThat(streamAllDataSets(scd)).hasSize(6);
@@ -287,7 +274,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_provided_and_no_ext_ref
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME2", allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, "IED_NAME2", allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
         assertThat(streamAllDataSets(scd)).isEmpty();
@@ -298,7 +285,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_not_found_should_throw_
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When & Then
-        assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", allowedFcdas))
+        assertThatThrownBy(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", allowedFcdas))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("IED.name 'non_existing_IED_name' not found in SCD");
     }
@@ -309,7 +296,7 @@ void createDataSetAndControlBlocks_with_targetIedName_and_targetLDeviceInst_shou
         // Given
         SCL scd = new SCL();
         // When Then
-        assertThatCode(() -> controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", fcdaForDataSets))
+        assertThatCode(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", fcdaForDataSets))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("Accepted FCDAs list is empty, you should initialize allowed FCDA lists with CsvHelper class before");
     }
@@ -319,7 +306,7 @@ void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_p
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11", allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
     }
@@ -329,7 +316,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_not_found_and_targetLDe
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When & Then
-        assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", "LD_INST11", allowedFcdas))
+        assertThatThrownBy(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", "LD_INST11", allowedFcdas))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("IED.name 'non_existing_IED_name' not found in SCD");
     }
@@ -339,7 +326,7 @@ void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_n
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When & Then
-        assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, "IED_NAME1", "non_existing_LDevice_inst", allowedFcdas))
+        assertThatThrownBy(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, "IED_NAME1", "non_existing_LDevice_inst", allowedFcdas))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("LDevice.inst 'non_existing_LDevice_inst' not found in IED 'IED_NAME1'");
     }
@@ -349,19 +336,18 @@ void createDataSetAndControlBlocks_when_targetLDeviceInst_is_provided_without_ta
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success.xml");
         // When & Then
-        assertThatThrownBy(() -> controlBlockService.createDataSetAndControlBlocks(scd, null, "LD_INST11", allowedFcdas))
+        assertThatThrownBy(() -> controlBlockEditorService.createDataSetAndControlBlocks(scd, null, "LD_INST11", allowedFcdas))
                 .isInstanceOf(ScdException.class)
                 .hasMessage("IED.name parameter is missing");
     }
 
 
-
     @Test
     void updateAllSourceDataSetsAndControlBlocks_should_sort_FCDA_inside_DataSet_and_avoid_duplicates() {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success_test_fcda_sort.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.createDataSetAndControlBlocks(scd, allowedFcdas);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.createDataSetAndControlBlocks(scd, allowedFcdas);
         // Then
         assertThat(sclReportItems).isEmpty();
         DataSetAdapter dataSetAdapter = findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI");
@@ -376,45 +362,73 @@ void updateAllSourceDataSetsAndControlBlocks_should_sort_FCDA_inside_DataSet_and
     }
 
     @Test
-    void configureNetworkForAllControlBlocks_should_create_GSE_and_SMV_elements() {
+    void configureNetworkForAllControlBlocks_should_create_GSE_elements() {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        CBCom cbCom = createCbCom();
+        // When
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
+        // Then
+        assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue();
+        TGSE gse1 = getCommunicationGSE(scd, "IED_NAME2", "CB_LD_INST21_GSI");
+        assertThat(gse1.getLdInst()).isEqualTo("LD_INST21");
+        assertThat(SclDuration.from(gse1.getMinTime())).isEqualTo(new SclDuration("10", "s", "m"));
+        assertThat(SclDuration.from(gse1.getMaxTime())).isEqualTo(new SclDuration("2000", "s", "m"));
+        assertThat(gse1.getAddress().getP()).extracting(TP::getType, TP::getValue).containsExactlyInAnyOrder(
+                Tuple.tuple("VLAN-PRIORITY", "1"),
+                Tuple.tuple("APPID", "0000"),
+                Tuple.tuple("MAC-Address", "01-0C-CD-01-00-00"),
+                Tuple.tuple("VLAN-ID", "12D")
+        );
+        TGSE gse2 = getCommunicationGSE(scd, "IED_NAME2", "CB_LD_INST21_GMI");
+        assertThat(gse2.getLdInst()).isEqualTo("LD_INST21");
+        assertThat(SclDuration.from(gse2.getMinTime())).isEqualTo(new SclDuration("10", "s", "m"));
+        assertThat(SclDuration.from(gse2.getMaxTime())).isEqualTo(new SclDuration("2000", "s", "m"));
+        assertThat(gse2.getAddress().getP()).extracting(TP::getType, TP::getValue).containsExactlyInAnyOrder(
+                Tuple.tuple("VLAN-PRIORITY", "1"),
+                Tuple.tuple("APPID", "0001"),
+                Tuple.tuple("MAC-Address", "01-0C-CD-01-00-01"),
+                Tuple.tuple("VLAN-ID", "12D")
+        );
+        TGSE gse3 = getCommunicationGSE(scd, "IED_NAME3", "CB_LD_INST31_GSE");
+        assertThat(gse3.getLdInst()).isEqualTo("LD_INST31");
+        assertThat(SclDuration.from(gse3.getMinTime())).isEqualTo(new SclDuration("10", "s", "m"));
+        assertThat(SclDuration.from(gse3.getMaxTime())).isEqualTo(new SclDuration("2000", "s", "m"));
+        assertThat(gse3.getAddress().getP()).extracting(TP::getType, TP::getValue).containsExactlyInAnyOrder(
+                Tuple.tuple("VLAN-PRIORITY", "2"),
+                Tuple.tuple("APPID", "0002"),
+                Tuple.tuple("MAC-Address", "01-0C-CD-01-00-02"),
+                Tuple.tuple("VLAN-ID", "12E")
+        );
+        MarshallerWrapper.assertValidateXmlSchema(scd);
+    }
 
-        TDurationInMilliSec minTime = newDurationInMilliSec(10);
-        TDurationInMilliSec maxTime = newDurationInMilliSec(2000);
-        ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null);
-
+    @Test
+    void configureNetworkForAllControlBlocks_should_create_SMV_elements() {
+        // Given
+        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        CBCom cbCom = createCbCom();
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
         // Then
         assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue();
-        TConnectedAP connectedAP = new SclRootAdapter(scd).findConnectedApAdapter("IED_NAME2", "AP_NAME").get().getCurrentElem();
-        TGSE gse = connectedAP.getGSE().stream()
-                .filter(tgse -> "CB_LD_INST21_GSI".equals(tgse.getCbName()))
-                .findFirst().get();
-        assertThat(gse.getLdInst()).isEqualTo("LD_INST21");
-        assertThat(gse.getMinTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-                .containsExactly("s", "m", new BigDecimal("10"));
-        assertThat(gse.getMaxTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-                .containsExactly("s", "m", new BigDecimal("2000"));
-        assertThat(gse.getAddress().getP()).extracting(TP::getType, TP::getValue)
-                .containsExactlyInAnyOrder(
-                        Tuple.tuple("VLAN-PRIORITY", "4"),
-                        Tuple.tuple("APPID", "0009"),
-                        Tuple.tuple("MAC-Address", "01-02-03-04-00-FF"),
-                        Tuple.tuple("VLAN-ID", "1D6")
-                );
-        TSMV smv = connectedAP.getSMV().stream()
-                .filter(tsmv -> "CB_LD_INST21_SVI".equals(tsmv.getCbName()))
-                .findFirst().get();
-        assertThat(smv.getLdInst()).isEqualTo("LD_INST21");
-        assertThat(smv.getAddress().getP()).extracting(TP::getType, TP::getValue)
-                .containsExactlyInAnyOrder(
-                        Tuple.tuple("VLAN-PRIORITY", "4"),
-                        Tuple.tuple("APPID", "400A"),
-                        Tuple.tuple("MAC-Address", "0A-0B-0C-0D-00-FF"),
-                        Tuple.tuple("VLAN-ID", "1D6")
-                );
+        TSMV smv1 = getCommunicationSMV(scd, "IED_NAME2", "CB_LD_INST21_SVI");
+        assertThat(smv1.getLdInst()).isEqualTo("LD_INST21");
+        assertThat(smv1.getAddress().getP()).extracting(TP::getType, TP::getValue).containsExactlyInAnyOrder(
+                Tuple.tuple("VLAN-PRIORITY", "3"),
+                Tuple.tuple("APPID", "4000"),
+                Tuple.tuple("MAC-Address", "01-0C-CD-04-00-00"),
+                Tuple.tuple("VLAN-ID", "12F")
+        );
+        assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue();
+        TSMV smv2 = getCommunicationSMV(scd, "IED_NAME3", "CB_LD_INST31_SVE");
+        assertThat(smv2.getLdInst()).isEqualTo("LD_INST31");
+        assertThat(smv2.getAddress().getP()).extracting(TP::getType, TP::getValue).containsExactlyInAnyOrder(
+                Tuple.tuple("VLAN-PRIORITY", "4"),
+                Tuple.tuple("APPID", "4001"),
+                Tuple.tuple("MAC-Address", "01-0C-CD-04-00-01"),
+                Tuple.tuple("VLAN-ID", "130")
+        );
         MarshallerWrapper.assertValidateXmlSchema(scd);
     }
 
@@ -422,12 +436,13 @@ void configureNetworkForAllControlBlocks_should_create_GSE_and_SMV_elements() {
     void configureNetworkForAllControlBlocks_should_create_GSE_with_incremental_appid_and_mac_addresses() {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-
-        TDurationInMilliSec minTime = newDurationInMilliSec(10);
-        TDurationInMilliSec maxTime = newDurationInMilliSec(2000);
-        ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null);
+        CBCom cbCom = createCbCom();
+        cbCom.getAppIdRanges().getAppIdRange().get(0).setStart("0009");
+        cbCom.getAppIdRanges().getAppIdRange().get(0).setEnd("000B");
+        cbCom.getMacRanges().getMacRange().get(0).setStart("01-02-03-04-00-FF");
+        cbCom.getMacRanges().getMacRange().get(0).setEnd("01-02-03-04-01-01");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
         // Then
         assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue();
         assertThat(streamAllConnectedApGseP(scd, "APPID"))
@@ -438,19 +453,160 @@ void configureNetworkForAllControlBlocks_should_create_GSE_with_incremental_appi
 
     @ParameterizedTest
     @MethodSource("provideConfigureNetworkForAllControlBlocksErrors")
-    void configureNetworkForAllControlBlocks_should_fail_when_no_settings_for_this_controlBlock(ControlBlockNetworkSettings controlBlockNetworkSettings,
-                                                                                                RangesPerCbType rangesPerCbType,
-                                                                                                String expectedMessage) {
+    void configureNetworkForAllControlBlocks_should_fail_when_no_settings_for_this_controlBlock(CBCom cbCom, String expectedMessage, String expectedXPath) {
         // Given
         SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
         // When
-        List<SclReportItem> sclReportItems = controlBlockService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType);
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
         // Then
         assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse();
         assertThat(sclReportItems)
-                .extracting(SclReportItem::message, SclReportItem::xpath)
-                .contains(Tuple.tuple(expectedMessage,
-                        "/SCL/IED[@name=\"IED_NAME2\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST21\"]/LN0/GSEControl[@name=\"CB_LD_INST21_GMI\"]"));
+                .contains(SclReportItem.error(expectedXPath, expectedMessage));
+    }
+
+    public static Stream<Arguments> provideConfigureNetworkForAllControlBlocksErrors() {
+        CBCom cbComWithNoVlan = createCbCom();
+        cbComWithNoVlan.getVlans().getVlan().clear();
+        CBCom cbComWithMissingVlanId = createCbCom();
+        cbComWithMissingVlanId.getVlans().getVlan().get(0).setVlanId(null);
+        CBCom cbComWithNotEnoughAppId = createCbCom();
+        cbComWithNotEnoughAppId.getAppIdRanges().getAppIdRange().get(0).setStart("0000");
+        cbComWithNotEnoughAppId.getAppIdRanges().getAppIdRange().get(0).setEnd("00001");
+        CBCom cbComWithNotEnoughMacAddress = createCbCom();
+        cbComWithNotEnoughMacAddress.getMacRanges().getMacRange().get(0).setStart("01-0C-CD-01-00-00");
+        cbComWithNotEnoughMacAddress.getMacRanges().getMacRange().get(0).setEnd("01-0C-CD-01-00-01");
+
+        return Stream.of(
+                Arguments.of(cbComWithNoVlan, "Cannot configure communication for this ControlBlock because: No controlBlock communication settings found with these Criteria[cbType=GOOSE, systemVersionWithoutV=01.00.009.001, iedType=BCU, iedRedundancy=A, iedSystemVersionInstance=1, bayIntOrExt=BAY_INTERNAL]",
+                        "/SCL/IED[@name=\"IED_NAME2\"]/AccessPoint[@name=\"AP_NAME\"]/Server/LDevice[@inst=\"LD_INST21\"]/LN0/GSEControl[@name=\"CB_LD_INST21_GMI\"]"),
+                Arguments.of(cbComWithMissingVlanId, "Cannot configure communication for this ControlBlock because no Vlan Id was provided in the settings",
+                        "/SCL/IED[@name=\"IED_NAME2\"]/AccessPoint[@name=\"AP_NAME\"]/Server/LDevice[@inst=\"LD_INST21\"]/LN0/GSEControl[@name=\"CB_LD_INST21_GMI\"]"),
+                Arguments.of(cbComWithNotEnoughAppId, "Cannot configure communication for this ControlBlock because range of appId is exhausted",
+                        "/SCL/IED[@name=\"IED_NAME3\"]/AccessPoint[@name=\"AP_NAME\"]/Server/LDevice[@inst=\"LD_INST31\"]/LN0/GSEControl[@name=\"CB_LD_INST31_GSE\"]"),
+                Arguments.of(cbComWithNotEnoughMacAddress, "Cannot configure communication for this ControlBlock because range of MAC Address is exhausted",
+                        "/SCL/IED[@name=\"IED_NAME3\"]/AccessPoint[@name=\"AP_NAME\"]/Server/LDevice[@inst=\"LD_INST31\"]/LN0/GSEControl[@name=\"CB_LD_INST31_GSE\"]")
+        );
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideBlankCriteria")
+    void configureNetworkForAllControlBlocks_when_setting_files_has_blank_criteria_should_return_error(Consumer<TVlan> setCriteriaBlank) {
+        // Given
+        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        CBCom cbCom = createCbCom();
+        setCriteriaBlank.accept(cbCom.getVlans().getVlan().get(0));
+        //When
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
+        //Then
+        assertThat(sclReportItems).hasSize(1);
+        assertThat(sclReportItems.get(0)).extracting(SclReportItem::isError, SclReportItem::xpath)
+                .containsExactly(true, "Control Block Communication setting files");
+        assertThat(sclReportItems.get(0).message()).matches("Error in Control Block communication setting file: vlan is missing attribute .*");
+    }
+
+    private static Stream<Arguments> provideBlankCriteria() {
+        return Stream.of(Arguments.of(
+                (Consumer<TVlan>) tVlan -> tVlan.setXY(null),
+                (Consumer<TVlan>) tVlan -> tVlan.setZW(null),
+                (Consumer<TVlan>) tVlan -> tVlan.setIEDType(null),
+                (Consumer<TVlan>) tVlan -> tVlan.setIEDRedundancy(null),
+                (Consumer<TVlan>) tVlan -> tVlan.setIEDSystemVersionInstance(null),
+                (Consumer<TVlan>) tVlan -> tVlan.setBayIntOrExt(null)
+        ));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideMalformedNumbers")
+    void configureNetworkForAllControlBlocks_when_malformed_numbers_should_return_error(Consumer<TVlan> setMalformedNumber) {
+        // Given
+        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        CBCom cbCom = createCbCom();
+        setMalformedNumber.accept(cbCom.getVlans().getVlan().get(0));
+        //When
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
+        //Then
+        assertThat(sclReportItems).hasSize(1);
+        assertThat(sclReportItems.get(0)).extracting(SclReportItem::isError, SclReportItem::xpath)
+                .containsExactly(true, "Control Block Communication setting files");
+        assertThat(sclReportItems.get(0).message()).matches("Error in Control Block communication setting file: .+ must be an integer( or 'none')?, but got : XXX");
+    }
+
+    private static Stream<Arguments> provideMalformedNumbers() {
+        return Stream.of(
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setIEDSystemVersionInstance("XXX")),
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setVlanId("XXX")),
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setVlanPriority("XXX")),
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setMinTime("XXX")),
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setMaxTime("XXX"))
+        );
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideOutOfBoundNumbers")
+    void configureNetworkForAllControlBlocks_when_out_of_bound_numbers_should_return_error(Consumer<TVlan> setMalformedNumber) {
+        // Given
+        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        CBCom cbCom = createCbCom();
+        setMalformedNumber.accept(cbCom.getVlans().getVlan().get(0));
+        //When
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
+        //Then
+        assertThat(sclReportItems).hasSize(1);
+        assertThat(sclReportItems.get(0)).extracting(SclReportItem::isError, SclReportItem::xpath)
+                .containsExactly(true, "Control Block Communication setting files");
+        assertThat(sclReportItems.get(0).message()).matches("Error in Control Block communication setting file: VLAN (ID|PRIORITY) must be between 0 and [0-9]+, but got : .*");
+    }
+
+    private static Stream<Arguments> provideOutOfBoundNumbers() {
+        return Stream.of(
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setVlanId("4096")), // VlanId > MAX_VLAN_ID
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setVlanId("-1")), // VlanId < 0
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setVlanPriority("8")), // VlanPriority > MAX_VLAN_PRIORITY
+                Arguments.of((Consumer<TVlan>) tVlan -> tVlan.setVlanPriority("-1")) // VlanPriority < 0
+        );
+    }
+
+    @Test
+    void configureNetworkForAllControlBlocks_when_missing_connectedAp_should_return_error() {
+        // Given
+        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        scd.getCommunication().getSubNetwork().get(0).getConnectedAP().remove(0);
+        CBCom cbCom = createCbCom();
+        //When
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
+        //Then
+        assertThat(sclReportItems).hasSize(3);
+        assertThat(sclReportItems).extracting(SclReportItem::isError).containsOnly(true);
+        assertThat(sclReportItems).extracting(SclReportItem::message).containsOnly("Cannot configure communication for ControlBlock because no ConnectedAP found for AccessPoint");
+        assertThat(sclReportItems).extracting(SclReportItem::xpath).allMatch(xpath -> xpath.startsWith("""
+                /SCL/IED[@name="IED_NAME2"]/AccessPoint[@name="AP_NAME"]/Server/LDevice[@inst="LD_INST21"]/LN0/"""));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideRemovePrivateInfo")
+    void configureNetworkForAllControlBlocks_when_missing_IED_privates_should_return_error(Consumer<TIED> removePrivateInfo) {
+        // Given
+        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
+        CBCom cbCom = createCbCom();
+        removePrivateInfo.accept(scd.getIED().get(1));
+        //When
+        List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
+        //Then
+        assertThat(sclReportItems).hasSize(3);
+        assertThat(sclReportItems).extracting(SclReportItem::isError, SclReportItem::xpath)
+                .containsOnly(Tuple.tuple(true, """
+                        /SCL/IED[@name="IED_NAME2"]/AccessPoint[@name="AP_NAME"]/Server/LDevice[@inst="LD_INST21"]"""));
+        assertThat(sclReportItems).extracting(SclReportItem::message).allSatisfy(message -> assertThat(message).containsAnyOf("COMPAS-ICDHeader", "COMPAS-SystemVersion"));
+    }
+
+    private static Stream<Arguments> provideRemovePrivateInfo() {
+        return Stream.of(
+                Arguments.of((Consumer<TIED>) tied -> PrivateUtils.removePrivates(tied, PrivateEnum.COMPAS_SYSTEM_VERSION)),
+                Arguments.of((Consumer<TIED>) tied -> PrivateUtils.extractCompasPrivate(tied, TCompasSystemVersion.class).ifPresent(tCompasSystemVersion -> tCompasSystemVersion.setMainSystemVersion(null))),
+                Arguments.of((Consumer<TIED>) tied -> PrivateUtils.extractCompasPrivate(tied, TCompasSystemVersion.class).ifPresent(tCompasSystemVersion -> tCompasSystemVersion.setMinorSystemVersion(null))),
+                Arguments.of((Consumer<TIED>) tied -> PrivateUtils.removePrivates(tied, PrivateEnum.COMPAS_ICDHEADER)),
+                Arguments.of((Consumer<TIED>) tied -> PrivateUtils.extractCompasPrivate(tied, TCompasICDHeader.class).ifPresent(tCompasICDHeader -> tCompasICDHeader.setIEDSystemVersioninstance(null)))
+        );
     }
 
     @Test
@@ -458,7 +614,7 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D
         // Given
         SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml");
         // When
-        controlBlockService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
+        controlBlockEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
         // Then
         SclRootAdapter scdRootAdapter = new SclRootAdapter(scl);
         List<LDeviceAdapter> lDevices = scdRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters).toList();
@@ -478,7 +634,7 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D
         // Given
         SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml");
         // When
-        controlBlockService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
+        controlBlockEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
         // Then
         SclRootAdapter scdRootAdapter = new SclRootAdapter(scl);
         List<TLN> lns = scdRootAdapter.streamIEDAdapters()
@@ -493,30 +649,70 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D
         assertIsMarshallable(scl);
     }
 
-    public static Stream<Arguments> provideConfigureNetworkForAllControlBlocksErrors() {
-        Settings settingsWithNullVlanId = new Settings(null, (byte) 1, newDurationInMilliSec(1), newDurationInMilliSec(2));
-        Settings settings = new Settings(1, (byte) 1, newDurationInMilliSec(1), newDurationInMilliSec(2));
-        return Stream.of(
-                Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(null, null),
-                        RANGES_PER_CB_TYPE,
-                        "Cannot configure network for this ControlBlock because no settings was provided"),
-                Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(null, "Custom error message"),
-                        RANGES_PER_CB_TYPE,
-                        "Cannot configure network for this ControlBlock because: Custom error message"),
-                Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settingsWithNullVlanId, null),
-                        RANGES_PER_CB_TYPE,
-                        "Cannot configure network for this ControlBlock because no Vlan Id was provided in the settings"),
-                Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settings, null),
-                        new RangesPerCbType(
-                                new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "01-AA"),
-                                SMV_NETWORK_RANGES),
-                        "Cannot configure network for this ControlBlock because range of appId is exhausted"),
-                Arguments.of((ControlBlockNetworkSettings) controlBlockAdapter -> new SettingsOrError(settings, null),
-                        new RangesPerCbType(
-                                new NetworkRanges(GSE_APP_ID_MIN, GSE_APP_ID_MIN + 10, GSE_MAC_ADDRESS_PREFIX + "00-FF", GSE_MAC_ADDRESS_PREFIX + "00-FF"),
-                                SMV_NETWORK_RANGES),
-                        "Cannot configure network for this ControlBlock because range of MAC Address is exhausted")
-        );
+    private static TGSE getCommunicationGSE(SCL scd, String iedName, String cbName) {
+        return new SclRootAdapter(scd).findConnectedApAdapter(iedName, "AP_NAME").orElseThrow()
+                .getCurrentElem()
+                .getGSE().stream()
+                .filter(tgse -> cbName.equals(tgse.getCbName()))
+                .findFirst().orElseThrow();
+    }
+
+    private static TSMV getCommunicationSMV(SCL scd, String iedName, String cbName) {
+        return new SclRootAdapter(scd).findConnectedApAdapter(iedName, "AP_NAME").orElseThrow()
+                .getCurrentElem()
+                .getSMV().stream()
+                .filter(tsmv -> cbName.equals(tsmv.getCbName()))
+                .findFirst().orElseThrow();
+    }
+
+    private static CBCom createCbCom() {
+        CBCom cbCom = new CBCom();
+        cbCom.setMacRanges(new MacRanges());
+        cbCom.setAppIdRanges(new AppIdRanges());
+        cbCom.setVlans(new Vlans());
+        cbCom.getMacRanges().getMacRange().add(newRange(TCBType.GOOSE, "01-0C-CD-01-00-00", "01-0C-CD-01-01-FF"));
+        cbCom.getMacRanges().getMacRange().add(newRange(TCBType.SV, "01-0C-CD-04-00-00", "01-0C-CD-04-FF-FF"));
+        cbCom.getAppIdRanges().getAppIdRange().add(newRange(TCBType.GOOSE, "0000", "4000"));
+        cbCom.getAppIdRanges().getAppIdRange().add(newRange(TCBType.SV, "4000", "7FFF"));
+        cbCom.getVlans().getVlan().addAll(List.of(
+                newVlan(TCBType.GOOSE, TBayIntOrExt.BAY_INTERNAL, "301", "1"),
+                newVlan(TCBType.GOOSE, TBayIntOrExt.BAY_EXTERNAL, "302", "2"),
+                newVlan(TCBType.SV, TBayIntOrExt.BAY_INTERNAL, "303", "3"),
+                newVlan(TCBType.SV, TBayIntOrExt.BAY_EXTERNAL, "304", "4")
+        ));
+        return cbCom;
     }
 
+    private static TRange newRange(TCBType tcbType, String start, String end) {
+        TRange macRangeGSE = new TRange();
+        macRangeGSE.setCBType(tcbType);
+        macRangeGSE.setStart(start);
+        macRangeGSE.setEnd(end);
+        return macRangeGSE;
+    }
+
+    private static TVlan newVlan(TCBType tcbType, TBayIntOrExt tBayIntOrExt, String vlanId, String vlanPriority) {
+        TVlan gseVlan = new TVlan();
+        gseVlan.setCBType(tcbType);
+        gseVlan.setXY("01.00");
+        gseVlan.setZW("009.001");
+        gseVlan.setIEDType(TIEDType.BCU);
+        gseVlan.setIEDRedundancy(TIEDRedundancy.A);
+        gseVlan.setIEDSystemVersionInstance("1");
+        gseVlan.setBayIntOrExt(tBayIntOrExt);
+        gseVlan.setVlanId(vlanId);
+        gseVlan.setVlanPriority(vlanPriority);
+        gseVlan.setMinTime("10");
+        gseVlan.setMaxTime("2000");
+        return gseVlan;
+    }
+
+    /**
+     * Help comparing TDurationInMilliSec
+     */
+    record SclDuration(String value, String unit, String multiplier) {
+        static SclDuration from(TDurationInMilliSec tDurationInMilliSec) {
+            return new SclDuration(tDurationInMilliSec.getValue().toString(), tDurationInMilliSec.getUnit(), tDurationInMilliSec.getMultiplier());
+        }
+    }
 }
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java
deleted file mode 100644
index 89450f8d6..000000000
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java
+++ /dev/null
@@ -1,235 +0,0 @@
-// SPDX-FileCopyrightText: 2023 RTE FRANCE
-//
-// SPDX-License-Identifier: Apache-2.0
-
-package org.lfenergy.compas.sct.commons.dto;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.EnumSource;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.junit.jupiter.params.provider.ValueSource;
-import org.lfenergy.compas.scl2007b4.model.SCL;
-import org.lfenergy.compas.scl2007b4.model.TDurationInMilliSec;
-import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.SettingsOrError;
-import org.lfenergy.compas.sct.commons.util.PrivateUtils;
-import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
-import org.lfenergy.compas.sct.commons.scl.ied.ControlBlockAdapter;
-import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
-import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
-import org.lfenergy.compas.sct.commons.util.ControlBlockEnum;
-import org.lfenergy.compas.sct.commons.util.ControlBlockNetworkSettingsCsvHelper;
-import org.lfenergy.compas.sct.commons.util.CsvUtils;
-import org.lfenergy.compas.sct.commons.util.PrivateEnum;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.math.BigDecimal;
-import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.Settings;
-import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.findControlBlock;
-import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.findIed;
-
-class ControlBlockNetworkSettingsTest {
-
-    private ControlBlockNetworkSettings controlBlockNetworkSettings;
-
-    @BeforeEach
-    public void setUp() {
-        String fileName = "ControlBlockCommunicationTemplates.csv";
-        InputStream inputStream = Objects.requireNonNull(CsvUtils.class.getClassLoader().getResourceAsStream(fileName), "Resource not found: " + fileName);
-        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
-        controlBlockNetworkSettings = new ControlBlockNetworkSettingsCsvHelper(inputStreamReader);
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = {
-            ";01.00;009.001;BCU;A;1;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;;009.001;BCU;A;1;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;01.00;;BCU;A;1;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;01.00;009.001;;A;1;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;01.00;009.001;BCU;;1;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;01.00;009.001;BCU;A;;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;01.00;009.001;BCU;A;1;;300;4;10;2000"
-    })
-    void constructor_when_csv_has_blank_criteria_cells_should_throw_exception(String row) {
-        //Given
-        StringReader stringReader = new StringReader(row);
-        //When & Then
-        assertThatThrownBy(() -> new ControlBlockNetworkSettingsCsvHelper(stringReader))
-                .isInstanceOf(IllegalArgumentException.class)
-                .hasMessageStartingWith("At least one criteria is null in row ControlBlockNetworkSettingsCsvHelper.Row")
-                .hasMessageContaining("=null,");
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = {
-            "GOOSE;01.00;009.001;BCU;A;XXX;BAY_INTERNAL;300;4;10;2000",
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;XXX;4;10;2000",
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;300;XXX;10;2000",
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;300;4;XXX;2000",
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;300;4;10;XXX"
-    })
-    void constructor_when_csv_has_malformed_numbers_should_throw_exception(String row) {
-        //Given
-        StringReader stringReader = new StringReader(row);
-        //When & Then
-        assertThatThrownBy(() -> new ControlBlockNetworkSettingsCsvHelper(stringReader))
-                .isInstanceOf(NumberFormatException.class)
-                .hasMessage("For input string: \"XXX\"");
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = {
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;4096;4;10;2000", // VlanId > MAX_VLAN_ID
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;-1;4;10;2000", // VlanId < 0
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;300;8;10;2000", // VlanPriority > MAX_VLAN_PRIORITY
-            "GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;300;-1;10;2000" // VlanPriority < 0
-    })
-    void constructor_when_csv_has_numbers_our_out_of_bound_should_throw_exception(String row) {
-        //Given
-        StringReader stringReader = new StringReader(row);
-        //When & Then
-        assertThatThrownBy(() -> new ControlBlockNetworkSettingsCsvHelper(stringReader))
-                .isInstanceOf(IllegalArgumentException.class)
-                .hasMessageContaining("must be between 0 and ");
-    }
-
-    @Test
-    void constructor_when_unsupported_cbType_should_throw_exception() {
-        //Given
-        StringReader stringReader = new StringReader("CUSTOM_CB_TYPE;01.00;009.001;BCU;A;1;BAY_INTERNAL;1;4;10;2000");
-        //When & Then
-        assertThatThrownBy(() -> new ControlBlockNetworkSettingsCsvHelper(stringReader))
-                .isInstanceOf(IllegalArgumentException.class)
-                .hasMessage("Unsupported Control Block Type : CUSTOM_CB_TYPE");
-    }
-
-    @Test
-    void getNetworkSettings_should_return_settings_for_bay_internal_controlBlock() {
-        //Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-        ControlBlockAdapter controlBlockAdapter = findControlBlock(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", ControlBlockEnum.GSE);
-
-        //When
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-
-        //Then
-        assertThat(settingsOrError.errorMessage()).isNull();
-        Settings networkSettings = settingsOrError.settings();
-        assertThat(networkSettings)
-                .extracting(Settings::vlanId, Settings::vlanPriority)
-                .containsExactly(300, (byte) 4);
-        assertThat(networkSettings.minTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-                .containsExactly("s", "m", new BigDecimal("10"));
-        assertThat(networkSettings.maxTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-                .containsExactly("s", "m", new BigDecimal("2000"));
-    }
-
-    @Test
-    void getNetworkSettings_should_return_settings_for_bay_external_controlBlock() {
-        //Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-        ControlBlockAdapter controlBlockAdapter = findControlBlock(scd, "IED_NAME3", "LD_INST31", "CB_LD_INST31_GSE", ControlBlockEnum.GSE);
-
-        //When
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-
-        //Then
-        assertThat(settingsOrError.errorMessage()).isNull();
-        Settings networkSettings = settingsOrError.settings();
-        assertThat(networkSettings)
-                .extracting(Settings::vlanId, Settings::vlanPriority)
-                .containsExactly(301, (byte) 5);
-        assertThat(networkSettings.minTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-                .containsExactly("s", "m", new BigDecimal("15"));
-        assertThat(networkSettings.maxTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-                .containsExactly("s", "m", new BigDecimal("5000"));
-    }
-
-    @Test
-    void getNetworkSettings_should_return_vlanId_null_when_column_contains_none() {
-        //Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-        ControlBlockAdapter controlBlockAdapter = findControlBlock(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_SVI", ControlBlockEnum.SAMPLED_VALUE);
-
-        //When
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-
-        //Then
-        assertThat(settingsOrError.errorMessage()).isNull();
-        Settings networkSettings = settingsOrError.settings();
-        assertThat(networkSettings.vlanId()).isNull();
-        assertThat(networkSettings.vlanPriority()).isNull();
-    }
-
-    @Test
-    void getNetworkSettings_should_return_null_when_row_not_found_in_csv_file() {
-        //Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        findIed(sclRootAdapter.getCurrentElem(), "IED_NAME2").getCompasSystemVersion().get().setMainSystemVersion("99.99");
-        ControlBlockAdapter controlBlockAdapter = findControlBlock(sclRootAdapter.getCurrentElem(), "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", ControlBlockEnum.GSE);
-
-        //When
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-
-        //Then
-        assertThat(settingsOrError.errorMessage()).isEqualTo("No row found with these criteria Criteria[controlBlockEnum=GSE, systemVersionWithoutV=99.99.009.001, iedType=BCU, iedRedundancy=A, iedSystemVersionInstance=1, isBayInternal=true]");
-        assertThat(settingsOrError.settings()).isNull();
-    }
-
-    @ParameterizedTest
-    @EnumSource(value = PrivateEnum.class, mode = EnumSource.Mode.INCLUDE, names = {"COMPAS_ICDHEADER", "COMPAS_SYSTEM_VERSION"})
-    void getNetworkSettings_should_return_null_when_missing_ied_private(PrivateEnum missingPrivate) {
-        //Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-        SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
-        PrivateUtils.removePrivates(findIed(sclRootAdapter.getCurrentElem(), "IED_NAME2").getCurrentElem(), missingPrivate);
-        ControlBlockAdapter controlBlockAdapter = findControlBlock(sclRootAdapter.getCurrentElem(), "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", ControlBlockEnum.GSE);
-
-        //When
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-
-        //Then
-        assertThat(settingsOrError.errorMessage()).isEqualTo("No private %s found in this IED".formatted(missingPrivate.getPrivateType()));
-        assertThat(settingsOrError.settings()).isNull();
-    }
-
-    @ParameterizedTest
-    @MethodSource("provideInvalidCompasAttributes")
-    void getNetworkSettings_should_return_null_when_missing_ied_private_attributes(Consumer<IEDAdapter> transformIedPrivate) {
-        //Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
-        ControlBlockAdapter controlBlockAdapter = findControlBlock(scd, "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", ControlBlockEnum.GSE);
-        IEDAdapter iedAdapter = findIed(scd, "IED_NAME2");
-        transformIedPrivate.accept(iedAdapter);
-
-        //When
-        SettingsOrError settingsOrError = controlBlockNetworkSettings.getNetworkSettings(controlBlockAdapter);
-
-        //Then
-        assertThat(settingsOrError.errorMessage()).startsWith("No row found with these criteria ");
-        assertThat(settingsOrError.settings()).isNull();
-    }
-
-    private static Stream<Arguments> provideInvalidCompasAttributes() {
-        return Stream.of(
-                Arguments.of((Consumer<IEDAdapter>) iedAdapter -> iedAdapter.getCompasICDHeader().get().setIEDType(null)),
-                Arguments.of((Consumer<IEDAdapter>) iedAdapter -> iedAdapter.getCompasICDHeader().get().setIEDredundancy(null)),
-                Arguments.of((Consumer<IEDAdapter>) iedAdapter -> iedAdapter.getCompasICDHeader().get().setIEDSystemVersioninstance(null)),
-                Arguments.of((Consumer<IEDAdapter>) iedAdapter -> iedAdapter.getCompasSystemVersion().get().setMainSystemVersion(null)),
-                Arguments.of((Consumer<IEDAdapter>) iedAdapter -> iedAdapter.getCompasSystemVersion().get().setMinorSystemVersion(null)),
-                Arguments.of((Consumer<IEDAdapter>) iedAdapter -> iedAdapter.getCompasSystemVersion().get().setMinorSystemVersion("1")) // Invalid format for MinorSystemVersion
-        );
-    }
-
-}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapterTest.java
index 2e419e3d4..2e1d29687 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/ControlBlockAdapterTest.java
@@ -4,21 +4,18 @@
 
 package org.lfenergy.compas.sct.commons.scl.ied;
 
-import org.assertj.core.groups.Tuple;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
-import org.lfenergy.compas.scl2007b4.model.*;
-import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.scl2007b4.model.SCL;
+import org.lfenergy.compas.scl2007b4.model.TControl;
+import org.lfenergy.compas.scl2007b4.model.TControlWithIEDName;
+import org.lfenergy.compas.scl2007b4.model.TGSEControl;
 import org.lfenergy.compas.sct.commons.scl.ln.LN0Adapter;
 import org.lfenergy.compas.sct.commons.scl.ln.LNAdapter;
-import org.lfenergy.compas.sct.commons.testhelpers.SclHelper;
 import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
 import org.lfenergy.compas.sct.commons.util.ControlBlockEnum;
-import org.lfenergy.compas.sct.commons.util.SclConstructorHelper;
 
-import java.math.BigDecimal;
 import java.util.List;
-import java.util.Optional;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.findLn;
@@ -64,80 +61,4 @@ void addTargetIfNotExists_should_add_target(){
             .containsExactly("AP_NAME", "IED_NAME2", "LD_INST21", "1", List.of("ANCR"), "prefix");
     }
 
-    @Test
-    @Tag("issue-321")
-    void configureNetwork_should_add_GSE_element() {
-        // Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scl-ln-adapter/scd_with_ln.xml");
-        TConnectedAP connectedAP = SclHelper.addConnectedAp(scd, "SUB_NETWORK_NAME", "AP_NAME", "IED_NAME1");
-        LN0Adapter ln0 = findLn0(scd, "IED_NAME1", "LD_INST11");
-        // When
-        ln0.createDataSetIfNotExists("datSet", ControlBlockEnum.GSE);
-        // When
-        ControlBlockAdapter controlBlockAdapter = ln0.createControlBlockIfNotExists("cbName", "cbId", "datSet", ControlBlockEnum.GSE);
-        // When
-        Optional<SclReportItem> sclReportItem = controlBlockAdapter.configureNetwork(10L, "00-01-02-04-05", 11, (byte) 12, SclConstructorHelper.newDurationInMilliSec(3),
-            SclConstructorHelper.newDurationInMilliSec(20));
-        // Then
-        assertThat(sclReportItem).isEmpty();
-        assertThat(connectedAP.getGSE()).hasSize(1);
-        TGSE gse = connectedAP.getGSE().get(0);
-        assertThat(gse.getLdInst()).isEqualTo("LD_INST11");
-        assertThat(gse.getMinTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-            .containsExactly("s", "m", new BigDecimal("3"));
-        assertThat(gse.getMaxTime()).extracting(TDurationInMilliSec::getUnit, TDurationInMilliSec::getMultiplier, TDurationInMilliSec::getValue)
-            .containsExactly("s", "m", new BigDecimal("20"));
-        assertThat(gse.getAddress().getP()).extracting(TP::getType, TP::getValue)
-            .containsExactlyInAnyOrder(
-                Tuple.tuple("APPID", "000A"),
-                Tuple.tuple("MAC-Address", "00-01-02-04-05"),
-                Tuple.tuple("VLAN-ID", "00B"),
-                Tuple.tuple("VLAN-PRIORITY", "12")
-            );
-    }
-
-    @Test
-    @Tag("issue-321")
-    void configureNetwork_should_add_SMV_element() {
-        // Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scl-ln-adapter/scd_with_ln.xml");
-        TConnectedAP connectedAP = SclHelper.addConnectedAp(scd, "SUB_NETWORK_NAME", "AP_NAME", "IED_NAME1");
-        LN0Adapter ln0 = findLn0(scd, "IED_NAME1", "LD_INST11");
-        // When
-        ln0.createDataSetIfNotExists("datSet", ControlBlockEnum.SAMPLED_VALUE);
-        // When
-        ControlBlockAdapter controlBlockAdapter = ln0.createControlBlockIfNotExists("cbName", "cbId", "datSet", ControlBlockEnum.SAMPLED_VALUE);
-        // When
-        Optional<SclReportItem> sclReportItem = controlBlockAdapter.configureNetwork(10L, "00-01-02-04-05", 11, (byte) 12, null, null);
-        // Then
-        assertThat(sclReportItem).isEmpty();
-        assertThat(connectedAP.getSMV()).hasSize(1);
-        TSMV smv = connectedAP.getSMV().get(0);
-        assertThat(smv.getLdInst()).isEqualTo("LD_INST11");
-        assertThat(smv.getAddress().getP()).extracting(TP::getType, TP::getValue)
-            .containsExactlyInAnyOrder(
-                Tuple.tuple("APPID", "000A"),
-                Tuple.tuple("MAC-Address", "00-01-02-04-05"),
-                Tuple.tuple("VLAN-ID", "00B"),
-                Tuple.tuple("VLAN-PRIORITY", "12")
-            );
-    }
-
-    @Test
-    @Tag("issue-321")
-    void configureNetwork_when_connectApNotFound_should_return_sclReportItem() {
-        // Given
-        SCL scd = SclTestMarshaller.getSCLFromFile("/scl-ln-adapter/scd_with_ln.xml");
-        SclHelper.addConnectedAp(scd, "SUB_NETWORK_NAME", "AP_NAME", "IED_NAME2"); // ConnectedAp for IED_NAME2 instead of IED_NAME1
-        LN0Adapter ln0 = findLn0(scd, "IED_NAME1", "LD_INST11");
-        // When
-        ln0.createDataSetIfNotExists("datSet", ControlBlockEnum.SAMPLED_VALUE);
-        // When
-        ControlBlockAdapter controlBlockAdapter = ln0.createControlBlockIfNotExists("cbName", "cbId", "datSet", ControlBlockEnum.SAMPLED_VALUE);
-        // When
-        Optional<SclReportItem> sclReportItem = controlBlockAdapter.configureNetwork(10L, "00-01-02-04-05", 11, (byte) 12, null, null);
-        // Then
-        assertThat(sclReportItem).isPresent();
-    }
-
 }
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnumTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnumTest.java
index 7aa300377..b3444fecb 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnumTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/ControlBlockEnumTest.java
@@ -7,41 +7,44 @@
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.lfenergy.compas.scl2007b4.model.*;
+import org.lfenergy.compas.sct.commons.model.cbcom.TCBType;
 
 import java.util.stream.Stream;
 
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.lfenergy.compas.sct.commons.util.ControlBlockEnum.from;
 
 class ControlBlockEnumTest {
 
     @ParameterizedTest
     @MethodSource("provideFromTServiceType")
-    void from_should_map_ServiceType_to_ControlBlockEnumTest(TServiceType tServiceType, ControlBlockEnum expected) {
+    void from_TServiceType_should_map_ServiceType_to_ControlBlockEnumTest(TServiceType tServiceType, ControlBlockEnum expected) {
         //Given : parameter
         //When
-        ControlBlockEnum result = ControlBlockEnum.from(tServiceType);
+        ControlBlockEnum result = from(tServiceType);
         //Then
         assertThat(result).isEqualTo(expected);
     }
 
     @Test
-    void from_POOL_should_throw_exception() {
+    void from_TServiceType_POOL_should_throw_exception() {
         //Given
         TServiceType pollServiceType = TServiceType.POLL;
         //When & Then
-        assertThatThrownBy(() -> ControlBlockEnum.from(pollServiceType))
+        assertThatThrownBy(() -> from(pollServiceType))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
     @ParameterizedTest
     @MethodSource("provideFromTControlClass")
-    void from_should_map_Class_to_ControlBlockEnumTest(Class<? extends TControl> tControlClass, ControlBlockEnum expected) {
+    void from_TControl_should_map_Class_to_ControlBlockEnumTest(Class<? extends TControl> tControlClass, ControlBlockEnum expected) {
         //Given : parameter
         //When
-        ControlBlockEnum result = ControlBlockEnum.from(tControlClass);
+        ControlBlockEnum result = from(tControlClass);
         //Then
         assertThat(result).isEqualTo(expected);
     }
@@ -63,4 +66,30 @@ public static Stream<Arguments> provideFromTServiceType() {
         );
     }
 
+    @ParameterizedTest
+    @MethodSource("provideFromTCBType")
+    public void from_TCBType_when_GOOSE_or_SV_should_succeed(TCBType tcbType, ControlBlockEnum expectedControlBlockEnum){
+        // Given : parameter
+        // When
+        ControlBlockEnum result = from(tcbType);
+        // Then
+        assertThat(result).isEqualTo(expectedControlBlockEnum);
+    }
+
+    @ParameterizedTest
+    @EnumSource(value = TCBType.class, mode = EnumSource.Mode.EXCLUDE, names = {"GOOSE", "SV"})
+    public void from_TCBType_when_unsupported_TCBType_should_throw_exception(TCBType tcbType){
+        // Given : parameter
+        // When & Then
+        assertThatThrownBy(() -> from(tcbType))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessage("Unsupported TCBType: " + tcbType.name());
+    }
+
+    public static Stream<Arguments> provideFromTCBType() {
+        return Stream.of(
+                Arguments.of(TCBType.GOOSE, ControlBlockEnum.GSE),
+                Arguments.of(TCBType.SV, ControlBlockEnum.SAMPLED_VALUE)
+        );
+    }
 }
diff --git a/sct-commons/src/test/resources/ControlBlockCommunicationTemplates.csv b/sct-commons/src/test/resources/ControlBlockCommunicationTemplates.csv
deleted file mode 100644
index 5d149af69..000000000
--- a/sct-commons/src/test/resources/ControlBlockCommunicationTemplates.csv
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-FileCopyrightText: 2022 RTE FRANCE
-#
-# SPDX-License-Identifier: Apache-2.0
-
-#CB Type;X.Y;Z.W;IedType;IedRedundancy;IedSystemVersionInstance;Bay Internal OR External;VLAN-ID;VLAN-PRIORITY;MINTIME;MAXTIME
-GOOSE;01.00;009.001;BCU;A;1;BAY_INTERNAL;300;4;10;2000
-SV;01.00;009.001;BCU;A;1;BAY_INTERNAL;None;None;;
-GOOSE;01.00;009.001;BCU;A;1;BAY_EXTERNAL;301;5;15;5000
-SV;01.00;009.001;BCU;A;1;BAY_EXTERNAL;None;None;;