diff --git a/README.md b/README.md
index e42cae615826530cc1c6dbb680590db534465746..6eda6c131858ced75e65fd492cf138755252adfe 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ The realizer module determines the realization of each slice by interacting with
## Requirements
-- Python3
+- Python3.12
- python3-pip
- python3-venv
@@ -70,8 +70,8 @@ To deploy and execute the NSC, follow these steps:
0. **Preparation**
```
- git clone https://github.com/Telefonica/network_slice_controller.git
- cd network_slice_controller
+ git clone https://labs.etsi.org/rep/tfs/nsc.git
+ cd nsc
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
diff --git a/app.py b/app.py
index 383d31c8e5c60fe498f87747fc6fc9ea104c68b1..1e34ec5486daeb0eb38f32e84494ba5f4fcb4db0 100644
--- a/app.py
+++ b/app.py
@@ -1,4 +1,4 @@
-# Copyright 2025 Telefonica Innovación Digital S.L.
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# This file is an original contribution from Telefonica Innovación Digital S.L.
+
from flask import Flask
from flask_restx import Api
from flask_cors import CORS
diff --git a/images/NSC_Architecture.png b/images/NSC_Architecture.png
index adee5374846eccdbf1974e616890b55fc4c131e2..852437d55f3fadcb9c6a4303be7c70a264977e30 100644
Binary files a/images/NSC_Architecture.png and b/images/NSC_Architecture.png differ
diff --git a/src/Constants.py b/src/Constants.py
index f699aed96dbcfa94839baaf467b139e874fd3afb..337be8856e4a91907a76466498fb6cb57634bca9 100644
--- a/src/Constants.py
+++ b/src/Constants.py
@@ -1,4 +1,4 @@
-# Copyright 2025 Telefonica Innovación Digital S.L.
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# This file is an original contribution from Telefonica Innovación Digital S.L.
+
import logging, os
# Default logging level
DEFAULT_LOGGING_LEVEL = logging.INFO
diff --git a/src/helpers.py b/src/helpers.py
index abbac026ba39edae5040b9e1efe8d6476d89caf5..47adc1619360e8f8438842b73efe31a07b3c1252 100644
--- a/src/helpers.py
+++ b/src/helpers.py
@@ -1,4 +1,4 @@
-# Copyright 2025 Telefonica Innovación Digital S.L.
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# 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/src/network_slice_controller.py b/src/network_slice_controller.py
index 871e5d19e14b0e118242a80986918248a9c35a57..7d141146d3a4cf1862008ef031ebfdfc10957f38 100644
--- a/src/network_slice_controller.py
+++ b/src/network_slice_controller.py
@@ -1,4 +1,4 @@
-# Copyright 2025 Telefonica Innovación Digital S.L.
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# 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/src/old/intent_generator.py b/src/old/intent_generator.py
deleted file mode 100644
index 05eae796f8a910477e0f66ce04d173a3541f5a24..0000000000000000000000000000000000000000
--- a/src/old/intent_generator.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python3
-import json
-import os
-#import requests
-import socket
-import random
-
-# Obtain the current directory
-current_dir = os.path.dirname(os.path.abspath(__file__))
-
-# Create the path to the templates directory
-parent_dir = os.path.dirname(current_dir)
-file_path = os.path.join(parent_dir, "templates")
-
-class IntentCreator:
-
- def __init__(self, plt, lnodes):
- self.plantilla = ''
- with open(plt, 'r') as source:
- self.plantilla = source.read()
- self.nodes = ''
- with open(lnodes, 'r') as source:
- self.nodes = source.read()
- self.nodes = json.loads(str(self.nodes))
-
-
- def __create_ep(self,node_name, node_ip, vlan_id):
- ep_tansport_key = f"EpTransport {node_name}"
- ep_transport = {
- ep_tansport_key:{
- "IpAddress":str(node_ip.rsplit('.', 1)[0] + '.1'),
- "logicalInterfaceInfo":{
- "logicalInterfaceType":"VLAN",
- "logicalInterfaceId":vlan_id
- },
- "NextHopInfo": str(node_ip.rsplit('.', 1)[0] + '.254'),
- "qosProfile":"A",
- "EpApplicationRef":[f"EP_F1U {node_name}"]
- }
- }
-
- ep_rp_key = f"EP_F1U {node_name}"
- ep_rp = {
- ep_rp_key:{
- "localAddress":node_ip,
- "remoteAddress":"",
- "epTransportRef":[ep_tansport_key]
- }
- }
- return ep_transport,ep_rp
-
- def create_intent(self):
- '''
- In this function we are going to create intents randomly and return them as a json.
- Parameters to modify:
- - Origin IP, Destination IP, Interfaces, Match type
- - SDP id and Node id
- - Required value
- '''
-
- request = json.loads(str(self.plantilla))
-
- # Subnet list in the slicing environment
- subnets = [["TopSliceSubnet1","TopSliceSubnetProfile"],["CNSliceSubnet1","CNSliceSubnetProfile"], ["RANSliceSubnet1","RANSliceSubnetProfile"], ["MidhaulSliceSubnet1","RANSliceSubnetProfile"], ["BackhaulSliceSubnet1","RANSliceSubnetProfile"]]
-
- # Possible values for throughput and latency
- throughput = [100, 200, 500, 1000]
- latency = [5, 10, 15, 20]
-
- # Assign random values to the QoS parameters
- top_slice_qos = [random.choice(throughput), 0, random.choice(latency)]
- top_slice_qos[1] = int(2*top_slice_qos[0])
- cn_slice_qos = [int(val) for val in [top_slice_qos[0]/2,top_slice_qos[1]/2, top_slice_qos[2]*0.4]]
- ran_slice_qos = [int(val) for val in [top_slice_qos[0]/2,top_slice_qos[1]/2, top_slice_qos[2]*0.6]]
- midhaul_slice_qos = [int(val) for val in [ran_slice_qos[0]*0.6,ran_slice_qos[1]*0.6, ran_slice_qos[2]/3]]
- backhaul_slice_qos = [int(val) for val in [ran_slice_qos[0]*0.4,ran_slice_qos[1]*0.4, ran_slice_qos[2]*2/3]]
-
- qos = [top_slice_qos, cn_slice_qos, ran_slice_qos, midhaul_slice_qos, backhaul_slice_qos]
-
- for index, subnet in enumerate(subnets):
- request[subnet[0]]["SliceProfileList"][0][subnet[1]]["dLThptPerSliceSubnet"]["GuaThpt"] = qos[index][0]
- request[subnet[0]]["SliceProfileList"][0][subnet[1]]["dLThptPerSliceSubnet"]["MaxThpt"] = qos[index][1]
- request[subnet[0]]["SliceProfileList"][0][subnet[1]]["uLThptPerSliceSubnet"]["GuaThpt"] = qos[index][0]
- request[subnet[0]]["SliceProfileList"][0][subnet[1]]["uLThptPerSliceSubnet"]["MaxThpt"] = qos[index][1]
- request[subnet[0]]["SliceProfileList"][0][subnet[1]]["dLLatency"] = qos[index][2]
- request[subnet[0]]["SliceProfileList"][0][subnet[1]]["uLLatency"] = qos[index][2]
-
- #dus = self.nodes["public-prefixes"]
- #cus = self.nodes["public-prefixes"]
- dus = self.nodes["DU"]
- cus = self.nodes["CU"]
-
- if random.randint(0, 1) == 0:
- src = random.choice(dus)
- dst = random.choice(cus)
- else:
- src = random.choice(cus)
- dst = random.choice(dus)
-
- # Delete all the EpTransport objects from the request
- pop_keys = []
-
- for key in request:
- # Verify if the key is an EpTransport object
- if key.startswith("EpTransport") or key.startswith("EP_F1U"):
- # Aggregate the key to the list of keys to be removed
- pop_keys.append(key)
-
- for key in pop_keys:
- request.pop(key)
-
- # Randomly select a VLAN ID
- l_iid = ["100","200","300", "400"]
- vlan_id = random.choice(l_iid)
-
- # Create the EPs for the source and destination nodes
- ep_transport_src, ep_rp_src = self.__create_ep(src["node-name"], src["prefix"], vlan_id)
- request.update(ep_transport_src)
- request.update(ep_rp_src)
- ep_transport_dst, ep_rp_dst = self.__create_ep(dst["node-name"], dst["prefix"], vlan_id)
- request.update(ep_transport_dst)
- request.update(ep_rp_dst)
-
- ep_transport_src_name = list(ep_transport_src.keys())[0]
- ep_transport_dst_name = list(ep_transport_dst.keys())[0]
-
- request["MidhaulSliceSubnet1"]["EpTransport"] = [ep_transport_src_name, ep_transport_dst_name]
-
- request[ep_transport_src[ep_transport_src_name]["EpApplicationRef"][0]]["remoteAddress"] = request[ep_transport_dst[ep_transport_dst_name]["EpApplicationRef"][0]]["localAddress"]
- request[ep_transport_dst[ep_transport_dst_name]["EpApplicationRef"][0]]["remoteAddress"] = request[ep_transport_src[ep_transport_src_name]["EpApplicationRef"][0]]["localAddress"]
-
- return (str(request).replace('\t', '').replace('\n', '').replace("'", '"').replace("None", '"None"'))
-
-if __name__ == '__main__':
- creador = IntentCreator(os.path.join(file_path, "3gpp_template_empty.json"), os.path.join(file_path, "ips.json"))
- print(creador.create_intent())
diff --git a/src/old/send_request.py b/src/old/send_request.py
deleted file mode 100644
index dc55d57b9cb8a3eb134ecf82bc14f8389d7fe991..0000000000000000000000000000000000000000
--- a/src/old/send_request.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import sys, os
-import requests
-import time
-import json
-from intent_generator import IntentCreator
-
-# Obtain the current directory
-current_dir = os.path.dirname(os.path.abspath(__file__))
-
-# Create the path to the templates directory
-parent_dir = os.path.dirname(current_dir)
-file_path = os.path.join(parent_dir, "templates")
-
-def send_request(port):
- if len(sys.argv) == 2:
- resp = IntentCreator(os.path.join(file_path, "3gpp_template_empty.json"), os.path.join(file_path, "ips.json")).create_intent()
- requests.post(f'http://localhost:{port}/intent', headers={'Content-Type': 'application/json'}, data=resp)
- else:
- intent = sys.argv[2]
- with open(intent, 'r') as source:
- resp = source.read()
- resp = str(resp).replace('\t', '').replace('\n', '').replace("'", '"').replace("None", '"None"')
- requests.post(f'http://localhost:{port}/intent', headers={'Content-Type': 'application/json'}, data=resp)
-
-while True:
- # Use: python3 send_request.py
- send_request(sys.argv[1])
- time.sleep(3)
diff --git a/swagger/models/create_models.py b/swagger/models/create_models.py
index 3dac63b2b131e5e710f3a61b1e0b40f0f6d65336..94ca83bc53b978beb68512dd5959452375256f67 100644
--- a/swagger/models/create_models.py
+++ b/swagger/models/create_models.py
@@ -1,4 +1,4 @@
-# Copyright 2025 Telefonica Innovación Digital S.L.
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+#This file is an original contribution from Telefonica Innovación Digital S.L.
+
from flask_restx import fields
def create_gpp_nrm_28541_model(slice_ns):
diff --git a/swagger/slice_namespace.py b/swagger/slice_namespace.py
index 6585163a659b2eaa9db237a2c7a062ea8c4b29db..0f629f97e1a8ecbf4550f3e5a24e5ecca46c15ae 100644
--- a/swagger/slice_namespace.py
+++ b/swagger/slice_namespace.py
@@ -1,4 +1,4 @@
-# Copyright 2025 Telefonica Innovación Digital S.L.
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# This file is an original contribution from Telefonica Innovación Digital S.L.
+
from flask import request
from flask_restx import Namespace, Resource, fields, reqparse
from src.network_slice_controller import NSController