Merge "Solution: provide k8s based oam solution"
diff --git a/code/container-analysis/container-analysis.sh b/code/container-analysis/container-analysis.sh
index 880d7a0..b305be8 100755
--- a/code/container-analysis/container-analysis.sh
+++ b/code/container-analysis/container-analysis.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the 'License');
 # you may not use this file except in compliance with the License.
diff --git a/code/helpers/yang_file_name_with_revision.py b/code/helpers/yang_file_name_with_revision.py
index 6ef6bba..20a9103 100644
--- a/code/helpers/yang_file_name_with_revision.py
+++ b/code/helpers/yang_file_name_with_revision.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the 'License');
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/.gitignore b/code/network-generator/.gitignore
index 64369ef..9629efc 100644
--- a/code/network-generator/.gitignore
+++ b/code/network-generator/.gitignore
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/README.md b/code/network-generator/README.md
index 66a6326..e61d347 100644
--- a/code/network-generator/README.md
+++ b/code/network-generator/README.md
@@ -41,11 +41,16 @@
 - [o-ran-network.svg](output/o-ran-network.svg)
 - [o-ran-network.kml](output/o-ran-network.kml)
 
-
 ## Output validation
 
 ```
-yanglint -f json model/yang/ietf-network-topology.yang output/o-ran-network-operational.json
+yanglint \
+network_generation/model/yang/ietf-network.yang \
+network_generation/model/yang/ietf-network-topology.yang \
+network_generation/model/yang/o-ran-common-identity-refs.yang \
+network_generation/model/yang/o-ran-sc-network.yang \
+\
+output/o-ran-network-operational.json 
 ```
 
 ## Development
diff --git a/code/network-generator/network_generation/__init__.py b/code/network-generator/network_generation/__init__.py
index 21a1465..b70d170 100644
--- a/code/network-generator/network_generation/__init__.py
+++ b/code/network-generator/network_generation/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/network_generation/__main__.py b/code/network-generator/network_generation/__main__.py
index 5f86ae6..68ae56e 100644
--- a/code/network-generator/network_generation/__main__.py
+++ b/code/network-generator/network_generation/__main__.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/network_generation/base.py b/code/network-generator/network_generation/base.py
index bf1dab0..93d3ce3 100644
--- a/code/network-generator/network_generation/base.py
+++ b/code/network-generator/network_generation/base.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/network_generation/cli.py b/code/network-generator/network_generation/cli.py
index e156fcd..2c7b6ad 100644
--- a/code/network-generator/network_generation/cli.py
+++ b/code/network-generator/network_generation/cli.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
 import sys
 
 from network_generation.base import NetworkGenerator
-from network_generation.model.python.o_ran_network import ORanNetwork
 from network_generation.parameter_validator import ParameterValidator
 from network_generation.view.network_viewer import NetworkViewer
 
@@ -28,57 +27,55 @@
 """
 
 
+def save_viewer_output(
+    viewer: NetworkViewer,
+    filename: str,
+    task: dict[str, str] | dict[str, int],
+    method_name: str,
+) -> None:
+    """
+    Save the output using the specified method of NetworkViewer.
+    """
+    if task["enabled"]:
+        method = getattr(viewer, method_name, None)
+        if callable(method):
+            method(filename, task["compressed"])
+
+
 def main() -> None:  # pragma: no cover
     """
     The main function executes on commands:
     `python -m network_generation`.
-
     """
-    validator: ParameterValidator = ParameterValidator(sys.argv)
+    validator = ParameterValidator(sys.argv)
 
-    if validator.is_valid():
-        configuration: dict = validator.configuration()
-        generator: NetworkGenerator = NetworkGenerator(
-            configuration["network"]
-        )
-        network: ORanNetwork = generator.generate()
-        viewer: NetworkViewer = NetworkViewer(network)
-
-        output_folder: str = configuration["outputFolder"]
-        # If folder doesn't exist, then create it.
-        if not os.path.isdir(output_folder):
-            os.makedirs(output_folder)
-
-        name: str = str(configuration["network"]["name"]).lower()
-        filename: str = "/".join([output_folder, name])
-
-        # topology json
-        if configuration["generationTasks"]["topology"]["enabled"] is True:
-            viewer.json().save(
-                filename,
-                configuration["generationTasks"]["topology"]["compressed"]
-            )
-
-        # dir structure for day0 configuration
-        # Note: compressed option ignored
-        if configuration["generationTasks"]["network_dir"]["enabled"] is True:
-            viewer.to_directory(
-                output_folder
-            )
-
-        # svg xml
-        if configuration["generationTasks"]["svg"]["enabled"] is True:
-            viewer.svg(
-                filename,
-                configuration["generationTasks"]["svg"]["compressed"]
-            )
-
-        # kml/kmz xml
-        if configuration["generationTasks"]["kml"]["enabled"] is True:
-            viewer.kml(
-                filename,
-                configuration["generationTasks"]["kml"]["compressed"]
-            )
-
-    else:
+    if not validator.is_valid():
         print(validator.error_message())
+        return
+
+    configuration = validator.configuration()
+    generator = NetworkGenerator(configuration["network"])
+    network = generator.generate()
+    viewer = NetworkViewer(network)
+
+    output_folder = str(configuration["outputFolder"])
+    if not os.path.isdir(output_folder):
+        os.makedirs(output_folder)
+
+    name = str(configuration["network"]["name"]).lower()
+    filename = os.path.join(output_folder, name)
+
+    generation_tasks = configuration["generationTasks"]
+
+    # Dictionary mapping task keys to viewer method names
+    task_to_method = {
+        "rfc8345": "rfc8345",
+        "day0Config": "to_directory",
+        "svg": "svg",
+        "kml": "kml",
+    }
+
+    for task_key, method_name in task_to_method.items():
+        save_viewer_output(
+            viewer, filename, generation_tasks.get(task_key, {}), method_name
+        )
diff --git a/code/network-generator/network_generation/model/python/countries.py b/code/network-generator/network_generation/model/python/countries.py
index 0f08909..6e79a47 100644
--- a/code/network-generator/network_generation/model/python/countries.py
+++ b/code/network-generator/network_generation/model/python/countries.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A TypeDefinition as enum for countries
diff --git a/code/network-generator/network_generation/model/python/cube.py b/code/network-generator/network_generation/model/python/cube.py
index 2c5ef06..388ff45 100644
--- a/code/network-generator/network_generation/model/python/cube.py
+++ b/code/network-generator/network_generation/model/python/cube.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
 #
 # inspired by http://www.redblobgames.com/grids/hexagons/
 
-# !/usr/bin/python
+# !/usr/bin/python3
 from network_generation.model.python.hexagon import Hex
 
 
diff --git a/code/network-generator/network_generation/model/python/geo_location.py b/code/network-generator/network_generation/model/python/geo_location.py
index 64449f8..a59940c 100644
--- a/code/network-generator/network_generation/model/python/geo_location.py
+++ b/code/network-generator/network_generation/model/python/geo_location.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A collection of TypeDefinitions for a geographical location
diff --git a/code/network-generator/network_generation/model/python/hexagon.py b/code/network-generator/network_generation/model/python/hexagon.py
index 555c601..0496c56 100644
--- a/code/network-generator/network_generation/model/python/hexagon.py
+++ b/code/network-generator/network_generation/model/python/hexagon.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
 #
 # inspired by http://www.redblobgames.com/grids/hexagons/
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 from __future__ import division, print_function
 
diff --git a/code/network-generator/network_generation/model/python/nr_cell_du.py b/code/network-generator/network_generation/model/python/nr_cell_du.py
index 13fc42b..1fea1a3 100644
--- a/code/network-generator/network_generation/model/python/nr_cell_du.py
+++ b/code/network-generator/network_generation/model/python/nr_cell_du.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing a 3GPP new radio cell du (NrCellDu)
@@ -112,9 +112,10 @@
 
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
-        result.append(ORanTerminationPoint(
-            {"id": self.name, "name": self.name}
-        ))
+        result.append(ORanTerminationPoint({
+            "name": self.name,
+            "type": "o-ran-sc-network:cell"
+        }))
         return result
 
     def to_topology_nodes(self) -> list[dict[str, Any]]:
@@ -127,28 +128,16 @@
         result: list[dict[str, Any]] = []  # super().to_topology_links()
         return result
 
-    def toKml(self) -> ET.Element:
-        placemark: ET.Element = ET.Element("Placemark")
-        name: ET.Element = ET.SubElement(placemark, "name")
-        name.text = self.name
-        style: ET.Element = ET.SubElement(placemark, "styleUrl")
-        style.text = "#" + self.__class__.__name__
-        multi_geometry: ET.Element = ET.SubElement(placemark, "MultiGeometry")
-        polygon: ET.Element = ET.SubElement(multi_geometry, "Polygon")
-        outer_boundary: ET.Element = ET.SubElement(polygon, "outerBoundaryIs")
-        linear_ring: ET.Element = ET.SubElement(outer_boundary, "LinearRing")
-        coordinates: ET.Element = ET.SubElement(linear_ring, "coordinates")
-
+    # returns a list of geo-locations as cell polygon
+    def get_cell_polygons(self) -> list[GeoLocation]:
         points: list[Point] = Hexagon.polygon_corners(
             self.layout, self.position
         )
         method = (
             self.parent.parent.parent.parent.parent.parent
-            .geo_location.point_to_geo_location
+                .geo_location.point_to_geo_location
         )
         geo_locations: list[GeoLocation] = list(map(method, points))
-        text: list[str] = []
-
         index: int = 1 + int(self._azimuth / self._cell_angle)
         network_center: GeoLocation = (
             self.parent.parent.parent.parent.parent.parent.geo_location
@@ -186,24 +175,8 @@
         # close polygon
         cell_polygon.append(tower)
 
-        for gl in cell_polygon:
-            strs: list[str] = [
-                str("%.6f" % float(gl.longitude)),
-                str("%.6f" % float(gl.latitude)),
-                str("%.6f" % float(gl.aboveMeanSeaLevel)),
-            ]
-            text.append(",".join(strs))
-        coordinates.text = " ".join(text)
-
         if self.cell_scale_factor > 0:
-            scaled_polygon: ET.Element = ET.SubElement(
-                multi_geometry, "Polygon")
-            scaled_outer_boundary: ET.Element = ET.SubElement(
-                scaled_polygon, "outerBoundaryIs")
-            scaled_linear_ring: ET.Element = ET.SubElement(
-                scaled_outer_boundary, "LinearRing")
-            scaled_coordinates: ET.Element = ET.SubElement(
-                scaled_linear_ring, "coordinates")
+            scaled_cell_polygon: list[GeoLocation] = []
 
             arc: float = self.azimuth * math.pi / 180
             meterToDegree: float = (
@@ -219,23 +192,48 @@
                 }
             )
             point_index: int = 0
-            text = []
+            scale: float = 1 + self.cell_scale_factor / 100
             for gl in cell_polygon:
-                scale: float = 1 + self.cell_scale_factor / 100
                 lng_new: float = (
                     1 * scale * (gl.longitude - cell_center.longitude)
                 ) + cell_center.longitude
                 lat_new: float = (
                     1 * scale * (gl.latitude - cell_center.latitude)
                 ) + cell_center.latitude
-                scaled_strs: list[str] = [
-                    str("%.6f" % float(lng_new)),
-                    str("%.6f" % float(lat_new)),
-                    str("%.6f" % float(gl.aboveMeanSeaLevel)),
-                ]
-                text.append(",".join(scaled_strs))
+
+                data: IGeoLocation = {
+                    "latitude": lat_new,
+                    "longitude": lng_new,
+                    "aboveMeanSeaLevel": gl.aboveMeanSeaLevel,
+                }
+
+                scaled_cell_polygon.append(GeoLocation(data))
                 point_index += 1
-            scaled_coordinates.text = " ".join(text)
+            cell_polygon = scaled_cell_polygon
+        return cell_polygon
+
+    def toKml(self) -> ET.Element:
+        placemark: ET.Element = ET.Element("Placemark")
+        name: ET.Element = ET.SubElement(placemark, "name")
+        name.text = self.name
+        style: ET.Element = ET.SubElement(placemark, "styleUrl")
+        style.text = "#" + self.__class__.__name__
+        multi_geometry: ET.Element = ET.SubElement(placemark, "MultiGeometry")
+        polygon: ET.Element = ET.SubElement(multi_geometry, "Polygon")
+        outer_boundary: ET.Element = ET.SubElement(polygon, "outerBoundaryIs")
+        linear_ring: ET.Element = ET.SubElement(outer_boundary, "LinearRing")
+        coordinates: ET.Element = ET.SubElement(linear_ring, "coordinates")
+
+        cell_polygon: list[GeoLocation] = self.get_cell_polygons()
+        text: list[str] = []
+        for gl in cell_polygon:
+            strs: list[str] = [
+                str("%.6f" % float(gl.longitude)),
+                str("%.6f" % float(gl.latitude)),
+                str("%.6f" % float(gl.aboveMeanSeaLevel)),
+            ]
+            text.append(",".join(strs))
+        coordinates.text = " ".join(text)
         return placemark
 
     def toSvg(self) -> ET.Element:
diff --git a/code/network-generator/network_generation/model/python/o_ran_cloud_du.py b/code/network-generator/network_generation/model/python/o_ran_cloud_du.py
index d3a4d10..877019e 100644
--- a/code/network-generator/network_generation/model/python/o_ran_cloud_du.py
+++ b/code/network-generator/network_generation/model/python/o_ran_cloud_du.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing an O-RAN O-Cloud resource pool for O-RAN distributed units
@@ -52,6 +52,7 @@
         o_ran_cloud_du_data: IORanCloudDu = self._to_o_ran_cloud_du_data(data)
 
         super().__init__(cast(dict[str, Any], o_ran_cloud_du_data), **kwargs)
+        self.type = "o-ran-sc-network:o-cloud"
         self._towers: list[Tower] = self._calculate_towers()
 
     def _to_o_ran_cloud_du_data(self, data: dict[str, Any]) -> IORanCloudDu:
@@ -63,10 +64,11 @@
 
     def _calculate_towers(self) -> list[Tower]:
         hex_ring_radius: int = (
-            self.parent.parent.parent.parent
-            .spiral_radius_profile.oRanDuSpiralRadiusOfTowers
+            self.parent.parent.parent.parent.spiral_radius_profile
+                .oRanDuSpiralRadiusOfTowers
         )
-        hex_list: list[Hex] = Cube.spiral(self.position, hex_ring_radius)
+        hex_list: list[Hex] = Cube.spiral(
+            self.position, hex_ring_radius)
         result: list[Tower] = []
         for index, hex in enumerate(hex_list):
             s: str = "00" + str(index)
@@ -90,6 +92,7 @@
                         "position": hex,
                         "layout": self.layout,
                         "parent": self,
+                        "network": self.network,
                     }
                 )
             )
@@ -102,26 +105,18 @@
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["o2"]:
             id: str = "-".join([self.name, interface.upper()])
-            result.append(
-                ORanTerminationPoint(
-                    {"id": id, "name": id, "supporter": phy_tp, "parent": self}
-                )
-            )
-        return result
-
-    def to_topology_nodes(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_nodes()
-        for tower in self.towers:
-            result.extend(tower.to_topology_nodes())
-        return result
-
-    def to_topology_links(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_links()
-        for tower in self.towers:
-            result.extend(tower.to_topology_links())
+            result.append(ORanTerminationPoint({
+                    "name": id,
+                    "type": ":".join(["o-ran-sc-network", interface]),
+                    "supporter": phy_tp,
+                    "parent": self
+                }))
         return result
 
     def toKml(self) -> ET.Element:
@@ -140,3 +135,33 @@
     def to_directory(self, parent_dir: str) -> None:
         for tower in self.towers:
             tower.to_directory(parent_dir)
+
+    def _extend_with_tower_references(
+        self: Any, super_method: Any, tower_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from towers.
+
+        :param super_method: The superclass method to call for the initial
+               result.
+        :param tower_method_name: The method name to call on each tower.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        for tower in self.towers:
+            result.extend(
+                self.flatten_list(getattr(tower, tower_method_name)())
+            )
+        return result
+
+    def to_topology_nodes(self) -> list[dict[str, Any]]:
+        return self._extend_with_tower_references(
+            super().to_topology_nodes,
+            "to_topology_nodes",
+        )
+
+    def to_topology_links(self) -> list[dict[str, Any]]:
+        return self._extend_with_tower_references(
+            super().to_topology_links,
+            "to_topology_links",
+        )
diff --git a/code/network-generator/network_generation/model/python/o_ran_cu.py b/code/network-generator/network_generation/model/python/o_ran_cu.py
index 2df40f6..1098d10 100644
--- a/code/network-generator/network_generation/model/python/o_ran_cu.py
+++ b/code/network-generator/network_generation/model/python/o_ran_cu.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing an O-RAN centralized unit (ORanCu)
@@ -48,6 +48,7 @@
     ) -> None:
         o_ran_cu_data: IORanCu = self._to_o_ran_cu_data(data)
         super().__init__(cast(dict[str, Any], o_ran_cu_data), **kwargs)
+        self.type = "o-ran-common-identity-refs:o-cu-function"
         self._o_ran_cloud_dus: list[ORanCloudDu] = self._calculate_o_ran_dus()
 
     def _to_o_ran_cu_data(self, data: dict[str, Any]) -> IORanCu:
@@ -59,13 +60,13 @@
 
     def _calculate_o_ran_dus(self) -> list[ORanCloudDu]:
         hex_ring_radius: int = (
-            self.parent.parent.parent
-            .spiral_radius_profile.oRanCuSpiralRadiusOfODus
+            self.parent.parent.parent.spiral_radius_profile
+                .oRanCuSpiralRadiusOfODus
         )
-        hex_list: list[
-            Hex
-        ] = self.parent.parent.parent.spiral_radius_profile.oRanDuSpiral(
-            self.position, hex_ring_radius
+        hex_list: list[Hex] = (
+            self.parent.parent.parent.spiral_radius_profile.oRanDuSpiral(
+                self.position, hex_ring_radius
+            )
         )
         result: list[ORanCloudDu] = []
         for index, hex in enumerate(hex_list):
@@ -85,6 +86,7 @@
                         "position": hex,
                         "layout": self.layout,
                         "parent": self,
+                        "network": self.network,
                     }
                 )
             )
@@ -105,30 +107,17 @@
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"tp-id": phy_tp, "name": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["e2", "o1"]:
             id: str = "-".join([self.name, interface.upper()])
-            result.append(
-                ORanTerminationPoint(
-                    {"id": id, "name": id, "supporter": phy_tp, "parent": self}
-                )
-            )
-        return result
-
-    def to_topology_nodes(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_nodes()
-        # for o_ran_du in self.o_ran_dus: # TODO
-        #     result.extend(o_ran_du.to_topology_nodes())
-        for o_ran_cloud_du in self.o_ran_cloud_dus:
-            result.extend(o_ran_cloud_du.to_topology_nodes())
-        return result
-
-    def to_topology_links(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_links()
-        # for o_ran_du in self.o_ran_dus:
-        # result.extend(o_ran_du.to_topology_links())
-        for o_ran_cloud_du in self.o_ran_cloud_dus:
-            result.extend(o_ran_cloud_du.to_topology_links())
+            result.append(ORanTerminationPoint({
+                "name": id,
+                "supporter": phy_tp,
+                "parent": self
+            }))
         return result
 
     def toKml(self) -> ET.Element:
@@ -147,3 +136,36 @@
     def to_directory(self, parent_dir: str) -> None:
         for o_ran_cloud_du in self.o_ran_cloud_dus:
             o_ran_cloud_du.to_directory(parent_dir)
+
+    def _extend_with_o_ran_cloud_du_references(
+        self: Any, super_method: Any, o_ran_cloud_du_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from o_ran_cloud_dus.
+
+        :param super_method: The superclass method to call for the initial
+                             result.
+        :param o_ran_cloud_du_method_name: The method name to call on each
+                                           o_ran_cloud_du.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        for o_ran_cloud_du in self.o_ran_cloud_dus:
+            result.extend(
+                self.flatten_list(
+                    getattr(o_ran_cloud_du, o_ran_cloud_du_method_name)()
+                )
+            )
+        return result
+
+    def to_topology_nodes(self) -> list[dict[str, Any]]:
+        return self._extend_with_o_ran_cloud_du_references(
+            super().to_topology_nodes,
+            "to_topology_nodes",
+        )
+
+    def to_topology_links(self) -> list[dict[str, Any]]:
+        return self._extend_with_o_ran_cloud_du_references(
+            super().to_topology_links,
+            "to_topology_links",
+        )
diff --git a/code/network-generator/network_generation/model/python/o_ran_du.py b/code/network-generator/network_generation/model/python/o_ran_du.py
index 98e8c1a..8dddf5c 100644
--- a/code/network-generator/network_generation/model/python/o_ran_du.py
+++ b/code/network-generator/network_generation/model/python/o_ran_du.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,13 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing an O-RAN distributed unit (ORanDu)
 """
-import xml.etree.ElementTree as ET
 import os
+import xml.etree.ElementTree as ET
 from typing import Any, cast
 
 from network_generation.model.python.o_ran_node import IORanNode, ORanNode
@@ -46,16 +46,16 @@
     def __init__(
         self,
         data: dict[str, Any] = cast(dict[str, Any], default_value),
-        **kwargs: dict[str, Any]
+        **kwargs: dict[str, Any],
     ) -> None:
         o_ran_du_data: IORanDu = self._to_o_ran_du_data(data)
         super().__init__(cast(dict[str, Any], o_ran_du_data), **kwargs)
+        self.type = "o-ran-common-identity-refs:o-du-function"
         self._o_ran_ru_count = (
             o_ran_du_data["oRanRuCount"]
             if o_ran_du_data and "oRanRuCount" in o_ran_du_data
             else 1
         )
-        self.type = "ntsim-ng-o-du"
 
     def _to_o_ran_du_data(self, data: dict[str, Any]) -> IORanDu:
         result: IORanDu = default_value
@@ -65,16 +65,21 @@
         return result
 
     def termination_points(self) -> list[ORanTerminationPoint]:
-        result: list[ORanTerminationPoint] = super().termination_points()
+        result: list[ORanTerminationPoint] = super(
+            ).termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu", "ofhs"]:
             id: str = "-".join([self.name, interface.upper()])
-            result.append(
-                ORanTerminationPoint(
-                    {"id": id, "name": id, "supporter": phy_tp, "parent": self}
-                )
-            )
+            result.append(ORanTerminationPoint({
+                     "name": id,
+                     "type": ":".join(["o-ran-sc-network", interface]),
+                     "supporter": phy_tp,
+                     "parent": self
+            }))
         return result
 
     def to_topology_nodes(self) -> list[dict[str, Any]]:
@@ -84,11 +89,14 @@
     def to_topology_links(self) -> list[dict[str, Any]]:
         result: list[dict[str, Any]] = super().to_topology_links()
         for interface in ["e2", "o1"]:
+            destination_node = self.parent.parent
+            if interface == "o1":
+                destination_node = self.parent.parent.parent
             link_id: str = "".join(
-                [interface, ":", self.name, "<->", self.parent.name]
+                [interface, ":", self.name, "<->", destination_node.name]
             )
             source_tp: str = "-".join([self.name, interface.upper()])
-            dest_tp: str = "-".join([self.parent.name, interface.upper()])
+            dest_tp: str = "-".join([destination_node.name, interface.upper()])
             result.append(
                 {
                     "link-id": link_id,
@@ -97,7 +105,7 @@
                         "source-tp": source_tp,
                     },
                     "destination": {
-                        "dest-node": self.parent.name,
+                        "dest-node": destination_node.name,
                         "dest-tp": dest_tp,
                     },
                 }
diff --git a/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py b/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py
index 17208f8..47579b7 100644
--- a/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py
+++ b/code/network-generator/network_generation/model/python/o_ran_near_rt_ric.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing an O-RAN Near real-time intelligent controller
@@ -52,6 +52,7 @@
         super().__init__(
             cast(dict[str, Any], o_ran_near_rt_ric_data), **kwargs
         )
+        self.type = "o-ran-sc-network:near-rt-ric"
         self._o_ran_cus: list[ORanCu] = self._calculate_o_ran_cus()
 
     def _to_o_ran_near_rt_ric_data(
@@ -65,13 +66,13 @@
 
     def _calculate_o_ran_cus(self) -> list[ORanCu]:
         hex_ring_radius: int = (
-            self.parent.parent
-            .spiral_radius_profile.oRanNearRtRicSpiralRadiusOfOCus
+            self.parent.parent.spiral_radius_profile
+                .oRanNearRtRicSpiralRadiusOfOCus
         )
-        hex_list: list[
-            Hex
-        ] = self.parent.parent.spiral_radius_profile.oRanCuSpiral(
-            self.position, hex_ring_radius
+        hex_list: list[Hex] = (
+            self.parent.parent.spiral_radius_profile.oRanCuSpiral(
+                self.position, hex_ring_radius
+            )
         )
         result: list[ORanCu] = []
         for index, hex in enumerate(hex_list):
@@ -91,6 +92,7 @@
                         "position": hex,
                         "layout": self.layout,
                         "parent": self,
+                        "network": self.network,
                     }
                 )
             )
@@ -111,26 +113,18 @@
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"tp-id": phy_tp, "name": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["a1", "o1", "o2", "e2"]:
             id: str = "-".join([self.name, interface.upper()])
-            result.append(
-                ORanTerminationPoint(
-                    {"id": id, "name": id, "supporter": phy_tp, "parent": self}
-                )
-            )
-        return result
-
-    def to_topology_nodes(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_nodes()
-        for o_ran_cu in self.o_ran_cus:
-            result.extend(o_ran_cu.to_topology_nodes())
-        return result
-
-    def to_topology_links(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_links()
-        for o_ran_cu in self.o_ran_cus:
-            result.extend(o_ran_cu.to_topology_links())
+            result.append(ORanTerminationPoint({
+                     "name": id,
+                     "type": ":".join(["o-ran-sc-network", interface]),
+                     "supporter": phy_tp,
+                     "parent": self
+            }))
         return result
 
     def toKml(self) -> ET.Element:
@@ -149,3 +143,31 @@
     def to_directory(self, parent_dir: str) -> None:
         for o_ran_cu in self.o_ran_cus:
             o_ran_cu.to_directory(parent_dir)
+
+    def _extend_with_o_ran_cu_references(
+        self: Any, super_method: Any, o_ran_cu_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from o_ran_cus.
+
+        :param super_method: The superclass method to call for the initial
+                             result.
+        :param o_ran_cu_method_name: The method name to call on each o_ran_cu.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        for o_ran_cu in self.o_ran_cus:
+            result.extend(
+                self.flatten_list(getattr(o_ran_cu, o_ran_cu_method_name)())
+            )
+        return result
+
+    def to_topology_nodes(self) -> list[dict[str, Any]]:
+        return self._extend_with_o_ran_cu_references(
+            super().to_topology_nodes, "to_topology_nodes"
+        )
+
+    def to_topology_links(self) -> list[dict[str, Any]]:
+        return self._extend_with_o_ran_cu_references(
+            super().to_topology_links, "to_topology_links"
+        )
diff --git a/code/network-generator/network_generation/model/python/o_ran_network.py b/code/network-generator/network_generation/model/python/o_ran_network.py
index 901e83f..2073d42 100644
--- a/code/network-generator/network_generation/model/python/o_ran_network.py
+++ b/code/network-generator/network_generation/model/python/o_ran_network.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies GmbH
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,12 +12,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 """
 Module for a class representing a O-RAN Network
 """
-import xml.etree.ElementTree as ET
 import os
+import uuid
+import xml.etree.ElementTree as ET
+from datetime import datetime, timezone
 from typing import Any, cast
 
 import network_generation.model.python.hexagon as Hexagon
@@ -36,8 +38,10 @@
 )
 from network_generation.model.python.point import Point
 
+
 # Define the "IORanNetwork" interface
-IORanNetwork = IORanObject
+class IORanNetwork(IORanObject):
+    network: Any
 
 
 class ORanNetwork(ORanObject):
@@ -47,12 +51,23 @@
 
     __my_default_value: IORanNetwork = cast(IORanNetwork, ORanObject.default())
 
+    __my_network_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, "Operator A"))
+
+    # Get the current date and time in UTC
+    __current_time = datetime.now(timezone.utc)
+    # Format the time string as required
+    __time_string = __current_time.strftime("%Y-%m-%dT%H:%M:%SZ")
+    __my_valid_for = {
+        "startDateTime": f'{__current_time.strftime("%Y")}-01-01T00:00:00Z',
+        "endDateTime": f'{__current_time.strftime("%Y")}-12-31T23:59:59Z',
+    }
+
     # constructor
     def __init__(
         self,
         configuration: dict[str, dict],
         data: dict[str, Any] = cast(dict[str, Any], __my_default_value),
-        **kwargs: dict[str, Any]
+        **kwargs: dict[str, Any],
     ) -> None:
         o_ran_network_data: IORanNetwork = self._to_o_ran_network_data(data)
         super().__init__(cast(dict[str, Any], o_ran_network_data), **kwargs)
@@ -86,9 +101,9 @@
                 "oRanNearRtRicSpiralRadiusOfOCus": configuration["pattern"][
                     "nearRtRic"
                 ]["oRanCuSpiralRadius"],
-                "oRanCuSpiralRadiusOfODus": configuration["pattern"][
-                    "oRanCu"
-                ]["oRanDuSpiralRadius"],
+                "oRanCuSpiralRadiusOfODus": configuration["pattern"]["oRanCu"][
+                    "oRanDuSpiralRadius"
+                ],
                 "oRanDuSpiralRadiusOfTowers": configuration["pattern"][
                     "oRanDu"
                 ]["towerSpiralRadius"],
@@ -100,6 +115,7 @@
                 "geoLocation": self.center,
                 "layout": layout,
                 "parent": self,
+                "network": self,
             }
         )
 
@@ -142,6 +158,7 @@
                 "network": [
                     {
                         "network-id": self.id,
+                        "o-ran-sc-network:name": self.name,
                         "node": nodes,
                         "ietf-network-topology:link": links,
                     }
diff --git a/code/network-generator/network_generation/model/python/o_ran_node.py b/code/network-generator/network_generation/model/python/o_ran_node.py
index 8dba3bc..569f2ec 100644
--- a/code/network-generator/network_generation/model/python/o_ran_node.py
+++ b/code/network-generator/network_generation/model/python/o_ran_node.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,18 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 An abstract Class for O-RAN Node
 """
+import uuid
 import xml.etree.ElementTree as ET
 from abc import abstractmethod
+from datetime import datetime, timezone
 from typing import Any, cast
 
 import network_generation.model.python.hexagon as Hexagon
 from network_generation.model.python.countries import Country
-from network_generation.model.python.geo_location import GeoLocation
+from network_generation.model.python.geo_location import (
+    GeoLocation,
+)
 from network_generation.model.python.hexagon import Hex, Layout
 from network_generation.model.python.o_ran_object import (
     IORanObject,
@@ -48,6 +52,7 @@
     layout: Layout
     spiralRadiusProfile: SpiralRadiusProfile
     parent: Any
+    network: Any
 
 
 default_address: AddressType = {
@@ -71,6 +76,7 @@
             "layout": Layout(Hexagon.layout_flat, Point(1, 1), Point(0, 0)),
             "spiralRadiusProfile": SpiralRadiusProfile(),
             "parent": None,
+            "network": None,
         },
     },
 )
@@ -78,6 +84,12 @@
 
 # Define an abstract O-RAN Node class
 class ORanNode(ORanObject):
+
+    # Get the current date and time in UTC
+    __current_time = datetime.now(timezone.utc)
+    # Format the time string as required
+    __time_string = __current_time.strftime("%Y-%m-%dT%H:%M:%SZ")
+
     @staticmethod
     def default() -> dict[str, Any]:
         return cast(dict[str, Any], default_value)
@@ -85,7 +97,7 @@
     def __init__(
         self,
         data: dict[str, Any] = cast(dict[str, Any], default_value),
-        **kwargs: dict[str, Any]
+        **kwargs: dict[str, Any],
     ) -> None:
         o_ran_node_data: IORanNode = self._to_o_ran_node_data(data)
         super().__init__(cast(dict[str, Any], data), **kwargs)
@@ -102,6 +114,7 @@
             SpiralRadiusProfile, o_ran_node_data["spiralRadiusProfile"]
         )
         self._parent: Any = o_ran_node_data["parent"]
+        self._network: Any = o_ran_node_data["network"]
         self._termination_points: list[ORanTerminationPoint] = []
 
     def _to_o_ran_node_data(self, data: dict[str, Any]) -> IORanNode:
@@ -169,6 +182,16 @@
     def parent(self, value: Any) -> None:
         self._parent = value
 
+    @property
+    def network(
+        self,
+    ) -> Any:  # expected is ORanNetwork
+        return self._network
+
+    @network.setter
+    def network(self, value: Any) -> None:
+        self._network = value
+
     # @property
     # @abstractmethod
     def termination_points(self) -> list[ORanTerminationPoint]:
@@ -178,12 +201,25 @@
     def to_topology_nodes(self) -> list[dict[str, Any]]:
         tps: list[dict[str, Any]] = []
         for tp in self.termination_points():
-            tps.append(tp.to_topology())
+            new_tp = tp.to_topology()
+            if any(
+                existing_tp["tp-id"] == new_tp["tp-id"] for existing_tp in tps
+            ):
+                pass
+            else:
+                tps.append(new_tp)
 
         result: list[dict[str, Any]] = []
         result.append(
             {
                 "node-id": self.name,
+                "o-ran-sc-network:uuid": str(
+                    uuid.uuid5(
+                        uuid.NAMESPACE_DNS,
+                        "-".join([self.network.name, self.name]),
+                    )
+                ),
+                "o-ran-sc-network:type": self.type,
                 "ietf-network-topology:termination-point": tps,
             }
         )
diff --git a/code/network-generator/network_generation/model/python/o_ran_object.py b/code/network-generator/network_generation/model/python/o_ran_object.py
index ef74b30..5e1789c 100644
--- a/code/network-generator/network_generation/model/python/o_ran_object.py
+++ b/code/network-generator/network_generation/model/python/o_ran_object.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 An abstract Class for O-RAN Objects
@@ -42,6 +42,7 @@
             **super().json(),
             "id": self.id,
             "name": self.name,
+            "type": self.type,
             "administrativeState": self.administrativeState,
             "operationalState": self.operationalState,
             "lifeCycleState": self.lifeCycleState,
@@ -49,3 +50,12 @@
             "usageState": self.usageState,
             "utilization": self.utilization,
         }
+
+    def flatten_list(self, nested_list: list) -> list:
+        flat_list = []
+        for item in nested_list:
+            if isinstance(item, list):
+                flat_list.extend(self.flatten_list(item))
+            else:
+                flat_list.append(item)
+        return flat_list
diff --git a/code/network-generator/network_generation/model/python/o_ran_ru.py b/code/network-generator/network_generation/model/python/o_ran_ru.py
index c88dfec..34f77a3 100644
--- a/code/network-generator/network_generation/model/python/o_ran_ru.py
+++ b/code/network-generator/network_generation/model/python/o_ran_ru.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,13 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing an O-RAN radio unit (ORanRu)
 """
-import xml.etree.ElementTree as ET
 import os
+import xml.etree.ElementTree as ET
 from typing import Any, cast
 
 from network_generation.model.python.nr_cell_du import NrCellDu
@@ -50,10 +50,11 @@
     def __init__(
         self,
         data: dict[str, Any] = cast(dict[str, Any], default_value),
-        **kwargs: dict[str, Any]
+        **kwargs: dict[str, Any],
     ) -> None:
         o_ran_ru_data: IORanRu = self._to_o_ran_ru_data(data)
         super().__init__(cast(dict[str, Any], o_ran_ru_data), **kwargs)
+        self.type = "o-ran-common-identity-refs:o-ru-function"
         self._cell_count: int = (
             int(str(o_ran_ru_data["cellCount"]))
             if o_ran_ru_data and "cellCount" in o_ran_ru_data
@@ -71,7 +72,6 @@
         )
         self._cells: list[NrCellDu] = self._create_cells()
         name: str = self.name.replace("RU", "DU")
-        self.type = "ntsim-ng-o-ru"
 
         o_ran_du_data: dict[str, Any] = {
             "name": name,
@@ -79,6 +79,7 @@
             "position": self.parent.position,
             "layout": self.layout,
             "parent": self.parent.parent.parent,
+            "network": self.network,
         }
         self._oRanDu: ORanDu = ORanDu(o_ran_du_data)
 
@@ -92,13 +93,12 @@
     def _create_cells(self) -> list[NrCellDu]:
         result: list[NrCellDu] = []
         cell_config: dict = (
-            self.parent.parent.parent.parent.parent.parent
-            .configuration["pattern"]["nrCellDu"]
+            self.parent.parent.parent.parent.parent.parent.configuration[
+                "pattern"
+            ]["nrCellDu"]
         )
         cell_angle: int = cell_config["cellAngle"]
-        cell_scale_factor: int = (
-            cell_config["cellScaleFactorForHandoverArea"]
-        )
+        cell_scale_factor: int = cell_config["cellScaleFactorForHandoverArea"]
         maxReach: int = cell_config["maxReach"]
         for index in range(self._cell_count):
             s: str = "00" + str(index)
@@ -114,6 +114,7 @@
                         "position": self.position,
                         "layout": self.layout,
                         "parent": self,
+                        "network": self.network,
                         "cellAngle": cell_angle,
                         "cellScaleFactorForHandoverArea": cell_scale_factor,
                         "maxReach": maxReach,
@@ -134,14 +135,18 @@
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["ofhm", "ofhc", "ofhu", "ofhs"]:
             id: str = "-".join([self.name, interface.upper()])
-            result.append(
-                ORanTerminationPoint(
-                    {"id": id, "name": id, "supporter": phy_tp, "parent": self}
-                )
-            )
+            result.append(ORanTerminationPoint({
+                "name": id,
+                "type": ":".join(["o-ran-sc-network", interface]),
+                "supporter": phy_tp,
+                "parent": self
+            }))
         for cell in self.cells:
             result.extend(cell.termination_points())
         return result
@@ -196,3 +201,20 @@
             os.makedirs(parent_path, exist_ok=True)
         if not os.path.exists(path):
             os.mkdir(path)
+
+    def _extend_with_cell_references(
+        self: Any, super_method: Any, cell_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from cells.
+
+        :param super_method: The superclass method to call for the initial
+                             result.
+        :param cell_method_name: The method name to call on each cell.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        result.extend(getattr(self.oRanDu, cell_method_name)())
+        for cell in self.cells:
+            result.extend(self.flatten_list(getattr(cell, cell_method_name)()))
+        return result
diff --git a/code/network-generator/network_generation/model/python/o_ran_smo.py b/code/network-generator/network_generation/model/python/o_ran_smo.py
index d9a7e9a..4fd1cd2 100644
--- a/code/network-generator/network_generation/model/python/o_ran_smo.py
+++ b/code/network-generator/network_generation/model/python/o_ran_smo.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing an O-RAN Service Management and
@@ -52,10 +52,11 @@
     ) -> None:
         o_ran_smo_data: IORanSmo = self._to_o_ran_smo_data(data)
         super().__init__(cast(dict[str, Any], o_ran_smo_data), **kwargs)
+        self.type = "o-ran-sc-network:smo"
         if self.parent is not None:
-            self._o_ran_near_rt_rics: list[
-                ORanNearRtRic
-            ] = self._calculate_near_rt_rics()
+            self._o_ran_near_rt_rics: list[ORanNearRtRic] = (
+                self._calculate_near_rt_rics()
+            )
 
     def _calculate_near_rt_rics(self) -> list[ORanNearRtRic]:
         hex_ring_radius: int = (
@@ -63,10 +64,10 @@
             if self.parent is not None
             else 1
         )
-        hex_list: list[
-            Hex
-        ] = self.parent.spiral_radius_profile.oRanNearRtRicSpiral(
-            self.position, hex_ring_radius
+        hex_list: list[Hex] = (
+            self.parent.spiral_radius_profile.oRanNearRtRicSpiral(
+                self.position, hex_ring_radius
+            )
         )
         result: list[ORanNearRtRic] = []
         for index, hex in enumerate(hex_list):
@@ -86,6 +87,7 @@
                         "position": hex,
                         "layout": self.layout,
                         "parent": self,
+                        "network": self.network,
                     },
                 )
             )
@@ -114,31 +116,18 @@
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["a1", "o1", "o2"]:
             id: str = "-".join([self.name, interface.upper()])
-            result.append(
-                ORanTerminationPoint(
-                    {
-                        "id": id,
-                        "name": id,
-                        "supporter": phy_tp,
-                        "parent": self,
-                    },
-                )
-            )
-        return result
-
-    def to_topology_nodes(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_nodes()
-        for ric in self.o_ran_near_rt_rics:
-            result.extend(ric.to_topology_nodes())
-        return result
-
-    def to_topology_links(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = []  # super().to_topology_links()
-        for ric in self.o_ran_near_rt_rics:
-            result.extend(ric.to_topology_links())
+            result.append(ORanTerminationPoint({
+                     "name": id,
+                     "type": ":".join(["o-ran-sc-network", interface]),
+                     "supporter": phy_tp,
+                     "parent": self
+            }))
         return result
 
     def toKml(self) -> ET.Element:
@@ -157,3 +146,30 @@
     def to_directory(self, parent_dir: str) -> None:
         for ric in self.o_ran_near_rt_rics:
             ric.to_directory(parent_dir)
+
+    def _extend_with_ric_references(
+        self: Any, super_method: Any, ric_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from
+        o_ran_near_rt_rics.
+
+        :param super_method: The superclass method to call for the initial
+                             result.
+        :param ric_method_name: The method name to call on each ric.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        for ric in self.o_ran_near_rt_rics:
+            result.extend(self.flatten_list(getattr(ric, ric_method_name)()))
+        return result
+
+    def to_topology_nodes(self) -> list[dict[str, Any]]:
+        return self._extend_with_ric_references(
+            super().to_topology_nodes, "to_topology_nodes"
+        )
+
+    def to_topology_links(self) -> list[dict[str, Any]]:
+        return self._extend_with_ric_references(
+            super().to_topology_links, "to_topology_links"
+        )
diff --git a/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py b/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py
index 75d684c..7c5e94d 100644
--- a/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py
+++ b/code/network-generator/network_generation/model/python/o_ran_spiral_radius_profile.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 from typing import Any
 
diff --git a/code/network-generator/network_generation/model/python/o_ran_termination_point.py b/code/network-generator/network_generation/model/python/o_ran_termination_point.py
index 03ecd2a..8b8d76b 100644
--- a/code/network-generator/network_generation/model/python/o_ran_termination_point.py
+++ b/code/network-generator/network_generation/model/python/o_ran_termination_point.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 An abstract Class for O-RAN TerminationPoint
@@ -82,32 +82,15 @@
         self._parent = value
 
     def to_topology(self) -> dict[str, Any]:
-        result: dict[str, Any] = {"tp-id": self.name}
+        result: dict[str, Any] = {
+            "tp-id": self.name,
+            "o-ran-sc-network:uuid": self.id,
+            "o-ran-sc-network:type": self.type,
+        }
         if self.supporter and type(self.parent) is not int:
-            network_ref: str = ""
-            match str(type(self.parent)):
-                case "<class 'model.python.o_ran_smo.ORanSmo'>":
-                    network_ref = self.parent.parent.id
-                case "<class 'model.python.o_ran_near_rt_ric.ORanNearRtRic'>":
-                    network_ref = self.parent.parent.parent.id
-                case "<class 'model.python.o_ran_cu.ORanCu'>":
-                    network_ref = self.parent.parent.parent.parent.id
-                case "<class 'model.python.o_ran_du.ORanDu'>":
-                    network_ref = self.parent.parent.parent.parent.parent.id
-                case "<class 'model.python.o_ran_cloud_du.ORanCloudDu'>":
-                    network_ref = self.parent.parent.parent.parent.parent.id
-                case "<class 'model.python.o_ran_ru.ORanRu'>":
-                    network_ref = (
-                        self.parent.parent.parent.parent.parent.parent.id
-                    )
-                case _:
-                    print("unknown: implement " + str(type(self.parent)))
-                    network_ref = "unknown: implement " + str(
-                        type(self.parent))
-
             result["supporting-termination-point"] = [
                 {
-                    "network-ref": network_ref,
+                    "network-ref": self.parent.network.id,
                     "node-ref": self.parent.name,
                     "tp-ref": self.supporter,
                 }
diff --git a/code/network-generator/network_generation/model/python/point.py b/code/network-generator/network_generation/model/python/point.py
index 41cd8a0..15da052 100644
--- a/code/network-generator/network_generation/model/python/point.py
+++ b/code/network-generator/network_generation/model/python/point.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
 #
 # inspired by http://www.redblobgames.com/grids/hexagons/
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 from __future__ import division, print_function
 
diff --git a/code/network-generator/network_generation/model/python/top.py b/code/network-generator/network_generation/model/python/top.py
index e68c615..373a92f 100644
--- a/code/network-generator/network_generation/model/python/top.py
+++ b/code/network-generator/network_generation/model/python/top.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,11 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 An abstract Class for all classes
 """
+import uuid
 from abc import ABC, abstractmethod
 from typing import Any, TypedDict, cast
 
@@ -34,6 +35,7 @@
 class ITop(TypedDict):
     id: str
     name: str
+    type: str
     administrativeState: AdministrativeState
     operationalState: OperationalState
     lifeCycleState: LifeCycleState
@@ -46,6 +48,7 @@
 default_value: ITop = {
     "id": "be5229af-2660-4bae-8f2c-b9d0f788fad1",
     "name": "NoName",
+    "type": "NoType",
     "administrativeState": AdministrativeState.LOCKED,
     "operationalState": OperationalState.DISABLED,
     "lifeCycleState": LifeCycleState.PLANNED,
@@ -68,6 +71,7 @@
         itop: ITop = self._to_itop_data(data)
         self._id: str = itop["id"]
         self._name: str = itop["name"]
+        self._type: str = itop["type"]
         self._administrativeState: AdministrativeState = itop[
             "administrativeState"
         ]
@@ -86,7 +90,7 @@
 
     @property
     def id(self) -> str:
-        return self._id
+        return str(uuid.uuid5(uuid.NAMESPACE_DNS, self.name))
 
     @id.setter
     def id(self, value: str) -> None:
@@ -101,6 +105,14 @@
         self._name = value
 
     @property
+    def type(self) -> str:
+        return self._type
+
+    @type.setter
+    def type(self, value: str) -> None:
+        self._type = value
+
+    @property
     def administrativeState(self) -> AdministrativeState:
         return self._administrativeState
 
diff --git a/code/network-generator/network_generation/model/python/tower.py b/code/network-generator/network_generation/model/python/tower.py
index 2aae0b3..2c20100 100644
--- a/code/network-generator/network_generation/model/python/tower.py
+++ b/code/network-generator/network_generation/model/python/tower.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A Class representing a Tower to mount O-RAN RUs
@@ -54,6 +54,7 @@
     ) -> None:
         tower_data: ITower = self._to_tower_data(data)
         super().__init__(cast(dict[str, Any], tower_data), **kwargs)
+        self.type = "o-ran-sc-network:tower"
         self._o_ran_ru_count: int = (
             int(str(tower_data["oRanRuCount"]))
             if tower_data and "oRanRuCount" in tower_data
@@ -95,6 +96,7 @@
                         "position": self.position,
                         "layout": self.layout,
                         "parent": self,
+                        "network": self.network,
                         "cellCount": cell_count,
                         "ruAngle": ru_angle,
                         "ruAzimuth": ru_azimuth,
@@ -110,12 +112,15 @@
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
         phy_tp: str = "-".join([self.name, "phy".upper()])
-        result.append(ORanTerminationPoint({"tp-id": phy_tp}))
+        result.append(ORanTerminationPoint({
+            "name": phy_tp,
+            "type": "o-ran-sc-network:phy"
+        }))
         for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu", "ofhs"]:
-            result.append(
-                ORanTerminationPoint(
-                    {
-                        "tp-id": "-".join([self.name, interface.upper()]),
+            id: str = "-".join([self.name, interface.upper()])
+            result.append(ORanTerminationPoint({
+                        "name": id,
+                        "type": ":".join(["o-ran-sc-network", interface]),
                         "supporting-termination-point": [
                             {
                                 "network-ref": type(
@@ -125,21 +130,7 @@
                                 "tp-ref": phy_tp,
                             }
                         ],
-                    }
-                )
-            )
-        return result
-
-    def to_topology_nodes(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_nodes()
-        for o_ran_ru in self.o_ran_rus:
-            result.extend(o_ran_ru.to_topology_nodes())
-        return result
-
-    def to_topology_links(self) -> list[dict[str, Any]]:
-        result: list[dict[str, Any]] = super().to_topology_links()
-        for o_ran_ru in self.o_ran_rus:
-            result.extend(o_ran_ru.to_topology_links())
+                    }))
         return result
 
     def toKml(self) -> ET.Element:
@@ -158,3 +149,33 @@
     def to_directory(self, parent_dir: str) -> None:
         for o_ran_ru in self.o_ran_rus:
             o_ran_ru.to_directory(parent_dir)
+
+    def _extend_with_o_ran_ru_references(
+        self: Any, super_method: Any, o_ran_ru_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from o_ran_rus.
+
+        :param super_method: The superclass method to call for the initial
+                             result.
+        :param o_ran_ru_method_name: The method name to call on each o_ran_ru.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        for o_ran_ru in self.o_ran_rus:
+            result.extend(
+                self.flatten_list(getattr(o_ran_ru, o_ran_ru_method_name)())
+            )
+        return result
+
+    def to_topology_nodes(self) -> list[dict[str, Any]]:
+        return self._extend_with_o_ran_ru_references(
+            super().to_topology_nodes,
+            "to_topology_nodes",
+        )
+
+    def to_topology_links(self) -> list[dict[str, Any]]:
+        return self._extend_with_o_ran_ru_references(
+            super().to_topology_links,
+            "to_topology_links",
+        )
diff --git a/code/network-generator/network_generation/model/python/type_definitions.py b/code/network-generator/network_generation/model/python/type_definitions.py
index 9dc0c8a..aea8fb6 100644
--- a/code/network-generator/network_generation/model/python/type_definitions.py
+++ b/code/network-generator/network_generation/model/python/type_definitions.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 
 """
 A collection of TypeDefinitions
diff --git a/code/network-generator/network_generation/model/yang/iana-hardware.yang b/code/network-generator/network_generation/model/yang/iana-hardware.yang
new file mode 100644
index 0000000..a72f84c
--- /dev/null
+++ b/code/network-generator/network_generation/model/yang/iana-hardware.yang
@@ -0,0 +1,180 @@
+module iana-hardware {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:iana-hardware";
+  prefix ianahw;
+
+  organization
+    "IANA";
+  contact
+    "        Internet Assigned Numbers Authority
+     Postal: ICANN
+             12025 Waterfront Drive, Suite 300
+             Los Angeles, CA  90094-2536
+             United States of America
+     Tel:    +1 310 301 5800
+     E-Mail: iana@iana.org>";
+  description
+    "IANA-defined identities for hardware class.
+     The latest revision of this YANG module can be obtained from
+     the IANA website.
+     Requests for new values should be made to IANA via
+     email (iana@iana.org).
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+     The initial version of this YANG module is part of RFC 8348;
+     see the RFC itself for full legal notices.";
+  reference
+    "https://www.iana.org/assignments/yang-parameters";
+
+  revision 2018-03-13 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 8348: A YANG Data Model for Hardware Management";
+  }
+
+  /*
+   * Identities
+   */
+
+  identity hardware-class {
+    description
+      "This identity is the base for all hardware class
+       identifiers.";
+  }
+
+  identity unknown {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is unknown
+       to the server.";
+  }
+
+  identity chassis {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is an
+       overall container for networking equipment.  Any class of
+       physical component, except a stack, may be contained within a
+       chassis; a chassis may only be contained within a stack.";
+  }
+
+  identity backplane {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of device for aggregating and forwarding networking traffic,
+       such as a shared backplane in a modular ethernet switch.  Note
+       that an implementation may model a backplane as a single
+       physical component, which is actually implemented as multiple
+       discrete physical components (within a chassis or stack).";
+  }
+
+  identity container {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is capable
+       of containing one or more removable physical entities,
+       possibly of different types.  For example, each (empty or
+       full) slot in a chassis will be modeled as a container.  Note
+       that all removable physical components should be modeled
+       within a container component, such as field-replaceable
+       modules, fans, or power supplies.  Note that all known
+       containers should be modeled by the agent, including empty
+       containers.";
+  }
+
+  identity power-supply {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is a
+       power-supplying component.";
+  }
+
+  identity fan {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is a fan or
+       other heat-reduction component.";
+  }
+
+  identity sensor {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of sensor, such as a temperature sensor within a router
+       chassis.";
+  }
+
+  identity module {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of self-contained sub-system.  If a module component is
+       removable, then it should be modeled within a container
+       component; otherwise, it should be modeled directly within
+       another physical component (e.g., a chassis or another
+       module).";
+  }
+
+  identity port {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of networking port capable of receiving and/or transmitting
+       networking traffic.";
+  }
+
+  identity stack {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of super-container (possibly virtual) intended to group
+       together multiple chassis entities.  A stack may be realized
+       by a virtual cable, a real interconnect cable attached to
+       multiple chassis, or multiple interconnect cables.  A stack
+       should not be modeled within any other physical components,
+       but a stack may be contained within another stack.  Only
+       chassis components should be contained within a stack.";
+  }
+
+  identity cpu {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of central processing unit.";
+  }
+
+  identity energy-object {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of energy object, i.e., it is a piece of equipment that is
+       part of or attached to a communications network that is
+       monitored, it is controlled, or it aids in the management of
+       another device for Energy Management.";
+  }
+
+  identity battery {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of battery.";
+  }
+
+  identity storage-drive {
+    base ianahw:hardware-class;
+    description
+      "This identity is applicable if the hardware class is some sort
+       of component with data storage capability as its main
+       functionality, e.g., hard disk drive (HDD), solid-state device
+       (SSD), solid-state hybrid drive (SSHD), object storage device
+       (OSD), or other.";
+  }
+}
diff --git a/code/network-generator/network_generation/model/yang/ietf-interfaces.yang b/code/network-generator/network_generation/model/yang/ietf-interfaces.yang
new file mode 100644
index 0000000..63e5b95
--- /dev/null
+++ b/code/network-generator/network_generation/model/yang/ietf-interfaces.yang
@@ -0,0 +1,1008 @@
+module ietf-interfaces {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+  prefix if;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETMOD (Network Modeling) Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+  description
+    "This module contains a collection of YANG definitions for
+     managing network interfaces.
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+     This version of this YANG module is part of RFC 8343; see
+     the RFC itself for full legal notices.";
+
+  revision 2018-02-20 {
+    description
+      "Updated to support NMDA.";
+    reference
+      "RFC 8343: A YANG Data Model for Interface Management";
+  }
+  revision 2014-05-08 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7223: A YANG Data Model for Interface Management";
+  }
+
+  /*
+   * Typedefs
+   */
+
+  typedef interface-ref {
+    type leafref {
+      path "/if:interfaces/if:interface/if:name";
+    }
+    description
+      "This type is used by data models that need to reference
+       interfaces.";
+  }
+
+  /*
+   * Identities
+   */
+
+  identity interface-type {
+    description
+      "Base identity from which specific interface types are
+       derived.";
+  }
+
+  /*
+   * Features
+   */
+
+  feature arbitrary-names {
+    description
+      "This feature indicates that the device allows user-controlled
+       interfaces to be named arbitrarily.";
+  }
+
+  feature pre-provisioning {
+    description
+      "This feature indicates that the device supports
+       pre-provisioning of interface configuration, i.e., it is
+       possible to configure an interface whose physical interface
+       hardware is not present on the device.";
+  }
+
+  feature if-mib {
+    description
+      "This feature indicates that the device implements
+       the IF-MIB.";
+    reference
+      "RFC 2863: The Interfaces Group MIB";
+  }
+
+  /*
+   * Data nodes
+   */
+
+  container interfaces {
+    description
+      "Interface parameters.";
+    list interface {
+      key "name";
+      description
+        "The list of interfaces on the device.
+         The status of an interface is available in this list in the
+         operational state.  If the configuration of a
+         system-controlled interface cannot be used by the system
+         (e.g., the interface hardware present does not match the
+         interface type), then the configuration is not applied to
+         the system-controlled interface shown in the operational
+         state.  If the configuration of a user-controlled interface
+         cannot be used by the system, the configured interface is
+         not instantiated in the operational state.
+         System-controlled interfaces created by the system are
+         always present in this list in the operational state,
+         whether or not they are configured.";
+      leaf name {
+        type string;
+        description
+          "The name of the interface.
+           A device MAY restrict the allowed values for this leaf,
+           possibly depending on the type of the interface.
+           For system-controlled interfaces, this leaf is the
+           device-specific name of the interface.
+           If a client tries to create configuration for a
+           system-controlled interface that is not present in the
+           operational state, the server MAY reject the request if
+           the implementation does not support pre-provisioning of
+           interfaces or if the name refers to an interface that can
+           never exist in the system.  A Network Configuration
+           Protocol (NETCONF) server MUST reply with an rpc-error
+           with the error-tag 'invalid-value' in this case.
+           If the device supports pre-provisioning of interface
+           configuration, the 'pre-provisioning' feature is
+           advertised.
+           If the device allows arbitrarily named user-controlled
+           interfaces, the 'arbitrary-names' feature is advertised.
+           When a configured user-controlled interface is created by
+           the system, it is instantiated with the same name in the
+           operational state.
+           A server implementation MAY map this leaf to the ifName
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifName.  The definition of
+           such a mechanism is outside the scope of this document.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+      leaf description {
+        type string;
+        description
+          "A textual description of the interface.
+           A server implementation MAY map this leaf to the ifAlias
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifAlias.  The definition of
+           such a mechanism is outside the scope of this document.
+           Since ifAlias is defined to be stored in non-volatile
+           storage, the MIB implementation MUST map ifAlias to the
+           value of 'description' in the persistently stored
+           configuration.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAlias";
+      }
+      leaf type {
+        type identityref {
+          base interface-type;
+        }
+        mandatory true;
+        description
+          "The type of the interface.
+           When an interface entry is created, a server MAY
+           initialize the type leaf with a valid value, e.g., if it
+           is possible to derive the type from the name of the
+           interface.
+           If a client tries to set the type of an interface to a
+           value that can never be used by the system, e.g., if the
+           type is not supported or if the type does not match the
+           name of the interface, the server MUST reject the request.
+           A NETCONF server MUST reply with an rpc-error with the
+           error-tag 'invalid-value' in this case.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifType";
+      }
+      leaf enabled {
+        type boolean;
+        default "true";
+        description
+          "This leaf contains the configured, desired state of the
+           interface.
+           Systems that implement the IF-MIB use the value of this
+           leaf in the intended configuration to set
+           IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
+           has been initialized, as described in RFC 2863.
+           Changes in this leaf in the intended configuration are
+           reflected in ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+      leaf link-up-down-trap-enable {
+        if-feature "if-mib";
+        type enumeration {
+          enum enabled {
+            value 1;
+            description
+              "The device will generate linkUp/linkDown SNMP
+               notifications for this interface.";
+          }
+          enum disabled {
+            value 2;
+            description
+              "The device will not generate linkUp/linkDown SNMP
+               notifications for this interface.";
+          }
+        }
+        description
+          "Controls whether linkUp/linkDown SNMP notifications
+           should be generated for this interface.
+           If this node is not configured, the value 'enabled' is
+           operationally used by the server for interfaces that do
+           not operate on top of any other interface (i.e., there are
+           no 'lower-layer-if' entries), and 'disabled' otherwise.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifLinkUpDownTrapEnable";
+      }
+      leaf admin-status {
+        if-feature "if-mib";
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "Not ready to pass packets and not in some test mode.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "The desired state of the interface.
+           This leaf has the same read semantics as ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+      leaf oper-status {
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "The interface does not pass any packets.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.  No operational packets can
+               be passed.";
+          }
+          enum unknown {
+            value 4;
+            description
+              "Status cannot be determined for some reason.";
+          }
+          enum dormant {
+            value 5;
+            description
+              "Waiting for some external event.";
+          }
+          enum not-present {
+            value 6;
+            description
+              "Some component (typically hardware) is missing.";
+          }
+          enum lower-layer-down {
+            value 7;
+            description
+              "Down due to state of lower-layer interface(s).";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "The current operational state of the interface.
+           This leaf has the same semantics as ifOperStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      }
+      leaf last-change {
+        type yang:date-and-time;
+        config false;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+      leaf if-index {
+        if-feature "if-mib";
+        type int32 {
+          range "1..2147483647";
+        }
+        config false;
+        mandatory true;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+      leaf phys-address {
+        type yang:phys-address;
+        config false;
+        description
+          "The interface's address at its protocol sub-layer.  For
+           example, for an 802.x interface, this object normally
+           contains a Media Access Control (MAC) address.  The
+           interface's media-specific modules must define the bit
+           and byte ordering and the format of the value of this
+           object.  For interfaces that do not have such an address
+           (e.g., a serial line), this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+      leaf-list higher-layer-if {
+        type interface-ref;
+        config false;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+      leaf-list lower-layer-if {
+        type interface-ref;
+        config false;
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+      leaf speed {
+        type yang:gauge64;
+        units "bits/second";
+        config false;
+        description
+          "An estimate of the interface's current bandwidth in bits
+           per second.  For interfaces that do not vary in
+           bandwidth or for those where no accurate estimation can
+           be made, this node should contain the nominal bandwidth.
+           For interfaces that have no concept of bandwidth, this
+           node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+      container statistics {
+        config false;
+        description
+          "A collection of interface-related statistics objects.";
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          mandatory true;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+        leaf in-octets {
+          type yang:counter64;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were not addressed to a
+             multicast or broadcast address at this sub-layer.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a broadcast
+             address at this sub-layer.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a multicast
+             address at this sub-layer.  For a MAC-layer protocol,
+             this includes both Group and Functional addresses.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+        leaf in-discards {
+          type yang:counter32;
+          description
+            "The number of inbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+        leaf in-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+        leaf in-unknown-protos {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface that were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing, the number of
+             transmission units received via the interface that were
+             discarded because of an unknown or unsupported protocol.
+             For any interface that does not support protocol
+             multiplexing, this counter is not present.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+        leaf out-octets {
+          type yang:counter64;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC-layer
+             protocol, this includes both Group and Functional
+             addresses.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+        leaf out-discards {
+          type yang:counter32;
+          description
+            "The number of outbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+        leaf out-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+    }
+  }
+
+  /*
+   * Legacy typedefs
+   */
+
+  typedef interface-state-ref {
+    type leafref {
+      path "/if:interfaces-state/if:interface/if:name";
+    }
+    status deprecated;
+    description
+      "This type is used by data models that need to reference
+       the operationally present interfaces.";
+  }
+
+  /*
+   * Legacy operational state data nodes
+   */
+
+  container interfaces-state {
+    config false;
+    status deprecated;
+    description
+      "Data nodes for the operational state of interfaces.";
+    list interface {
+      key "name";
+      status deprecated;
+      description
+        "The list of interfaces on the device.
+         System-controlled interfaces created by the system are
+         always present in this list, whether or not they are
+         configured.";
+      leaf name {
+        type string;
+        status deprecated;
+        description
+          "The name of the interface.
+           A server implementation MAY map this leaf to the ifName
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifName.  The definition of
+           such a mechanism is outside the scope of this document.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+      leaf type {
+        type identityref {
+          base interface-type;
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The type of the interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifType";
+      }
+      leaf admin-status {
+        if-feature "if-mib";
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "Not ready to pass packets and not in some test mode.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.";
+          }
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The desired state of the interface.
+           This leaf has the same read semantics as ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+      leaf oper-status {
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "The interface does not pass any packets.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.  No operational packets can
+               be passed.";
+          }
+          enum unknown {
+            value 4;
+            description
+              "Status cannot be determined for some reason.";
+          }
+          enum dormant {
+            value 5;
+            description
+              "Waiting for some external event.";
+          }
+          enum not-present {
+            value 6;
+            description
+              "Some component (typically hardware) is missing.";
+          }
+          enum lower-layer-down {
+            value 7;
+            description
+              "Down due to state of lower-layer interface(s).";
+          }
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The current operational state of the interface.
+           This leaf has the same semantics as ifOperStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      }
+      leaf last-change {
+        type yang:date-and-time;
+        status deprecated;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+      leaf if-index {
+        if-feature "if-mib";
+        type int32 {
+          range "1..2147483647";
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+      leaf phys-address {
+        type yang:phys-address;
+        status deprecated;
+        description
+          "The interface's address at its protocol sub-layer.  For
+           example, for an 802.x interface, this object normally
+           contains a Media Access Control (MAC) address.  The
+           interface's media-specific modules must define the bit
+           and byte ordering and the format of the value of this
+           object.  For interfaces that do not have such an address
+           (e.g., a serial line), this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+      leaf-list higher-layer-if {
+        type interface-state-ref;
+        status deprecated;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+      leaf-list lower-layer-if {
+        type interface-state-ref;
+        status deprecated;
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+      leaf speed {
+        type yang:gauge64;
+        units "bits/second";
+        status deprecated;
+        description
+          "An estimate of the interface's current bandwidth in bits
+           per second.  For interfaces that do not vary in
+           bandwidth or for those where no accurate estimation can
+           be made, this node should contain the nominal bandwidth.
+           For interfaces that have no concept of bandwidth, this
+           node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+      container statistics {
+        status deprecated;
+        description
+          "A collection of interface-related statistics objects.";
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          mandatory true;
+          status deprecated;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+        leaf in-octets {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were not addressed to a
+             multicast or broadcast address at this sub-layer.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a broadcast
+             address at this sub-layer.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a multicast
+             address at this sub-layer.  For a MAC-layer protocol,
+             this includes both Group and Functional addresses.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+        leaf in-discards {
+          type yang:counter32;
+          status deprecated;
+          description
+            "The number of inbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+        leaf in-errors {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+        leaf in-unknown-protos {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface that were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing, the number of
+             transmission units received via the interface that were
+             discarded because of an unknown or unsupported protocol.
+             For any interface that does not support protocol
+             multiplexing, this counter is not present.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+        leaf out-octets {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC-layer
+             protocol, this includes both Group and Functional
+             addresses.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+        leaf out-discards {
+          type yang:counter32;
+          status deprecated;
+          description
+            "The number of outbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+        leaf out-errors {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+    }
+  }
+}
diff --git a/code/network-generator/network_generation/model/yang/o-ran-common-identity-refs.yang b/code/network-generator/network_generation/model/yang/o-ran-common-identity-refs.yang
new file mode 100644
index 0000000..1e99f28
--- /dev/null
+++ b/code/network-generator/network_generation/model/yang/o-ran-common-identity-refs.yang
@@ -0,0 +1,186 @@
+module o-ran-common-identity-refs {
+  yang-version 1.1;
+  namespace "urn:o-ran:wg1identityref:1.0";
+  prefix o-ran-iref;
+
+  import iana-hardware {
+    prefix ianahw;
+  }
+
+  organization
+    "O-RAN Alliance";
+  contact
+    "www.o-ran.org";
+  description
+    "This module defines a set of re-usable identity references, that can be
+     re-used across O-RAN working groups.
+
+     Copyright 2020 the O-RAN Alliance.
+
+     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+     POSSIBILITY OF SUCH DAMAGE.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, are permitted provided that the following conditions are met:
+
+     * Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the above disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice,
+     this list of conditions and the above disclaimer in the documentation
+     and/or other materials provided with the distribution.
+     * Neither the Members of the O-RAN Alliance nor the names of its
+     contributors may be used to endorse or promote products derived from
+     this software without specific prior written permission.";
+
+  revision 2020-11-01 {
+    description
+      "version 1.0.0
+
+       1) initial version.";
+    reference
+      "ORAN-WG1.IM.0-v01.00";
+  }
+
+  // O-RAN functional identity types
+
+  identity o-ran-function-base {
+    description
+      "Base identity from which all O-RAN defined functions are derived.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity o-ru-function {
+    base o-ran-function-base;
+    description
+      "an identity corresponding to an O-RAN O-RU Function.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity o-du-function {
+    base o-ran-function-base;
+    description
+      "an identity corresponding to all O-RAN O-DU Functions.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity o-cu-function {
+    base o-ran-function-base;
+    description
+      "an identity corresponding to all O-RAN O-CU Functions.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity o-cu-up-function {
+    base o-cu-function;
+    description
+      "an identity corresponding to an O-RAN O-CU UP Function.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity o-cu-cp-function {
+    base o-cu-function;
+    description
+      "an identity corresponding to an O-RAN O-CU CP Function.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  // O-RAN radio technology identity types
+
+  identity o-ran-radio-technology-base {
+    description
+      "Base identity for O-RAN defined radio technology types.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity new-radio-technology {
+    base o-ran-radio-technology-base;
+    description
+      "An identity corresponding to new radio technology.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity lte-technology {
+    base o-ran-radio-technology-base;
+    description
+      "An identity corresponding to lte technology.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity nb-iot {
+    base lte-technology;
+    description
+      "An identity corresponding to nb-iot technology.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  // O-RAN Transport technology identity types
+
+  identity o-ran-transport-technology-base {
+    description
+      "Base identity from which all O-RAN defined transport technology identities are derived.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  // O-RAN Fronthaul transport identity types
+
+  identity o-ran-fronthaul-transport-base {
+    description
+      "Base identity from which all O-RAN defined fronthaul transports are derived.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity ethernet-fronthaul-transport {
+    base o-ran-fronthaul-transport-base;
+    description
+      "an identity corresponding to fronthaul transport using ethernet based flows.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  // Hardware component identity types
+
+  identity o-ran-module {
+    base ianahw:module;
+    description
+      "Any O-RAN module that represents a self-contained sub-system.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity o-ran-hardware-class {
+    base ianahw:hardware-class;
+    description
+      "This identity corresponding to a generic O-RAN hardware class.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity fpga {
+    base o-ran-hardware-class;
+    description
+      "Represent an FPGA.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+}
diff --git a/code/network-generator/network_generation/model/yang/o-ran-sc-network.yang b/code/network-generator/network_generation/model/yang/o-ran-sc-network.yang
new file mode 100644
index 0000000..18650af
--- /dev/null
+++ b/code/network-generator/network_generation/model/yang/o-ran-sc-network.yang
@@ -0,0 +1,265 @@
+module o-ran-sc-network {
+  yang-version 1.1;
+  namespace "urn:o-ran-sc:yang:o-ran-sc-network";
+  prefix onw;
+
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+  import ietf-interfaces {
+    prefix if;
+    reference
+      "RFC 8343: A YANG Data Model for Interface Management";
+  }
+  import ietf-network {
+    prefix nw;
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+  import ietf-network-topology {
+    prefix nt;
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+  import o-ran-common-identity-refs {
+    prefix o-ran-iref;
+    reference
+      "O-RAN Information Model and Data Models";
+  }
+
+  organization
+    "O-RAN Software Community";
+  contact
+    "www.o-ran-sc.org";
+  description
+    "This module adds a type and an uuid parameter to the node object
+     class.
+
+     Copyright 2024 the O-RAN Software Community.
+
+     Licensed under the Apache License, Version 2.0 (the 'License');
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an 'AS IS' BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.";
+
+  revision 2024-09-13 {
+    description
+      "Initial version";
+    reference
+      "https://lf-o-ran-sc.atlassian.net/wiki/spaces/OAM/pages/29491658/Hybrid+and+Hierarchical+OAM+Architecture";
+  }
+
+  identity o-ran-sc-network-base {
+    base o-ran-iref:o-ran-function-base;
+    description
+      "Base identity from which extend the o-ran-function-base
+       The identities are used to define the value of a topological
+       type of the abstract topological node from ietf-network.
+
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity smo {
+    base o-ran-sc-network-base;
+    description
+      "An identity corresponding to a Service, Maintenance and
+       Orchestration Framework (SMO) topology node.";
+  }
+
+  identity near-rt-ric {
+    base o-ran-sc-network-base;
+    description
+      "An identity corresponding to a near real-time radio access
+       network intelligent controller (NearRtRic) topology node.";
+  }
+
+  identity o-cloud {
+    base o-ran-sc-network-base;
+    description
+      "An identity corresponding to a near real-time O-RAN cloud
+       resource pool instance (O-Cloud) topology node.";
+  }
+
+  identity tower {
+    base o-ran-sc-network-base;
+    description
+      "An identity corresponding to a telecommunication network tower
+       offering mount points for network elements.";
+  }
+
+  identity o-ran-sc-interface-type {
+    base if:interface-type;
+    description
+      "This identity is used as a base for all interface types
+       defined in the context of O-RAN-SC.
+       This identity is abstract and MUST NOT be used as a value.";
+  }
+
+  identity phy {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an physical interface";
+  }
+
+  identity a1 {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN A1 interface";
+  }
+
+  identity e2 {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN A1 interface";
+  }
+
+  identity o1 {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN O1 interface";
+  }
+
+  identity o2 {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN O2 interface";
+  }
+
+  identity ofhm {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN WG4 OpenFronthaul Management Plane
+       interface";
+  }
+
+  identity ofhc {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN WG4 OpenFronthaul Control Plane
+       interface";
+  }
+
+  identity ofhu {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN WG4 OpenFronthaul User Plane
+       interface";
+  }
+
+  identity ofhs {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to an O-RAN WG4 OpenFronthaul Synchronization
+       Plane interface";
+  }
+
+  identity cell {
+    base o-ran-sc-interface-type;
+    description
+      "An identity corresponding to a 3GPP NRCellDu.";
+    reference 
+      "3GPP TS 28.541 5G Network Resource Model (NRM)";
+  }
+
+  typedef o-ran-sc-node-type {
+    type identityref {
+      base o-ran-iref:o-ran-function-base;
+    }
+    description
+      "Type reference to a node type identity.";
+  }
+
+  
+  typedef o-ran-sc-interface-type {
+    type identityref {
+      base o-ran-sc-interface-type;
+    }
+    description
+      "Type reference to a termination point type identity.";
+  }
+
+  grouping o-ran-sc-network {
+    description
+      "An abstract object call hosting O-RAN-SC specific extension
+       to an ietf-network network object class.";
+    leaf name {
+      type string {
+        length "1..255";
+      }
+      description
+        "A human readable name for the network of the
+         O-RAN-SC OAM topology.";
+    }
+  }
+
+  grouping o-ran-sc-network-node {
+    description
+      "An abstract object call hosting O-RAN-SC specific extension
+       to an ietf-network node object class.";
+    leaf uuid {
+      type yang:uuid;
+      description
+        "A Universally Unique IDentifier identifying a topological
+         ietf-network node type in the context of an
+         O-RAN-SC OAM topology.";
+      reference
+        "RFC 4122
+         A Universally Unique IDentifier (UUID) URN Namespace";
+    }
+    leaf type {
+      type o-ran-sc-node-type;
+      description
+        "A parameter which defines the topological ietf-network
+         node type in the context of an O-RAN-SC OAM topology.";
+    }
+  }
+
+  grouping o-ran-sc-network-tp {
+    description
+      "An abstract object call hosting O-RAN-SC specific extension
+       to an ietf-network node object class.";
+    leaf uuid {
+      type yang:uuid;
+      description
+        "A Universally Unique IDentifier identifying a topological
+         ietf-network node type in the context of an
+         O-RAN-SC OAM topology.";
+      reference
+        "RFC 4122
+         A Universally Unique IDentifier (UUID) URN Namespace";
+    }
+    leaf type {
+      type o-ran-sc-interface-type;
+      description
+        "A parameter which defines the topological ietf-network
+         termination point type in the context of an O-RAN-SC OAM topology.";
+    }
+  }
+
+  augment "/nw:networks/nw:network" {
+    description
+      "Augments ietf-network node with a name parameter.";
+    uses o-ran-sc-network;
+  }
+
+  augment "/nw:networks/nw:network/nw:node" {
+    description
+      "Augments ietf-network node with type and uuid parameters.";
+    uses o-ran-sc-network-node;
+  }
+
+  augment "/nw:networks/nw:network/nw:node/nt:termination-point" {
+    description
+      "Augments ietf-network node with type and uuid parameters.";
+    uses o-ran-sc-network-tp;
+  }
+}
diff --git a/code/network-generator/network_generation/parameter_validator.py b/code/network-generator/network_generation/parameter_validator.py
index 4c1dabe..15debc0 100644
--- a/code/network-generator/network_generation/parameter_validator.py
+++ b/code/network-generator/network_generation/parameter_validator.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 """
 Module containing a class for parameter validation
 """
@@ -67,7 +67,7 @@
         """
         return self.__config_file
 
-    def configuration(self) -> dict[str, str | dict[str, int]]:
+    def configuration(self) -> dict:
         """
         Getter for the configuration as input parameter.
         :return Init configuration as dict.
diff --git a/code/network-generator/network_generation/view/network_viewer.py b/code/network-generator/network_generation/view/network_viewer.py
index 750a661..5bf87ca 100644
--- a/code/network-generator/network_generation/view/network_viewer.py
+++ b/code/network-generator/network_generation/view/network_viewer.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies GmbH
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,18 +12,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# !/usr/bin/python
+# !/usr/bin/python3
 """
 Provides functions to convert the Network into different formats
 """
 
 import gzip
 import json
-from typing_extensions import Buffer
-import zipfile
 import xml.etree.ElementTree as ET
+import zipfile
 from typing import Any
 
+from typing_extensions import Buffer
+
 from network_generation.model.python.o_ran_network import ORanNetwork
 
 
@@ -65,24 +66,28 @@
         self.__network.to_directory(parent_dir)
         print(f'Directory structure saved to "{parent_dir}"')
 
-    def save(self, filename: str, compressed: bool = True) -> None:
+    def __save_on_disc(
+        self, filename: str, compressed: bool, content: Any
+    ) -> None:
+        if compressed is True:
+            with gzip.open(f"{filename}.gz", "wb") as zf:
+                zf.write(json.dumps(content, indent=2).encode("utf-8"))
+            print(f'File "{filename}.gz" saved!')
+        else:
+            with open(f"{filename}", "w", encoding="utf-8") as jf:
+                json.dump(content, jf, ensure_ascii=False, indent=2)
+            print(f'File "{filename}" saved!')
+
+    def rfc8345(self, filename: str, compressed: bool = True) -> None:
         """
         Method saving the class content to a file in json format.
         :param filename: A valid path to a file on the system.
-        :param compressed: if True, svg is stored as svgz format.
+        :param compressed: if True, svg is stored as json format.
         :type filename: string
         """
         output: dict[str, Any] = self.__network.to_topology()
-        if compressed is True:
-            with gzip.open(f'{filename}-operational.json.gz', 'wb') as zf:
-                zf.write(json.dumps(output, indent=2).encode('utf-8'))
-            print(f'File "{filename}-operational.json.gz" saved!')
-        else:
-            with open(
-                f'{filename}-operational.json', "w", encoding="utf-8"
-            ) as jf:
-                json.dump(output, jf, ensure_ascii=False, indent=2)
-            print(f'File "{filename}-operational.json" saved!')
+        file_extension: str = "-operational.json"
+        self.__save_on_disc(f"{filename}{file_extension}", compressed, output)
 
     def readStylesFromFile(self) -> str:
         """
@@ -108,13 +113,14 @@
 
         if compressed is True:
             svg_output: Buffer = ET.tostring(
-                root, encoding="utf-8", xml_declaration=True)
-            with gzip.open(f'{filename}.svgz', 'wb') as zf:
+                root, encoding="utf-8", xml_declaration=True
+            )
+            with gzip.open(f"{filename}.svgz", "wb") as zf:
                 zf.write(svg_output)
             print(f'File "{filename}.svgz" saved!')
         else:
             ET.ElementTree(root).write(
-                f'{filename}.svg', encoding="utf-8", xml_declaration=True
+                f"{filename}.svg", encoding="utf-8", xml_declaration=True
             )
             print(f'File "{filename}.svg" saved!')
 
@@ -142,16 +148,15 @@
                 fill.text = str(value["fill"]["color"])
                 root.findall(".//Document")[0].append(style)
 
-        kml: str = ET.tostring(
-            root, encoding="utf-8", xml_declaration=True)
+        kml: str = ET.tostring(root, encoding="utf-8", xml_declaration=True)
         if compressed is True:
             with zipfile.ZipFile(
-                f'{filename}.kmz', 'w', zipfile.ZIP_DEFLATED
+                f"{filename}.kmz", "w", zipfile.ZIP_DEFLATED
             ) as zf:
                 zf.writestr(f'{filename.split("/")[1]}.kml', data=kml)
             print(f'File "{filename}.kmz" saved!')
         else:
-            kml_file = open(f'{filename}.kml', 'w')
-            kml_file.write(kml)
+            kml_file = open(f"{filename}.kml", "wb")
+            kml_file.write(kml.encode('utf-8'))
             kml_file.close()
             print(f'File "{filename}.kml" saved!')
diff --git a/code/network-generator/test_config.json b/code/network-generator/test_config.json
index 9b70e65..dbff3f6 100644
--- a/code/network-generator/test_config.json
+++ b/code/network-generator/test_config.json
@@ -39,9 +39,13 @@
   },
   "outputFolder": "output",
   "generationTasks": {
-    "topology": {
+    "day0Config": {
+      "enabled": false,
+      "compressed": false
+    },
+    "rfc8345": {
       "enabled": true,
-      "compressed": true
+      "compressed": false
     },
     "svg": {
       "enabled": true,
diff --git a/code/network-generator/tests/conftest.py b/code/network-generator/tests/conftest.py
index 0eab9e6..5b20d02 100644
--- a/code/network-generator/tests/conftest.py
+++ b/code/network-generator/tests/conftest.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_base.py b/code/network-generator/tests/test_base.py
index 7890ea2..fb719b9 100644
--- a/code/network-generator/tests/test_base.py
+++ b/code/network-generator/tests/test_base.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_cli.py b/code/network-generator/tests/test_cli.py
index 88854fc..3697921 100644
--- a/code/network-generator/tests/test_cli.py
+++ b/code/network-generator/tests/test_cli.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_countries.py b/code/network-generator/tests/test_countries.py
index 94d9f7d..32b13a7 100644
--- a/code/network-generator/tests/test_countries.py
+++ b/code/network-generator/tests/test_countries.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_geo_location.py b/code/network-generator/tests/test_geo_location.py
index 2828b8e..0f1d8cd 100644
--- a/code/network-generator/tests/test_geo_location.py
+++ b/code/network-generator/tests/test_geo_location.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_hexagon.py b/code/network-generator/tests/test_hexagon.py
index 69f2fdc..70c9f95 100644
--- a/code/network-generator/tests/test_hexagon.py
+++ b/code/network-generator/tests/test_hexagon.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_main.py b/code/network-generator/tests/test_main.py
index 22a01ec..000b3cc 100644
--- a/code/network-generator/tests/test_main.py
+++ b/code/network-generator/tests/test_main.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_o_ran_network.py b/code/network-generator/tests/test_o_ran_network.py
index 06b32cd..12784bc 100644
--- a/code/network-generator/tests/test_o_ran_network.py
+++ b/code/network-generator/tests/test_o_ran_network.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_o_ran_spiral_radius_profile.py b/code/network-generator/tests/test_o_ran_spiral_radius_profile.py
index 3a1a21d..62a1c05 100644
--- a/code/network-generator/tests/test_o_ran_spiral_radius_profile.py
+++ b/code/network-generator/tests/test_o_ran_spiral_radius_profile.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_o_ran_termination_point.py b/code/network-generator/tests/test_o_ran_termination_point.py
index 005e943..e461025 100644
--- a/code/network-generator/tests/test_o_ran_termination_point.py
+++ b/code/network-generator/tests/test_o_ran_termination_point.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -22,12 +22,15 @@
 
 
 def test_o_ran_termination_point() -> None:
-    o_ran_termination_point: ORanTerminationPoint = ORanTerminationPoint()
-    assert o_ran_termination_point.id == "O-RAN-DU-00-00-00-00-02-OFHS"
+    o_ran_termination_point: ORanTerminationPoint = ORanTerminationPoint({
+        "name": "my-name",
+        "supporter": "my-supporter"
+    })
+    assert o_ran_termination_point.name == "my-name"
     assert o_ran_termination_point.administrativeState.value == "locked"
-    assert o_ran_termination_point.supporter == "O-RAN-DU-00-00-00-00-02-PHY"
+    assert o_ran_termination_point.supporter == "my-supporter"
     assert o_ran_termination_point.parent == 0
-    assert len(str(o_ran_termination_point)) == 337
+    assert len(str(o_ran_termination_point)) == 357
 
     o_ran_termination_point = ORanTerminationPoint(
         {
@@ -38,9 +41,9 @@
             "parent": ORanTerminationPoint(),
         }
     )
-    assert len(o_ran_termination_point.id) == 5
+    assert len(o_ran_termination_point.id) == 36
     assert o_ran_termination_point.administrativeState.value == "unlocked"
     assert o_ran_termination_point.operationalState.value == "enabled"
     assert o_ran_termination_point.supporter == "my_personal_fan"
     assert type(o_ran_termination_point.parent) is int
-    assert len(str(o_ran_termination_point)) == 316
+    assert len(str(o_ran_termination_point)) == 359
diff --git a/code/network-generator/tests/test_parameter_validator.py b/code/network-generator/tests/test_parameter_validator.py
index 1f44e81..c3796c9 100644
--- a/code/network-generator/tests/test_parameter_validator.py
+++ b/code/network-generator/tests/test_parameter_validator.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_point.py b/code/network-generator/tests/test_point.py
index e40fb6f..5f6c2b7 100644
--- a/code/network-generator/tests/test_point.py
+++ b/code/network-generator/tests/test_point.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/code/network-generator/tests/test_type_definitions.py b/code/network-generator/tests/test_type_definitions.py
index 615e5d5..de0b838 100644
--- a/code/network-generator/tests/test_type_definitions.py
+++ b/code/network-generator/tests/test_type_definitions.py
@@ -1,4 +1,4 @@
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/solution/network/config.py b/solution/network/config.py
index 3bee9be..6bbb1f9 100644
--- a/solution/network/config.py
+++ b/solution/network/config.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the 'License');
 # you may not use this file except in compliance with the License.
diff --git a/solution/network/docker-compose.yaml b/solution/network/docker-compose.yaml
index 13e1d99..14cf1b9 100755
--- a/solution/network/docker-compose.yaml
+++ b/solution/network/docker-compose.yaml
@@ -1,5 +1,5 @@
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/solution/smo/apps/flows/Dockerfile b/solution/smo/apps/flows/Dockerfile
index 7716597..9338b0a 100644
--- a/solution/smo/apps/flows/Dockerfile
+++ b/solution/smo/apps/flows/Dockerfile
@@ -1,5 +1,5 @@
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the 'License');
 # you may not use this file except in compliance with the License.
diff --git a/solution/smo/common/docker-compose.yaml b/solution/smo/common/docker-compose.yaml
index 772d073..030271c 100755
--- a/solution/smo/common/docker-compose.yaml
+++ b/solution/smo/common/docker-compose.yaml
@@ -1,5 +1,5 @@
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/solution/smo/oam/docker-compose.yaml b/solution/smo/oam/docker-compose.yaml
index bc827ae..82fc102 100755
--- a/solution/smo/oam/docker-compose.yaml
+++ b/solution/smo/oam/docker-compose.yaml
@@ -1,5 +1,5 @@
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/solution/smo/oam/ves-collector/Dockerfile b/solution/smo/oam/ves-collector/Dockerfile
index 3a7a4d6..402ac75 100644
--- a/solution/smo/oam/ves-collector/Dockerfile
+++ b/solution/smo/oam/ves-collector/Dockerfile
@@ -1,5 +1,5 @@
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the 'License');
 # you may not use this file except in compliance with the License.
diff --git a/solution/smo/oam/ves-collector/install.py b/solution/smo/oam/ves-collector/install.py
index eb1dc6b..c86dda3 100644
--- a/solution/smo/oam/ves-collector/install.py
+++ b/solution/smo/oam/ves-collector/install.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python3
 ################################################################################
-# Copyright 2023 highstreet technologies GmbH
+# Copyright 2024 highstreet technologies
 #
 # Licensed under the Apache License, Version 2.0 (the 'License');
 # you may not use this file except in compliance with the License.