diff --git a/.clang-format b/.clang-format index d3378d0f4a..aa8f087091 100644 --- a/.clang-format +++ b/.clang-format @@ -60,6 +60,7 @@ ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH + - RB_FOREACH IncludeBlocks: Preserve IncludeCategories: - Regex: '^' diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a49bfdd73..b36bd18ce2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1292,6 +1292,7 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB_NGAP.c ${NR_RRC_DIR}/rrc_gNB_radio_bearers.c ${NR_RRC_DIR}/rrc_gNB_cuup.c + ${NR_RRC_DIR}/rrc_gNB_du.c ) set(L2_SRC_UE diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index bc6b36bd8b..7957bdf066 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -1245,7 +1245,7 @@ class Containerize(): fullStatus = True if anyLogs: # Analyzing log file(s)! - listOfPossibleRanContainers = ['enb', 'gnb', 'cu', 'du'] + listOfPossibleRanContainers = ['enb*', 'gnb*', 'cu*', 'du*'] for container in listOfPossibleRanContainers: filenames = './*-oai-' + container + '.log' cmd = f'ls {filenames}' diff --git a/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf b/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf index e7c5dd0514..8a33b6dd96 100644 --- a/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf +++ b/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf @@ -75,15 +75,11 @@ security = { drb_ciphering = "yes"; drb_integrity = "no"; }; - log_config : - { - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="debug"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - f1ap_log_level ="debug"; - ngap_log_level ="debug"; - }; + +log_config : { + global_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + f1ap_log_level = "info"; + ngap_log_level = "info"; +}; diff --git a/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf index 09f8d5007e..94474b86bf 100644 --- a/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf @@ -217,7 +217,7 @@ THREAD_STRUCT = ( rfsimulator: { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf index 5c674b3f6f..105530c0ba 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf @@ -217,21 +217,17 @@ THREAD_STRUCT = ( ); rfsimulator: { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" } - log_config : - { - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="info"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - f1ap_log_level ="debug"; - ngap_log_level ="debug"; - }; +log_config: { + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + f1ap_log_level = "info"; +}; diff --git a/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf index 66deda5e59..c81c9fb0f6 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf index b72217d5e6..706cae1e23 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf @@ -240,7 +240,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf index 60b1e92f9e..a6d97f67fe 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf @@ -232,7 +232,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf index 583235bf60..e736a8830f 100644 --- a/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf b/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf index 5dc8cf12f7..564bac2c85 100644 --- a/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf +++ b/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf @@ -229,7 +229,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 86d369e526..0f4e0e5487 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -32,9 +32,8 @@ 000022 000023 000024 + 000025 020021 - 020022 - 030021 100021 @@ -72,33 +71,33 @@ DeployGenObject - Deploy OAI 5G DU RF sim SA + Deploy 3 OAI 5G DUs RF sim SA yaml_files/5g_f1_rfsimulator - oai-du - 8 + oai-du oai-du2 oai-du3 + 10 DeployGenObject Deploy OAI 5G NR-UE RF sim SA yaml_files/5g_f1_rfsimulator - oai-nr-ue - 9 + oai-nr-ue oai-nr-ue2 + 12 + + + + DeployGenObject + Deploy OAI 5G NR-UE RF sim SA + yaml_files/5g_f1_rfsimulator + oai-nr-ue3 + 13 Ping - Ping ext-dn from NR-UE - rfsim5g_ue - -c 20 192.168.72.135 - 5 - - - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - -c 20 12.1.1.2 + Ping ext-dn from all NR-UEs + rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 + -c 20 192.168.72.135 -i0.25 5 diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index dd8c62d97d..e2c6d7ed0d 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -198,6 +198,42 @@ services: interval: 10s timeout: 5s retries: 5 + oai-du2: + image: oaisoftwarealliance/oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-du2 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim --gNBs.[0].gNB_ID 0xe01 --gNBs.[0].nr_cellid 87654321 --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 --MACRLCs.[0].local_n_address 192.168.71.143 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-cu + networks: + public_net: + ipv4_address: 192.168.71.143 + volumes: + - ../../conf_files/gnb-du.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 + oai-du3: + image: oaisoftwarealliance/oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-du3 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim --gNBs.[0].gNB_ID 0xe02 --gNBs.[0].nr_cellid 11111111 --gNBs.[0].servingCellConfigCommon.[0].physCellId 2 --MACRLCs.[0].local_n_address 192.168.71.144 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-cu + networks: + public_net: + ipv4_address: 192.168.71.144 + volumes: + - ../../conf_files/gnb-du.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 oai-nr-ue: image: oaisoftwarealliance/oai-nr-ue:develop privileged: true @@ -216,6 +252,42 @@ services: interval: 10s timeout: 5s retries: 5 + oai-nr-ue2: + image: oaisoftwarealliance/oai-nr-ue:develop + privileged: true + container_name: rfsim5g-oai-nr-ue2 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001101 -C 3619200000 --rfsimulator.serveraddr 192.168.71.143 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-du2 + networks: + public_net: + ipv4_address: 192.168.71.151 + volumes: + - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 + oai-nr-ue3: + image: oaisoftwarealliance/oai-nr-ue:develop + privileged: true + container_name: rfsim5g-oai-nr-ue3 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001102 -C 3619200000 --rfsimulator.serveraddr 192.168.71.144 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-du3 + networks: + public_net: + ipv4_address: 192.168.71.152 + volumes: + - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 networks: public_net: diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql b/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql index fbd7907a71..19a6e27079 100755 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql @@ -192,6 +192,8 @@ LOCK TABLES `users` WRITE; /*!40000 ALTER TABLE `users` DISABLE KEYS */; INSERT INTO `users` VALUES ('20834123456789','380561234567','35609204079300',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,'+�E��ų\0�,IH��H',0,0,00000000000000000096,'Px�X \Z1��x��','^��K�����FeU���'),('20810000001234','33611123456','35609204079299',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000281454575616225,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','�4�s@���z��~�'),('31002890832150','33638060059','35611302209414',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012416,'`�F�݆��D��ϛ���','�4�s@���z��~�'),('001010123456789','33600101789','35609204079298',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'\0 \n \r',1,0,00000000000000000351,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','L�*\\�����^��]� '),('208930000000001','33638030001','35609204079301',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000002','33638050002','35609204079502',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000020471,'\0 \n \r','�4�s@���z��~�'),('208950000000003','33638050003','35609204079503',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012343,'\0 \n \r','�4�s@���z��~�'),('208950000000004','33638050004','35609204079504',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000005','33638050005','35609204079505',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000001','33638050001','35609204079501',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000006','33638050006','35609204079506',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000007','33638050007','35609204079507',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208930000000002','33638030002','35609204079302',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000003','33638030003','35609204079303',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000004','33638030004','35609204079304',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000005','33638030005','35609204079305',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000006','33638030006','35609204079306',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000007','33638030007','35609204079307',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000007','33638040007','35609204079407',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000006','33638040006','35609204079406',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000005','33638040005','35609204079405',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000004','33638040004','35609204079404',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000003','33638040003','35609204079403',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000002','33638040002','35609204079402',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000001','33638040001','35609204079401',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208920100001100','33638020001','35609204079201',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001101','33638020001','35609204079201',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204937234,'\0 \n \r','�$I6;��+f�k�u�|�'),('208920100001102','33638020002','35609204079202',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001103','33638020003','35609204079203',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001104','33638020004','35609204079204',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001105','33638020005','35609204079205',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001106','33638020006','35609204079206',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000000000000006103,'ebd07771ace8677a','�$I6;��+f�k�u�|�'),('208920100001107','33638020007','35609204079207',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001108','33638020008','35609204079208',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001109','33638020009','35609204079209',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001110','33638020010','35609204079210',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001111','33638030011','35609304079211',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001112','33638030012','35609304079212',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001113','33638030013','35609304079213',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006263,'�SNܒ�Iv��e�6','�4�s@���z��~�'),('208950000000008','33638050008','35609204079508',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000009','33638050009','35609204079509',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000010','33638050010','35609204079510',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000011','33638050011','35609204079511',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000012','33638050012','35609204079512',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000013','33638050013','35609204079513',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000014','33638050014','35609204079514',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000015','33638050015','35609204079515',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000000000,'3536663032363164','�4�s@���z��~�'),('208920100001118','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204934762,'~?03�u-%�ey�y�','�$I6;��+f�k�u�|�'),('208920100001121','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'&��@xg�]���\n��Vp','�$I6;��+f�k�u�|�'),('208920100001119','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'269482407867805d','�$I6;��+f�k�u�|�'),('208920100001120','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'3236393438323430','�$I6;��+f�k�u�|�'); INSERT INTO `users` VALUES ('208990100001100','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1); +INSERT INTO `users` VALUES ('208990100001101','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1); +INSERT INTO `users` VALUES ('208990100001102','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1); INSERT INTO `users` VALUES ('208950000000031','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d); INSERT INTO `users` VALUES ('208950000000032','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d); INSERT INTO `users` VALUES ('208950000000033','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d); diff --git a/common/utils/telnetsrv/telnetsrv_bearer.c b/common/utils/telnetsrv/telnetsrv_bearer.c index f019d3d48b..7281ac3e6b 100644 --- a/common/utils/telnetsrv/telnetsrv_bearer.c +++ b/common/utils/telnetsrv/telnetsrv_bearer.c @@ -71,7 +71,7 @@ int add_bearer(char *buf, int debug, telnet_printfunc_t prnt) } // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti); if (!rrcue) ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); @@ -95,7 +95,7 @@ int release_bearer(char *buf, int debug, telnet_printfunc_t prnt) } // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti); if (!rrcue) ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 2d7019b00e..943a3eec29 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -87,7 +87,7 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) rnti = strtol(buf, NULL, 16); if (rnti < 1 || rnti >= 0xfffe) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); - ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + ue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti); if (!ue) ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n"); } diff --git a/doc/F1-design.md b/doc/F1-design.md index 7e491f5346..2666856a42 100644 --- a/doc/F1-design.md +++ b/doc/F1-design.md @@ -12,204 +12,44 @@ -# 1. Introduction +[[_TOC_]] -We use OpenAirInterface source code, and it's regular deployment scheme. +# Introduction -F1 specification is in 3GPP documents: TS 38.470 header document and all documents listed in chapter 2 References of TS 38.470. +The F1 interface is the functional split of 3GPP between the CU (centralized +unit: PDCP, RRC, SDAP) and the DU (distributed unit: RLC, MAC, PHY). It is +standardized in TS 38.470 - 38.473 for 5G NR. No equivalent for 4G exists. -This document explains how the source code works. +We assume that each DU handles only one cell. Multiple DUs connected to one CU +are supported. Mobility over F1 is not yet supported. -Offered features and deployment instructions are described in: -https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/f1-interface +# Control plane status (F1-C) -# 2. Common multi-threading architecture # +## Implementation Status -The CU and DU interfaces are based on ITTI threads (see oai/common/utils/ocp_itti/itti.md) +Note that OAI uses F1 "internally". That means, that even if you run a +monolithic gNB, the internal information exchange uses F1. You can therefore +expect that everything working in a monolithic deployment should also work in +F1. The current implementation is based on R16.3. -All OAI upper layers use the ITTI framework to run isolated threads dedicated to one feature. -The lower layers adopt case by case specific software architecture. +Note that NSA does NOT follow this logic yet, and does not work with F1. -```mermaid -graph TD -Linux[configuration file] --> APP[gNB_app_task] -Socks[Linux UDP] --> GTP[nr_gtpv1u_gNB_task] -APP --> CU -APP --> DU -A[Linux SCTP] -->|sockets| SCTP(OAI itti thread TASK_SCTP) -SCTP-->|TASK_NGAP| NG[ngap_gNB_task] -NG-->|TASK_SCTP| SCTP -SCTP-->|TASK_DU_F1| DU[F1AP_DU_task] -SCTP-->|TASK_CU_F1| CU[F1AP_CU_task] -CU-->|TASK_RRC_GNB| RRC -RRC -->|non ITTI| PHY[OAI L1+L2] -RRC -->|API calls to create tunnels| GTP -PHY --> |user plane| GTP -CU --> |TASK_GTPV1_U| GTP -DU --> |TASK_GTPV1_U| GTP -``` -A "task" is a Linux thread running infinite waiting loop on one ITTI queue +The following messages are currently implemented: -app task manages the initial configuration +- F1 Setup Request and F1 Setup Response/Failure +- Initial UL RRC, UL/DL RRC Message Transfer +- F1 UE Context management messages for the "good case" + * Setup Request/Response + * Modification Request/Response + * Release Request/Command/Complete -sctp task mamanges the SCTP Linux sockets +All other messages are not implemented or not working reliably: -CU code runs in the task F1AP_CU_task. It stores it's private data context in a static variable. No mutex is used, as the single interface to CU ITTI tast in incoming ITTI messages. CU task is a single ITTI queue, but multiple CU could exist in one Linux process, using the "instance id" (called "module id" also) to create separate contextual information for each CU instance. +- F1 CU/DU configuration updade +- Paging messages +- Warning Message transmissions -DU code runs in the task F1AP_DU_task. The design is similar to CU task - -All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design: - -1. tunnel creation/deletion is by C API functions direct calls (a mutex protects it) -2. outgoing packets are pushed in a ITTI queue to the gtp thread -3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block - - -# 3. CU F1AP messages # - -## startup - -CU thread starts when the CU starts. It opens listening socket on F1AP_PORT_NUMBER by sending the appropriate message to TASK_SCTP. - -It will accept the first incoming connection on this port - -## F1 SETUP - -DU has connected, and sent this message. - -The CU receives, decode it and send relevant information to RRC thread by message F1AP_SETUP_REQ - -## F1 SETUP response - -RRC sends two messages to CU F1 task: the information to encode the F1 setup response and a second message to encode F1AP_GNB_CU_CONFIGURATION_UPDATE - -Upon reception of these two messages the CU task encodes and sends the messages to the DU - -## UE entry - -When CCH channel decoding finds a new UE identity, it call rrc_gNB_generate_RRCSetup() that will send F1AP_DL_RRC_MESSAGE to the CU task. - -The CU encodes and sends to DU DLRRCMessageTransfer - -## UE attach/detach - -When rrc_gNB_process_RRCReconfigurationComplete() occurs, the RRC sends to CU task the message F1AP_UE_CONTEXT_SETUP_REQ. The CU task encodes the F1 message UEContextSetup and send it to the DU over F1AP. - -This function rrc_gNB_process_RRCReconfigurationComplete() also creates the GTP-U user plane bearers. - -## F1AP incoming messages - -SCTP tasks sends a ITTI message SCTP_DATA_IND to the CU task. - -A array of functions pointers and the F1AP standard identifier "procedureCode", the CU calls the appropriate function - -Hereafter the most significant messages processing - -### CU_handle_F1_SETUP_REQUEST - -Transcodes information to the same message toward RRC (F1AP_SETUP_REQ) - -### CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER - -Transcodes information to the same message toward RRC (NR_RRC_MAC_CCCH_DATA_IND) - -### CU_handle_UL_RRC_MESSAGE_TRANSFER - -Encode and send data to PDCP (calling pdcp_data_ind ()) for processing UL data. - -# DU F1 Messages - -## Startup - -The task "gNB app" after rzading the configuration file, sends a first message F1AP_SETUP_REQ to DU task - -Using this message, the uniq DU task (Linux Thread) creates a DU instance context memory space, calls SCTP task to create a socket to the CU. - -When it receives from the SCTP task the socket creation success, the DU task encodes+sends the F1 setup message to the CU. - -## F1AP_INITIAL_UL_RRC_MESSAGE - -When MAC layer push UL data to DU task, the DU sends to CU the message InitialULRRCMessageTransfer - -## F1AP_UL_RRC_MESSAGE - -In case of SRB bearer, the RLC layer use this message to push rlc bearer payload to DU task, that forward to CU - -## pdcp_data_ind - -This function call in RLC, when it is a DRB will be replaced by F1-U transport to CU - -## F1AP incoming messages - -SCTP tasks sends a ITTI message SCTP_DATA_IND to the DU task. - -A array of functions pointers and the F1AP standard identifier "procedureCode", the DU calls the appropriate function - -Hereafter the most significant messages processing - -### DU_send_F1_SETUP_RESPONSE - -Decode the CU message, then encode a message to TASK_GNB_APP. The thread "APP" extracts the system information block and reconfigure the DU with: du_extract_and_decode_SI(), configure_gnb_du_mac() - -### DU_handle_gNB_CU_CONFIGURATION_UPDATE - -No developped - -### DU_handle_UE_CONTEXT_SETUP_REQUEST - -Push data to RLC layer for transmisstion in DL (to the UE) by calling enqueue_rlc_data_req() - -### DU_handle_DL_RRC_MESSAGE_TRANSFER - -Depending on the content, adds UE context in DU low layers and/or send data to the UE with rlc_data_req() - -# F1-U messages - -The data path by itself doesn't make any difficulty: -1. for UL, rlc calls pdcp_data_ind (DRB) or sends a message to RRC (SRB). So, we can replace pdcp_data_ind() by du_pdcp_data_ind() that will push the message in the GTP tunnel. In CU, assuming the tunnel is in place, the right call back decapsulate the transport (cu_ul_recv()), then calls pdcp_data_ind() in CU -The SRB are sent in DU RRC tasks via itti F1AP_UL_RRC_MESSAGE (see above the processing) -2. For DL, pdcp (in CU for DRBs) calls rlc_data_req (by a decoupling queue and thread rlc_data_req_thread, so function du_rlc_data_req() or enqueue_rlc_data_req()). in DU, assuming the gtp-u tunnel exists, a reception call back (du_dl_recv()) decapsulate the gtp-u packet and calls du_rlc_data_req() - -Hereafter the processing design, that doesn't require to setup a new context storage, as we can use the GTP-U internal tables: rnti+rb=>teid for outgoing gtp-u packets and teid=>rnti+rb for incoming gtp-u packets - -In CU case, the DRB tunnel to DU and the tunnel on N3 have the same key (rnti, rb id), but they run in two different GTP-U instances. -Each instance binds on diffrent sockets. - -For F1-U, both DU and CU binds on the full quadruplet (IP source, port source, IP destination, port destination) from the configuration file parameters: -local_s_address, remote_s_address,local_s_portd, remote_s_portd - -These 4 values are in: -CU: at cell level (same level as nr_cellid parameter), they are read if tr_s_preference = "f1"; is set -DU: in block MACRLCs, if tr_n_preference = "f1"; is set in this block - -## tunnels setup -In GTP-U, TS 29.281 specifies a option header (NR RAN Container This extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user plane interfaces), but it is not mandatory optional header (as is the N3 one). - -So, we can use this header a something reliable with other vendors implementation. - -In DL, we need to associate the packet with: rnti, rb (radio bearer) and "mui" (a OAI internal id that is optional and may be removed soon) to call rlc_data_req() - -In UL, we need also the RNTI, the rb - -So, we need to create a gtp-u tunnel for each rb over F1, then manage in CU and DU the association between a uniq TEid and the pair(rnti, rb). This is already what we have in existing OAI GTP-U layer interface. - -In F1AP, for each "DRB to Be Setup Item IEs", we have a field TNL (transport network layer) to set a specific GTP tunnel (@IP, TEid, udp port is always 2152). This is the same for each message related to DRBs. (F1AP carries the SRB payload inside F1AP). - -So, For each F1AP containing DRB setup/modification/deletion, the related GTP-U tunnels will be modified one to one. -The exception is the intialisation of new tunnel: in the call to tunnel creation, we need to send the remote TEID, but we don't know yet if we are the initial source. In this case, we issue a dummy (0xFFFF) remote teid; when we receive the remote answer, we get the source teid, that we can inform GTP-U with (using update tunnel). - -## processing on GTP-U incoming message - -Du_dl_recv() or cu_ul_recv() are called because we have set this callbacks in creat/update tunnel calls to gtp-u. As gtp-u maintains a pair(rnti,rbid) associated to each tunnel, the functions can be very simple stateless callback that calls pdcp_data_ind() or rlc_data_req() to get back in normal processing path - -## CU/DU outgoing - -DU rlc north output goes to du_pdcp_data_ind() that push a outgoing packet request to gtp-u, using the rnti+rb as ids. GTP-U must have the tunnel existing, then it simply implement the same as in N3 for exemple. - -CU pdcp south output calls cu_rlc_data_ind() that do the same symetric processing. - - -# High-level F1-C code structure +## High-level F1-C code structure The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC) to exchange information. In DL, the CU sends messages as defined by the @@ -252,3 +92,233 @@ Monolithic: mac_rrc_dl_direct.c | | | | +-------------+ ``` + +# Data plane status (F1-U) + +F1-U uses GTP-U for information exchange. The GTP protocol uses some extensions +for NR-U protocol to report buffer status, but this is not properly tested and +might malfunction. One limitation is that the current implementation +acknowledges each packet individually. + +Multiple DUs at one CU are supported in the data plane (as in the control plane). + +# How to run + +As mentioned earlier, OAI uses F1 internally. It is always compiled in. +To start CU/DU, you use `./nr-softmodem` with the appropriate configuration +files, for instance: + +``` +sudo cmake_targets/ran_build/build/nr-softmodem --sa -O ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf +sudo cmake_targets/ran_build/build/nr-softmodem --sa -O ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf +``` + +These files are tested in the CI, and are configured for use in docker, +see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml). + +## Configuration of F1 IP/port information + +For a local deployment, you should update the following fields. +We assume that the CU will bind on `192.168.70.129` towards the core, +`127.0.0.3` towards the DU, and the DU `127.0.0.4` towards the CU. + +In the CU file: +- Update the `gNBs.[0].amf_ip_address` and `gNBs.[0].NETWORK_INTERFACES` + section towards the core (typically, OAI CN is configured to provide a docker + bridge on `192.168.70.129` and the AMF is on `192.168.70.132`): + - `gNBs.[0].amf_ip_address.[0].ipv4 192.168.70.132` + - `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.70.129` + - `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 192.168.70.132` +- Set `gNBs.[0].tr_s_preference` (transport south-bound) to `f1` +- Update the `gNBs.[0].local_s_address` (CU-local south address) for the F1-C + south-bound interface: `127.0.0.3` +- Note: the `gNBs.[0].remote_s_address` (CU-remote/DU south address) is + ignored, but we recommend to put `0.0.0.0` ("any") +- Ports should match the ones in the DU config, but for simplicity and + standards-conformity, simply set all to 2152: + - `local_s_portc` in CU should match `remote_n_portc` in DU + - `local_s_portd` in CU should match `remote_n_portd` in DU + - `remote_s_portc` in CU should match `local_n_portc` in DU + - `remote_s_portd` in CU should match `local_n_portd` in DU + +In the DU file: +- Set `MACRLCs.[0].tr_n_preference` to `f1` +- Update `MACRLCs.[0].local_n_address` (local north-bound address of the DU) to + `127.0.0.4` +- Update `MACRLCs.[].remote_n_address` (remote north-bound address of the CU) + to `127.0.0.3` + +Note: all `local_*_if_name` parameters are ignored. + +## Configuration of multiple DUs + +Upon F1 Setup Request of a new DU, the CU cross-checks that + +- no DUs have the same gNB-DU IDs, taken from `gNBs.[0].gNB_ID`, and +- no cells have the same NR Cell ID, taken from `gNBs.[0].nr_cellid`, and +- no cells have the same physical cell IDs, taken from `gNBs.[0].servingCellConfigCommon.[0].physCellId`. + +If any of these are the same, the CU will reject the DU with an F1 Setup +Failure. Thus, you should make sure that in the DU's configs, these parameters +are set differently. + +You have to of course make sure that the local interface of the DU +(`MACRLCs.[0].local_n_address`) is different as well. + +Assuming you use RFsim, you should make the RFsimulator server side (typically +the gNB) bind on different hosts (`rfsimulator.serverport`). + +# Code documentation + +## Common multi-threading architecture + +The CU and DU interfaces are based on ITTI threads (see `common/utils/ocp_itti/itti.md`) +adopted by all OAI upper layers to run isolated threads dedicated to one feature. + +```mermaid +graph TD +Linux[configuration file] --> APP[gNB_app_task] +Socks[Linux UDP] --> GTP[nr_gtpv1u_gNB_task] +APP --> CU +APP --> DU +A[Linux SCTP] -->|sockets| SCTP(OAI itti thread TASK_SCTP) +SCTP-->|TASK_NGAP| NG[ngap_gNB_task] +NG-->|TASK_SCTP| SCTP +SCTP-->|TASK_DU_F1| DU[F1AP_DU_task] +SCTP-->|TASK_CU_F1| CU[F1AP_CU_task] +CU-->|TASK_RRC_GNB| RRC +RRC -->|non ITTI| PHY[OAI L1+L2] +RRC -->|API calls to create tunnels| GTP +PHY --> |user plane| GTP +CU --> |TASK_GTPV1_U| GTP +DU --> |TASK_GTPV1_U| GTP +``` + +A "task" is a Linux thread running an infinite waiting loop on one ITTI queue. + +The `app` task manages the initial configuration; the `sctp` task manages the +SCTP Linux sockets. + +The CU encoding/decoding runs in the task executing `F1AP_CU_task()`. It stores its private data context in a static variable. +The DU encoding/decoding runs in the task executing `F1AP_DU_task()`. The design is similar to CU task. + +All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design: + +1. tunnel creation/deletion is by C API functions direct calls (a mutex protects it) +2. outgoing packets are pushed in a ITTI queue to the gtp thread +3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block + + +## F1-C messages towards the CU + +The CU thread starts when the CU starts. It opens listening socket on the +configuration-specified IP/port by sending the appropriate message to +`TASK_SCTP`. It will accept any incoming connection and forward any F1 message +to RRC. + +You can trace any message by looking up the handler +`cu_task_handle_sctp_data_ind()`, which ultimately triggers a corresponding +ITTI message sent to RRC. All ITTI messages arriving are dispatched in the ITTI +message handling function in `rrc_gNB.c`. For your convenience, find below a +table of same messages that might arrive from the DU and how they are +forwarded. + +After handling messages, the RRC uses a callback that determines if messages go +directly to the MAC or are sent to the CU ITTI task (see +[above](#high-level-f1-c-code-structure)) + +You might also want to consult TS 38.401 regarding the message exchange. + +| Incoming F1 message | ITTI message to RRC | RRC handler | Comments | +|---------------------|---------------------|-------------|----------| +| F1 Setup Request | `F1AP_SETUP_REQ` | `rrc_gNB_process_f1_setup_req()` | will trigger either a response or failure | +| Initial UL RRC Message Transfer | `F1AP_INITIAL_UL_RRC_MESSAGE` | `rrc_gNB_process_initial_ul_rrc_message()` | first message from UE, follows up with RRC Setup or Reestablishment | +| UL RRC Message Transfer | `F1AP_UL_RRC_MESSAGE` | `rrc_gNB_decode_dcch()` | UL RRC messages contain DCCH | +| UE Context Response | `F1AP_UE_CONTEXT_SETUP_RESP` | `rrc_CU_process_ue_context_setup_response()` | does not trigger a follow-up, as UE sends Security Response | +| UE Context Modification Response | `F1AP_UE_CONTEXT_MODIFICATION_RESP` | `rrc_CU_process_ue_context_modification_response()` | triggers Reconfiguration if CellGroup in answer | +| UE Context Modification Required | `F1AP_UE_CONTEXT_MODIFICATION_REQUIRED` | `rrc_CU_process_ue_modification_required()` | triggers Reconfiguration | +| UE Context Release Request | `F1AP_UE_CONTEXT_RELEASE_REQ` | `rrc_CU_process_ue_context_release_request()` | RRC will trigger UE release | +| UE Context Release Complete | `F1AP_UE_CONTEXT_RELEASE_COMPLETE` | `rrc_CU_process_ue_context_release_complete()` | frees UE Context, signals to NGAP | + +## F1-C Messages towards the DU + +The task "gNB app", after reading the configuration file, sends a message +`F1AP_DU_REGISTER_REQ` to the DU task. This message contains network +configuration for the establishment of the SCTP connection, as well as the F1 +Setup Request to be sent to the CU. + +Using the network configuration, the DU task sets up an SCTP connection via the +SCTP task. When it receives from the SCTP task the socket creation success, +the DU task encodes and sends the F1 setup message to the CU. + +Similarly as for the CU, you can trace any message by looking up the handler +`du_task_handle_sctp_data_ind()`. Unlike in the CU, the decoders do NOT send an +ITTI message, but directly call into the scheduler via a message handling +function. This handler acquires the scheduler mutex and executes the +corresponding message handling functionality. All handlers are in +`mac_rrc_dl_handler.c`. + +After handling messages, the MAC uses a callback that determines if messages +are sent back to RRC via ITTI, or are sent to the DU ITTI task (see +[above](#high-level-f1-c-code-structure)) + +You might also want to consult TS 38.401 regarding the message exchange. + +| Incoming F1 message | MAC handler | Comments | +|---------------------|-------------|----------| +| F1 Setup Response | `f1_setup_response()` | the DU does not start the radio before receiving this message | +| DL RRC Message Transfer | `dl_rrc_message_transfer()` | Processing timer started if reconfiguration is present[^footnote-reconfig] | +| UE Context Setup Request | `ue_context_setup_request()` | | +| UE Context Modification Request | `ue_context_modification_request()` | | +| UE Context Modification Confirm | `ue_context_modification_confirm()` | | +| UE Context Modification Refuse | `ue_context_modification_refuse()` | Will trigger release request | +| UE Context Release Command | `ue_context_release_command()` | Starts timer for release if UE in sync | + +[^footnote-reconfig]: The DU does not decode RRC messages, and does not know + whether an RRC message is a reconfiguration. However, the spec mandates that + a reconfiguration has to be triggered if the CU receives a CellGroupConfig, + originating at the DU. See also flag `expect_reconfiguration`. + +## F1-U messages + +### General + +In the DU in UL, RLC checks in `deliver_sdu()` if we are operating in split +mode, and either (direct) calls `pdcp_data_ind` (DRB) or (f1ap) sends an +`GTPV1U_TUNNEL_DATA_REQ` ITTI message to the GTP task. + +In the CU in UL, assuming the tunnel is in place, GTP decapsulates the packet +and calls the callback `cu_f1u_data_req()`, which calls `pdcp_data_ind()` in CU. + +In the CU in DL, the PDCP function `deliver_pdu_drb_gnb()` either (direct) calls +into the RLC via `enqueue_rlc_data_req()`, or (f1ap) sends a +`GTPV1U_TUNNEL_DATA_REQ` ITTI message to the GTP task. + +In the DU in DL, assuming the GTP-U tunnel exists, GTP decapsulates the packet +and calls the reception call back `du_rlc_data_req()`, which calls +`enqueue_rlc_data_req()` in turn. + +## Tunnel Setup + +In GTP-U, TS 29.281 specifies a optional header (NR RAN Container). This +extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user +plane interfaces, but it is not mandatory. + +Note that the GTP-U uses internal tables. Instead of exposing TEIDs, it uses the +UE ID (RNTI, RRC UE ID) and Radio Bearer ID to map to a TEID for outgoing GTP-U +packets. Upon receiving, it does the reverse and calls the callbacks. In the CU +case, the DRB tunnel to DU and the tunnel on N3 have the same keys (RRC UE ID, +RB ID), but they run in two different GTP-U instances. Each instance binds on +diffrent sockets, which is the reason you cannot have the same interface for +F1-U and N3/NG-U interfaces (this can be considered a design flaw). + +In F1AP, for each "DRB to Be Setup Item IEs", we have a field TNL (transport +network layer) to set a specific GTP tunnel (@IP, TEid). This is the same for +each message related to DRBs. + +So, For each F1AP containing DRB setup/modification/deletion, the related GTP-U +tunnels will be modified one to one. The exception is the intialisation of new +tunnel: in the call to tunnel creation, we need to send the remote TEID, but we +don't know yet if we are the initial source. In this case, we issue a dummy +(0xFFFF) remote TEID; when we receive the remote answer, we get the source teid, +with which the GTP-U endpoint is updadet. diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 57860e9b89..edead47430 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -393,10 +393,11 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf return -1; } - LOG_I(NR_RRC, "Creating NR RRC gNB Task, that will also create TASKS\n"); - if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); - return -1; + if (!NODE_IS_DU(node_type)) { + if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); + return -1; + } } // If CU diff --git a/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c b/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c index 3550a80981..0a14dfe915 100644 --- a/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c +++ b/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c @@ -38,7 +38,7 @@ void read_gtp_sm(void * data) UE_iterator(UE_info->list, UE) { uint16_t const rnti = UE->rnti; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[mod_id], rnti); + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[mod_id], rnti); if (ue_context_p != NULL) { gtp->msg.ngut[i].rnti = ue_context_p->ue_context.rnti; int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions; diff --git a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c index ea1735fcd8..dc173cc52f 100644 --- a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c +++ b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c @@ -43,7 +43,7 @@ matched_ues_mac_t filter_ues_by_s_nssai_in_du_or_monolithic(test_cond_e const co { if (NODE_IS_MONOLITHIC(RC.nrrrc[0]->node_type)) { - rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti); + rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], ue->rnti); ngap_ue_context_list = ngap_get_ue_context(rrc_ue_context_list->ue_context.rrc_ue_id); assert(ngap_ue_context_list->gNB_instance[0].s_nssai[0][0].sST == value && "Please, check the condition for S-NSSAI. At the moment, OAI supports eMBB"); } @@ -589,7 +589,7 @@ kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3_in_monolithic(const matched_ues_ma for (size_t i = 0; isib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); sys_info->sib1_length = DUsi->sIB1_message.size; } - - // char *measurement_timing_information[F1AP_MAX_NB_CELLS]; - // uint8_t ranac[F1AP_MAX_NB_CELLS]; - // int fdd_flag = f1ap_setup_req->fdd_flag; - // union { - // struct { - // uint32_t ul_nr_arfcn; - // uint8_t ul_scs; - // uint8_t ul_nrb; - // uint32_t dl_nr_arfcn; - // uint8_t dl_scs; - // uint8_t dl_nrb; - // uint32_t sul_active; - // uint32_t sul_nr_arfcn; - // uint8_t sul_scs; - // uint8_t sul_nrb; - // uint8_t num_frequency_bands; - // uint16_t nr_band[32]; - // uint8_t num_sul_frequency_bands; - // uint16_t nr_sul_band[32]; - // } fdd; - // struct { - // uint32_t nr_arfcn; - // uint8_t scs; - // uint8_t nrb; - // uint32_t sul_active; - // uint32_t sul_nr_arfcn; - // uint8_t sul_scs; - // uint8_t sul_nrb; - // uint8_t num_frequency_bands; - // uint16_t nr_band[32]; - // uint8_t num_sul_frequency_bands; - // uint16_t nr_sul_band[32]; - // } tdd; - // } nr_mode_info[F1AP_MAX_NB_CELLS]; - - if (req->num_cells_available > 0) { - itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); - } else { - CU_send_F1_SETUP_FAILURE(instance); - itti_free(TASK_CU_F1,message_p); - return -1; - } + + itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); return 0; } -int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp) +int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp) { F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; @@ -339,11 +299,12 @@ int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int CU_send_F1_SETUP_FAILURE(instance_t instance) { +int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail) +{ LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n"); F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; @@ -406,7 +367,7 @@ int CU_send_F1_SETUP_FAILURE(instance_t instance) { } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -419,12 +380,12 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) { AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) { AssertFatal(1==0,"Not implemented yet\n"); } @@ -433,8 +394,8 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, gNB-CU Configuration Update */ -//void CU_send_gNB_CU_CONFIGURATION_UPDATE(F1AP_GNBCUConfigurationUpdate_t *GNBCUConfigurationUpdate) { -int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update) { +int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update) +{ F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer; uint32_t len; @@ -520,7 +481,7 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configu LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-CU CONFIGURATION UPDATE : "); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -546,7 +507,7 @@ int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, AssertFatal(0, "Not implemented yet\n"); } -int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, +int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id, F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse) { AssertFatal(0, "Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h index abdb60bf88..4d3f562128 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.h +++ b/openair2/F1AP/f1ap_cu_interface_management.h @@ -36,41 +36,41 @@ /* * Reset */ -int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); +int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset); int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); +int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge); /* * Error Indication */ int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication); +int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication); /* * F1 Setup */ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp); +int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp); -int CU_send_F1_SETUP_FAILURE(instance_t instance); +int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail); /* * gNB-DU Configuration Update */ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure); -int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge); /* * gNB-CU Configuration Update */ -int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update); +int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update); int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, @@ -89,7 +89,7 @@ int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, +int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id, F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse); #endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c index 5175456c4e..330264ffd2 100644 --- a/openair2/F1AP/f1ap_cu_paging.c +++ b/openair2/F1AP/f1ap_cu_paging.c @@ -37,7 +37,8 @@ extern f1ap_setup_req_t *f1ap_du_data_from_du; -int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { +int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging) +{ F1AP_F1AP_PDU_t pdu = {0}; pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; @@ -114,6 +115,6 @@ int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { return -1; } ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h index 5cff651fcc..4029d27312 100644 --- a/openair2/F1AP/f1ap_cu_paging.h +++ b/openair2/F1AP/f1ap_cu_paging.h @@ -32,5 +32,5 @@ #ifndef F1AP_CU_PAGING_H_ #define F1AP_CU_PAGING_H_ -int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging); +int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging); #endif /* F1AP_DU_PAGING_H_ */ diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 391841cfa0..03c210c972 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -88,6 +88,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t // create an ITTI message and copy SDU message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); ul_rrc->gNB_DU_ue_id = du_ue_id; ul_rrc->nr_cellid = nr_cellid; // CU instance @@ -107,9 +108,8 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t /* DL RRC Message Transfer. */ -//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) { -int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, - f1ap_dl_rrc_message_t *f1ap_dl_rrc) { +int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc) +{ LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n"); F1AP_F1AP_PDU_t pdu= {0}; F1AP_DLRRCMessageTransfer_t *out; @@ -207,7 +207,7 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.h b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h index 6b7023a84d..a0c732d104 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h @@ -35,7 +35,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, f1ap_dl_rrc_message_t *f1ap_dl_rrc); +int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc); int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 3d1f0b6aac..1c2b727237 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -53,20 +53,12 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind, eth_params_t *IPaddrs) { - createF1inst(instance, NULL, NULL); // save the assoc id f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); - f1ap_cu_data->assoc_id = sctp_new_association_ind->assoc_id; + // we don't need the assoc_id, subsequent messages (the first being F1 Setup + // Request), will deliver the assoc_id f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; - if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) { - getCxt(instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs); - AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); - } else - LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n"); - // Fixme: fully inconsistent instances management - // dirty global var is a bad fix - CUuniqInstance=getCxt(instance)->gtpInst; } static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { @@ -76,7 +68,6 @@ static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_a f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); AssertFatal(f1ap_cu_data != NULL, "illegal state: SCTP shutdown for non-existing F1AP endpoint\n"); LOG_I(F1AP, "Received SCTP shutdown for assoc_id %d, removing endpoint\n", sctp_new_association_resp->assoc_id); - destroyF1inst(instance); /* inform RRC that the DU is gone */ MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_LOST_CONNECTION); message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id; @@ -139,12 +130,25 @@ void *F1AP_CU_task(void *arg) { // Hardcoded instance id! IPaddrs = &RC.nrrrc[0]->eth_params_s; - cu_task_send_sctp_init_req(0, IPaddrs->my_addr); + const int instance = 0; + createF1inst(instance, NULL, NULL); + cu_task_send_sctp_init_req(instance, IPaddrs->my_addr); + + if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) { + getCxt(instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs); + AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); + } else { + LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n"); + } + // Fixme: fully inconsistent instances management + // dirty global var is a bad fix + CUuniqInstance=getCxt(instance)->gtpInst; while (1) { itti_receive_msg(TASK_CU_F1, &received_msg); - LOG_D(F1AP, "CU Task Received %s for instance %ld\n", - ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg)); + sctp_assoc_t assoc_id = ITTI_MSG_ORIGIN_INSTANCE(received_msg); + LOG_D(F1AP, "CU Task Received %s for instance %ld: sending SCTP message via assoc_id %d\n", + ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg), assoc_id); switch (ITTI_MSG_ID(received_msg)) { case SCTP_NEW_ASSOCIATION_IND: cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg), @@ -163,59 +167,55 @@ void *F1AP_CU_task(void *arg) { break; case F1AP_SETUP_RESP: // from rrc - CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_F1_SETUP_RESPONSE(assoc_id, &F1AP_SETUP_RESP(received_msg)); break; + case F1AP_SETUP_FAILURE: + CU_send_F1_SETUP_FAILURE(assoc_id, &F1AP_SETUP_FAILURE(received_msg)); + break; + case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc - CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_gNB_CU_CONFIGURATION_UPDATE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg)); break; case F1AP_DL_RRC_MESSAGE: // from rrc - CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_DL_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_DL_RRC_MESSAGE(received_msg)); free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container); break; case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc - CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_SETUP_REQUEST(assoc_id, &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REQ: - CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_MODIFICATION_REQUEST(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc - CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_RELEASE_COMMAND(assoc_id, &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); break; case F1AP_PAGING_IND: - CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_Paging(assoc_id, &F1AP_PAGING_IND(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM: - CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REFUSE: - CU_send_UE_CONTEXT_MODIFICATION_REFUSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_MODIFICATION_REFUSE(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg)); break; - // case F1AP_SETUP_RESPONSE: // This is from RRC - // CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp) - // break; - - // case F1AP_SETUP_FAILURE: // This is from RRC - // CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure) - // break; - case TERMINATE_MESSAGE: LOG_W(F1AP, " *** Exiting F1AP thread\n"); itti_exit_task(); @@ -232,5 +232,7 @@ void *F1AP_CU_task(void *arg) { received_msg = NULL; } // while + destroyF1inst(instance); + return NULL; } diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index ff82cd3840..94cecd6254 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -65,8 +65,8 @@ static void setQos(F1AP_NonDynamic5QIDescriptor_t *toFill) { } } -int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, - f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) { +int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) +{ F1AP_F1AP_PDU_t pdu= {0}; /* Create */ /* 0. Message Type */ @@ -506,7 +506,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(instance)->gtpInst, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, f1ap_ue_context_setup_req->gNB_CU_ue_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, @@ -625,7 +625,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, // return -1; // } LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -636,6 +636,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_ F1AP_UEContextSetupResponseIEs_t *ie; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_RESP); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_setup_t *f1ap_ue_context_setup_resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextSetupResponse; int i; @@ -769,6 +770,7 @@ int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_i int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); F1AP_UEContextReleaseRequest_t *container; F1AP_UEContextReleaseRequestIEs_t *ie; @@ -822,9 +824,8 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc return 0; } - -int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, - f1ap_ue_context_release_cmd_t *cmd) { +int CU_send_UE_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, f1ap_ue_context_release_cmd_t *cmd) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextReleaseCommand_t *out; uint8_t *buffer=NULL; @@ -909,7 +910,7 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -919,6 +920,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso F1AP_UEContextReleaseCompleteIEs_t *ie; DevAssert(pdu); MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete; /* GNB_CU_UE_F1AP_ID */ @@ -948,7 +950,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; @@ -1548,7 +1550,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; /* dRBID */ drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id; - newGtpuDeleteOneTunnel(getCxt(instance)->gtpInst, + newGtpuDeleteOneTunnel(getCxt(0)->gtpInst, f1ap_ue_context_modification_req->gNB_CU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } @@ -1559,7 +1561,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n"); return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -1570,6 +1572,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t F1AP_UEContextModificationResponseIEs_t *ie; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; int i; @@ -1698,6 +1701,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t DevAssert(pdu != NULL); MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p); F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired; @@ -1826,7 +1830,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm) +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(sctp_assoc_t assoc_id, f1ap_ue_context_modif_confirm_t *confirm) { F1AP_F1AP_PDU_t pdu = {0}; pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; @@ -1884,11 +1888,11 @@ int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n"); return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse) +int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_refuse_t *refuse) { F1AP_F1AP_PDU_t pdu = {0}; pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; @@ -1951,6 +1955,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_ LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n"); return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 5409c6e53e..05e67930b3 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -36,7 +36,7 @@ /* * UE Context Setup */ -int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, +int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req); int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -51,7 +51,7 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc /* * UE Context Release (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, +int CU_send_UE_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, f1ap_ue_context_release_cmd_t *cmd); int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -59,7 +59,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso /* * UE Context Modification (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -68,9 +68,9 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t */ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm); +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(sctp_assoc_t assoc_id, f1ap_ue_context_modif_confirm_t *confirm); -int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse); +int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_refuse_t *refuse); /* * UE Inactivity Notification diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index b9dfdcd668..91454a8b66 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -55,11 +55,12 @@ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { +int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) { AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { +int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset) +{ AssertFatal(1==0,"Not implemented yet\n"); } @@ -72,7 +73,8 @@ int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint Error Indication */ -int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p) { +int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p) +{ AssertFatal(1==0,"Not implemented yet\n"); } @@ -86,7 +88,7 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3 */ // SETUP REQUEST -int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req) +int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req) { F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer; @@ -298,7 +300,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req) } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -317,7 +319,6 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint F1AP_F1SetupResponseIEs_t *ie; int TransactionId = -1; int num_cells_to_activate = 0; - F1AP_Cells_to_be_Activated_List_Item_t *cell; f1ap_setup_resp_t resp = {0}; for (int i=0; i < in->protocolIEs.list.count; i++) { @@ -365,7 +366,8 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject"); AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item, "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item"); - cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item; + F1AP_Cells_to_be_Activated_List_Item_t *cell = + &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item; TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, resp.cells_to_activate[i].plmn.mcc, resp.cells_to_activate[i].plmn.mnc, @@ -377,6 +379,8 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint cell->nRCGI.nRCellIdentity.buf[3], cell->nRCGI.nRCellIdentity.buf[4]); BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, resp.cells_to_activate[i].nr_cellid); + if (cell->nRPCI != NULL) + resp.cells_to_activate[i].nrpci = *cell->nRPCI; F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions; if (ext==NULL) @@ -492,10 +496,8 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3 gNB-DU Configuration Update */ -//void DU_send_gNB_DU_CONFIGURATION_UPDATE(F1AP_GNBDUConfigurationUpdate_t *GNBDUConfigurationUpdate) { -int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, - instance_t du_mod_idP, - f1ap_setup_req_t *f1ap_setup_req) { +int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t *f1ap_setup_req) +{ F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; uint32_t len=0; @@ -891,14 +893,16 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso return 0; } -int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, +int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure) { AssertFatal(1==0,"received gNB CU CONFIGURATION UPDATE FAILURE with cause %d\n", GNBCUConfigurationUpdateFailure->cause); } -int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, - f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) { +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE( + sctp_assoc_t assoc_id, + f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) +{ AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0, "%d cells failed to activate\n", GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated); @@ -937,13 +941,13 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } - -int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, - F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) { +int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id, + F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) +{ AssertFatal(0, "Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h index f077dc547a..8fa166d0bc 100644 --- a/openair2/F1AP/f1ap_du_interface_management.h +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -37,20 +37,20 @@ * Reset */ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); -int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); +int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge); +int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset); int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); /* * Error Indication */ -int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p); +int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p); int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); /* * F1 Setup */ -int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req); +int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req); int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -59,8 +59,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3 /* * gNB-DU Configuration Update */ -int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, - instance_t du_mod_idP, +int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t *f1ap_du_data); int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -75,10 +74,10 @@ int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, */ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, +int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure); -int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge); @@ -86,7 +85,7 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, /* * gNB-DU Resource Coordination */ -int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, +int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id, F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest); int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c index 08a2b319e7..5351b6bf26 100644 --- a/openair2/F1AP/f1ap_du_paging.c +++ b/openair2/F1AP/f1ap_du_paging.c @@ -87,9 +87,7 @@ int DU_handle_Paging(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, F1AP_ProtocolIE_ID_id_PagingCell_List, true); - for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - rrc_gNB_generate_pcch_msg((uint32_t)tmsi, pagingdrx, instance, CC_id); - } + AssertFatal(false, "not implemented\n"); return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 5a61879059..3a2f7ce725 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -141,7 +141,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id } /* UL RRC Message Transfer */ -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg) +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_InitialULRRCMessageTransfer_t *out; @@ -170,7 +170,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI; //Fixme: takes always the first cell - addnRCGI(ie2->value.choice.NRCGI, &getCxt(instanceP)->setupReq.cell[0].info); + addnRCGI(ie2->value.choice.NRCGI, &getCxt(0)->setupReq.cell[0].info); /* mandatory */ /* c3. C_RNTI */ // 16 asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3); @@ -211,20 +211,18 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini return -1; } - f1ap_itti_send_sctp_data_req(instanceP, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) +int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_ULRRCMessageTransfer_t *out; uint8_t *buffer = NULL; uint32_t len; LOG_D(F1AP, - "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", - instance, - __func__, + "size %d UE RNTI %x in SRB %d\n", msg->rrc_container_length, msg->gNB_DU_ue_id, msg->srb_id); @@ -277,6 +275,6 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_me return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h index e959d8b9e1..4064a7cd2a 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -38,8 +38,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg); +int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg); -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg); +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg); #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 797099a480..7ba479e1f9 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -76,11 +76,11 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat } // save the assoc id - f1ap_du_data->assoc_id = sctp_new_association_resp->assoc_id; + f1ap_du_data->du.assoc_id = sctp_new_association_resp->assoc_id; f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams; f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams; /* setup parameters for F1U and start the server */ - DU_send_F1_SETUP_REQUEST(instance, &f1ap_du_data->setupReq); + DU_send_F1_SETUP_REQUEST(f1ap_du_data->du.assoc_id, &f1ap_du_data->setupReq); } void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { @@ -102,8 +102,8 @@ void *F1AP_DU_task(void *arg) { MessageDef *msg = NULL; itti_receive_msg(TASK_DU_F1, &msg); instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); - LOG_D(F1AP, "DU Task Received %s for instance %ld\n", - ITTI_MSG_NAME(msg),myInstance); + sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->du.assoc_id : 0; + LOG_D(F1AP, "DU Task Received %s for instance %ld: sending SCTP messages via assoc_id %d\n", ITTI_MSG_NAME(msg), myInstance, assoc_id); switch (ITTI_MSG_ID(msg)) { case F1AP_SETUP_REQ: AssertFatal(false, "the F1AP_SETUP_REQ should not be received; use the F1AP_DU_REGISTER_REQ instead\n"); @@ -121,12 +121,12 @@ void *F1AP_DU_task(void *arg) { } break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: - DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg), + DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg)); break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE: - DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(myInstance, + DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(msg)); break; @@ -144,34 +144,32 @@ void *F1AP_DU_task(void *arg) { break; case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc - { - f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); - DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(myInstance, msgRrc); - } break; + DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_INITIAL_UL_RRC_MESSAGE(msg)); + break; case F1AP_UL_RRC_MESSAGE: // to rrc - DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, &F1AP_UL_RRC_MESSAGE(msg)); + DU_send_UL_NR_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_UL_RRC_MESSAGE(msg)); break; case F1AP_UE_CONTEXT_SETUP_RESP: - DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); + DU_send_UE_CONTEXT_SETUP_RESPONSE(assoc_id, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_RESP: - DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); + DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); break; case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC - DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance, + DU_send_UE_CONTEXT_RELEASE_REQUEST(assoc_id, &F1AP_UE_CONTEXT_RELEASE_REQ(msg)); break; case F1AP_UE_CONTEXT_RELEASE_COMPLETE: - DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); + DU_send_UE_CONTEXT_RELEASE_COMPLETE(assoc_id, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED: - DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg)); + DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg)); break; case TERMINATE_MESSAGE: diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 49e19f7697..fe7b8c78f5 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -205,7 +205,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i return 0; } -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { +int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *resp) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextSetupResponse_t *out; uint8_t *buffer=NULL; @@ -329,7 +330,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ @@ -542,15 +543,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) { +int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id) +{ AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, - f1ap_ue_context_release_req_t *req) { + +int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_release_req_t *req) +{ F1AP_F1AP_PDU_t pdu; F1AP_UEContextReleaseRequest_t *out; uint8_t *buffer=NULL; @@ -617,7 +620,7 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -681,7 +684,7 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc return 0; } -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete) +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextReleaseComplete_t *out; @@ -764,7 +767,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -986,8 +989,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t return 0; } -//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp) +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationResponse_t *out; @@ -1079,7 +1081,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex transport_layer_addr_t tl_addr = {0}; memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; - drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(instance)->gtpInst, + drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, resp->gNB_DU_ue_id, drb->drb_id, drb->drb_id, @@ -1098,7 +1100,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ @@ -1136,7 +1138,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); @@ -1211,7 +1213,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex /* 8.1 SCell_ToBeSetup_Item */ F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; /* - sCell_ID */ - addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(instance)->setupReq.cell[i].info); + addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(0)->setupReq.cell[i].info); asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); tmp->present = F1AP_Cause_PR_radioNetwork; tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; @@ -1320,15 +1322,15 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { +int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id) { AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required) +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required) { /* 0. Message Type */ F1AP_F1AP_PDU_t pdu = {0}; @@ -1444,7 +1446,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_contex return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index 536007da42..43663ba538 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -36,16 +36,16 @@ /* * UE Context Setup */ -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req); +int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *req); int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance); +int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id); /* * UE Context Release Request (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, +int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_release_req_t *req); @@ -57,20 +57,20 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc /* * UE Context Release Complete (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete); +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete); /* * UE Context Modification (gNB-CU initiated) */ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp); -int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp); +int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id); /* * UE Context Modification Required (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required); +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required); int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); diff --git a/openair2/F1AP/f1ap_ids.h b/openair2/F1AP/f1ap_ids.h index 60d35de737..54d17243c5 100644 --- a/openair2/F1AP/f1ap_ids.h +++ b/openair2/F1AP/f1ap_ids.h @@ -34,6 +34,7 @@ typedef struct f1_ue_data_t { uint32_t secondary_ue; sctp_assoc_t e1_assoc_id; + sctp_assoc_t du_assoc_id; // only used at the CU } f1_ue_data_t; void cu_init_f1_ue_data(void); diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index d4e112d1d5..cdda26c5f6 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -22,27 +22,14 @@ #include "f1ap_common.h" #include "f1ap_itti_messaging.h" -void f1ap_itti_send_sctp_data_req(instance_t instance, uint8_t *buffer, uint32_t buffer_length) +void f1ap_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length) { - MessageDef *message_p; - sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_CU_F1, 0, SCTP_DATA_REQ); - sctp_data_req = &message_p->ittiMsg.sctp_data_req; - sctp_data_req->assoc_id = getCxt(instance)->assoc_id; - sctp_data_req->buffer = buffer; + instance_t instance = 0; // we have only one instance + MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, instance, SCTP_DATA_REQ); + sctp_data_req_t *sctp_data_req = &message_p->ittiMsg.sctp_data_req; + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; sctp_data_req->stream = 0; - LOG_D(F1AP, "Sending ITTI message to SCTP Task\n"); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } - -void f1ap_itti_send_sctp_close_association(instance_t instance) -{ - MessageDef *message_p = NULL; - sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION); - sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; - sctp_close_association_p->assoc_id = getCxt(instance)->assoc_id; - itti_send_msg_to_task(TASK_SCTP, instance, message_p); -} - diff --git a/openair2/F1AP/f1ap_itti_messaging.h b/openair2/F1AP/f1ap_itti_messaging.h index b132b3d826..6adc3d320e 100644 --- a/openair2/F1AP/f1ap_itti_messaging.h +++ b/openair2/F1AP/f1ap_itti_messaging.h @@ -22,6 +22,6 @@ #ifndef F1AP_ITTI_MESSAGING_H_ #define F1AP_ITTI_MESSAGING_H_ -void f1ap_itti_send_sctp_data_req(instance_t instance, uint8_t *buffer, uint32_t buffer_length); +void f1ap_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length); #endif /* F1AP_ITTI_MESSAGING_H_ */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index ab3b7646e7..19289597e3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -27,6 +27,7 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_setup_req_t *f1ap_msg = &F1AP_SETUP_REQ(msg); f1ap_msg->gNB_DU_id = req->gNB_DU_id; f1ap_msg->gNB_DU_name = strdup(req->gNB_DU_name); @@ -71,6 +72,7 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, (void) req; /* we don't need the request -- it is to set up GTP in F1 case */ MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg); /* copy all fields, but reallocate memory buffers! */ *f1ap_msg = *resp; @@ -100,6 +102,7 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ { (void)req; /* we don't need the request -- it is to set up GTP in F1 case */ MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; @@ -152,6 +155,7 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ static void ue_context_modification_required_direct(const f1ap_ue_context_modif_required_t *required) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg); f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id; f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id; @@ -177,6 +181,7 @@ static void ue_context_modification_required_direct(const f1ap_ue_context_modif_ static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); *f1ap_msg = *req; itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); @@ -185,6 +190,7 @@ static void ue_context_release_request_direct(const f1ap_ue_context_release_req_ static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); *f1ap_msg = *complete; itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); @@ -193,6 +199,7 @@ static void ue_context_release_complete_direct(const f1ap_ue_context_release_com static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + msg->ittiMsgHeader.originInstance = -1; // means monolithic /* copy all fields, but reallocate rrc_containers! */ f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); *f1ap_msg = *ul_rrc; diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 6e43212f5e..36c6af4396 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -25,16 +25,16 @@ #include "platform_types.h" #include "f1ap_messages_types.h" -typedef void (*f1_setup_response_func_t)(const f1ap_setup_resp_t *resp); -typedef void (*f1_setup_failure_func_t)(const f1ap_setup_failure_t *fail); +typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp); +typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail); -typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); -typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); -typedef void (*ue_context_modification_confirm_func_t)(const f1ap_ue_context_modif_confirm_t *confirm); -typedef void (*ue_context_modification_refuse_func_t)(const f1ap_ue_context_modif_refuse_t *refuse); -typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); +typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req); +typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req); +typedef void (*ue_context_modification_confirm_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm); +typedef void (*ue_context_modification_refuse_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse); +typedef void (*ue_context_release_command_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd); -typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc); +typedef void (*dl_rrc_message_transfer_func_t)(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc); struct nr_mac_rrc_dl_if_s; void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index ee9a29c6ae..55d1bf0236 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -24,14 +24,62 @@ #include "mac_rrc_dl.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" +static void f1_setup_response_direct(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + f1_setup_response(resp); +} + +static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + f1_setup_failure(fail); +} + +static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_setup_request(req); +} + +static void ue_context_modification_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_modification_request(req); +} + +static void ue_context_modification_confirm_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_modification_confirm(confirm); +} + +static void ue_context_modification_refuse_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_modification_refuse(refuse); +} + +static void ue_context_release_command_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_release_command(cmd); +} + +static void dl_rrc_message_transfer_direct(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + dl_rrc_message_transfer(dl_rrc); +} + void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { - mac_rrc->f1_setup_response = f1_setup_response; - mac_rrc->f1_setup_failure = f1_setup_failure; - mac_rrc->ue_context_setup_request = ue_context_setup_request; - mac_rrc->ue_context_modification_request = ue_context_modification_request; - mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm; - mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse; - mac_rrc->ue_context_release_command = ue_context_release_command; - mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer; + mac_rrc->f1_setup_response = f1_setup_response_direct; + mac_rrc->f1_setup_failure = f1_setup_failure_direct; + mac_rrc->ue_context_setup_request = ue_context_setup_request_direct; + mac_rrc->ue_context_modification_request = ue_context_modification_request_direct; + mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_direct; + mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_direct; + mac_rrc->ue_context_release_command = ue_context_release_command_direct; + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 951e9639c5..891d5d94f1 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -24,9 +24,10 @@ #include "mac_rrc_dl.h" #include "nr_rrc_defs.h" -static void f1_setup_response_f1ap(const f1ap_setup_resp_t *resp) +static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_resp_t *f1ap_msg = &F1AP_SETUP_RESP(msg); *f1ap_msg = *resp; if (resp->gNB_CU_name != NULL) @@ -34,17 +35,19 @@ static void f1_setup_response_f1ap(const f1ap_setup_resp_t *resp) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void f1_setup_failure_f1ap(const f1ap_setup_failure_t *fail) +static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_FAILURE); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_failure_t *f1ap_msg = &F1AP_SETUP_FAILURE(msg); *f1ap_msg = *fail; itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) +static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); *f1ap_msg = *req; AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); @@ -59,9 +62,10 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req) +static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg); *f1ap_msg = *req; if (req->cu_to_du_rrc_information != NULL) { @@ -110,9 +114,10 @@ static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_confirm_t *confirm) +static void ue_context_modification_confirm_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_CONFIRM); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_confirm_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(msg); f1ap_msg->gNB_CU_ue_id = confirm->gNB_CU_ue_id; f1ap_msg->gNB_DU_ue_id = confirm->gNB_DU_ue_id; @@ -127,17 +132,19 @@ static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_con itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_refuse_f1ap(const f1ap_ue_context_modif_refuse_t *refuse) +static void ue_context_modification_refuse_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REFUSE); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_refuse_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(msg); *f1ap_msg = *refuse; itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) +static void ue_context_release_command_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd) { MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); *msg = *cmd; if (cmd->rrc_container_length > 0) { @@ -149,11 +156,12 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } -static void dl_rrc_message_transfer_f1ap(const f1ap_dl_rrc_message_t *dl_rrc) +static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); + message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); *msg = *dl_rrc; if (dl_rrc->old_gNB_DU_ue_id) { diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 2d5e00b3fc..892873638a 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -366,6 +366,9 @@ typedef struct cucp_cuup_if_s { } cucp_cuup_if_t; typedef struct nr_rrc_du_container_t { + /* Tree-related data */ + RB_ENTRY(nr_rrc_du_container_t) entries; + sctp_assoc_t assoc_id; f1ap_setup_req_t *setup_req; NR_MIB_t *mib; @@ -408,7 +411,9 @@ typedef struct gNB_RRC_INST_s { nr_mac_rrc_dl_if_t mac_rrc; cucp_cuup_if_t cucp_cuup; - nr_rrc_du_container_t *du; + RB_HEAD(rrc_du_tree, nr_rrc_du_container_t) dus; // DUs, indexed by assoc_id + size_t num_dus; + RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id size_t num_cuups; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 36ab857518..9ca0ce612f 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -152,7 +152,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint); -int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); +int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx); void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size); /** @}*/ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 25ca92cd90..40972d55c6 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -78,6 +78,7 @@ #include "openair3/SECU/secu_defs.h" #include "rrc_gNB_NGAP.h" +#include "rrc_gNB_du.h" #include "rrc_gNB_GTPV1U.h" @@ -105,10 +106,20 @@ extern RAN_CONTEXT_t RC; -static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn); +static inline uint64_t bitStr_to_uint64(const BIT_STRING_t *asn); mui_t rrc_gNB_mui = 0; +// the assoc_id might be 0 (if the DU goes offline). Below helper macro to +// print an error and return from the function in that case +#define RETURN_IF_INVALID_ASSOC_ID(ue_data) \ + { \ + if (ue_data.du_assoc_id == 0) { \ + LOG_E(NR_RRC, "cannot send data: invalid assoc_id 0, DU offline\n"); \ + return; \ + } \ + } + ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -188,6 +199,7 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list) typedef struct deliver_dl_rrc_message_data_s { const gNB_RRC_INST *rrc; f1ap_dl_rrc_message_t *dl_rrc; + sctp_assoc_t assoc_id; } deliver_dl_rrc_message_data_t; static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { @@ -196,7 +208,7 @@ static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, in data->dl_rrc->rrc_container = (uint8_t *)buf; data->dl_rrc->rrc_container_length = size; DevAssert(data->dl_rrc->srb_id == srb_id); - data->rrc->mac_rrc.dl_rrc_message_transfer(data->dl_rrc); + data->rrc->mac_rrc.dl_rrc_message_transfer(data->assoc_id, data->dl_rrc); } @@ -204,8 +216,9 @@ void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RR { DevAssert(size > 0); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id}; - deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id }; nr_pdcp_data_req_srb(ue_p->rrc_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } @@ -214,11 +227,6 @@ static int get_dl_band(const f1ap_served_cell_info_t *cell_info) return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.freqinfo.band : cell_info->fdd.dl_freqinfo.band; } -static int get_ul_band(const f1ap_served_cell_info_t *cell_info) -{ - return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.freqinfo.band : cell_info->fdd.ul_freqinfo.band; -} - static int get_ssb_scs(const f1ap_served_cell_info_t *cell_info) { return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs; @@ -337,6 +345,7 @@ void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *c uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); RB_INIT(&rrc->cuups); + RB_INIT(&rrc->dus); rrc->configuration = *configuration; /// System Information INIT init_NR_SI(rrc); @@ -456,6 +465,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, freeSRBlist(SRBs); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -463,7 +473,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, .rrc_container_length = size, .srb_id = CCCH }; - rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(ue_data.du_assoc_id, &dl_rrc); } static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) @@ -485,6 +495,7 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context LOG_I(NR_RRC, " [RAPROC] ue %04x Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", ue_p->rnti, size); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -494,7 +505,7 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context .execute_duplication = 1, .RAT_frequency_priority_information.en_dc = 0 }; - rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(ue_data.du_assoc_id, &dl_rrc); } //----------------------------------------------------------------------------- @@ -528,9 +539,6 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_p->xids[xid] = RRC_DEFAULT_RECONF; - const nr_rrc_du_container_t *du = rrc->du; - DevAssert(du != NULL); - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); /* Add all NAS PDUs to the list */ @@ -555,7 +563,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co dedicatedNAS_MessageList = NULL; } - AssertFatal(du->setup_req->num_cells_available == 1, "cannot handle more than one cell, but have %d\n", du->setup_req->num_cells_available); + const nr_rrc_du_container_t *du = get_du_for_ue(rrc, ue_p->rrc_ue_id); + DevAssert(du != NULL); f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; int scs = get_ssb_scs(cell_info); int band = get_dl_band(cell_info); @@ -1044,12 +1053,13 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context nr_pdcp_reestablishment(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); uint32_t old_gNB_DU_ue_id = old_rnti; f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = DCCH, .old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; - deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id}; nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } @@ -1157,211 +1167,153 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP return 0; } -/*------------------------------------------------------------------------------*/ -static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) +static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id, const NR_RRCSetupRequest_IEs_t *rrcSetupRequest, const f1ap_initial_ul_rrc_message_t *msg) { - asn_dec_rval_t dec_rval; - NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; - NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; - NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; - rnti_t rnti = msg->crnti; - - /* look up corresponding DU. For the moment, there is only one */ - const nr_rrc_du_container_t *du = gnb_rrc_inst->du; - AssertFatal(du != NULL, "received CCCH message, but no corresponding DU found\n"); - - LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, msg->rrc_container_length); - dec_rval = - uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **)&ul_ccch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0); - - if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { - LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); - return -1; - } - - if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { - switch (ul_ccch_msg->message.choice.c1->present) { - case NR_UL_CCCH_MessageType__c1_PR_NOTHING: - /* TODO */ - LOG_I(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message\n"); - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: - LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti); - { - rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; - rrc_gNB_ue_context_t *ue_context_p = NULL; - if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { - /* randomValue BIT STRING (SIZE (39)) */ - if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value - LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); - ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - return -1; - } - uint64_t random_value = 0; - memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - - /* if there is already a registered UE (with another RNTI) with this random_value, - * the current one must be removed from MAC/PHY (zombie UE) - */ - if ((ue_context_p = rrc_gNB_ue_context_random_exist(gnb_rrc_inst, random_value))) { - LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", rnti); - AssertFatal(false, "not implemented\n"); - } - - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { - /* TODO */ - /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ - /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ - if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - return -1; - } - - uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); - - // memcpy(((uint8_t *) & random_value) + 3, - // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, - // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - - if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(gnb_rrc_inst, s_tmsi_part1))) { - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, rnti); - AssertFatal(false, "not implemented\n"); - - /* replace rnti in the context */ - UE->rnti = rnti; - } else { - LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); - - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1, msg->gNB_DU_ue_id); - AssertFatal(ue_context_p != NULL, "out of memory\n"); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE->Initialue_identity_5g_s_TMSI.presence = true; - UE->ng_5G_S_TMSI_Part1 = s_tmsi_part1; - } - } else { - /* TODO */ - uint64_t random_value = 0; - memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", rnti); - rrc_gNB_generate_RRCReject(module_id, ue_context_p); - break; - } - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE = &ue_context_p->ue_context; - UE->establishment_cause = rrcSetupRequest->establishmentCause; - UE->Srb[1].Active = 1; - rrc_gNB_generate_RRCSetup(module_id, - rnti, - ue_context_p, - msg->du2cu_rrc_container, - msg->du2cu_rrc_container_length); - } - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: - LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { - LOG_DUMPMSG(NR_RRC, - DEBUG_RRC, - (char *)(msg->rrc_container), - msg->rrc_container_length, - "[MSG] RRC Reestablishment Request\n"); - rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest; - const NR_ReestablishmentCause_t cause = rrcReestablishmentRequest.reestablishmentCause; - const long physCellId = rrcReestablishmentRequest.ue_Identity.physCellId; - LOG_I(NR_RRC, - "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n", - rnti, - physCellId, - cause == NR_ReestablishmentCause_otherFailure - ? "Other Failure" - : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); - - AssertFatal(du->setup_req->num_cells_available == 1, "cannot handle more than one cell\n"); - const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; - if (physCellId != cell_info->nr_pci) { - /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ - LOG_E(NR_RRC, - " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n", - physCellId, - cell_info->nr_pci); - /* 38.401 8.7: "If the UE accessed from a gNB-DU other than the - * original one, the gNB-CU should trigger the UE Context Setup - * procedure" we did not implement this yet; TBD for Multi-DU */ - AssertFatal(false, "not implemented\n"); - break; - } - - for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { - LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); - } - - rnti_t old_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; - // TODO: we need to check within a specific DU! - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, old_rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - /* in case we need to do RRC Setup, give the UE a new random identity */ - uint64_t random_value; - fill_random(&random_value, sizeof(random_value)); - random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ - if (ue_context_p == NULL) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - ue_context_p->ue_context.Srb[1].Active = 1; - rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); - break; - } - - // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values - if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { - /* c_RNTI range error should not happen */ - LOG_E(NR_RRC, - "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", - rrcReestablishmentRequest.ue_Identity.c_RNTI); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - ue_context_p->ue_context.Srb[1].Active = 1; - rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); - break; - } - - /* TODO: start timer in ITTI and drop UE if it does not come back */ - - // update with new RNTI, and update secondary UE association - UE->rnti = rnti; - cu_remove_f1_ue_data(UE->rrc_ue_id); - f1_ue_data_t ue_data = {.secondary_ue = rnti}; - cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); - - UE->reestablishment_cause = cause; - LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); - - rrc_gNB_generate_RRCReestablishment(ue_context_p, - msg->du2cu_rrc_container, - old_rnti, - du); - } break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: - LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", rnti); - /* TODO */ - break; - - default: - LOG_E(NR_RRC, "UE %04x Unknown message\n", rnti); - break; + rrc_gNB_ue_context_t *ue_context_p = NULL; + if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { + /* randomValue BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value + LOG_E(NR_RRC, + "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); + return; } + uint64_t random_value = 0; + memcpy(((uint8_t *)&random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); + + /* if there is already a registered UE (with another RNTI) with this random_value, + * the current one must be removed from MAC/PHY (zombie UE) + */ + if ((ue_context_p = rrc_gNB_ue_context_random_exist(rrc, random_value))) { + LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", msg->crnti); + AssertFatal(false, "not implemented\n"); + } + + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { + /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ + /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { + LOG_E(NR_RRC, + "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + return; + } + + uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); + + // memcpy(((uint8_t *) & random_value) + 3, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + + if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(rrc, s_tmsi_part1))) { + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, msg->crnti); + AssertFatal(false, "not implemented\n"); + + /* replace rnti in the context */ + UE->rnti = msg->crnti; + } else { + LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", msg->crnti, s_tmsi_part1); + + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, s_tmsi_part1, msg->gNB_DU_ue_id); + AssertFatal(ue_context_p != NULL, "out of memory\n"); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->Initialue_identity_5g_s_TMSI.presence = true; + UE->ng_5G_S_TMSI_Part1 = s_tmsi_part1; + } + } else { + uint64_t random_value = 0; + memcpy(((uint8_t *)&random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); + + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", msg->crnti); + rrc_gNB_generate_RRCReject(0, ue_context_p); + return; } - ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - return 0; + + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE = &ue_context_p->ue_context; + UE->establishment_cause = rrcSetupRequest->establishmentCause; + UE->Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); +} + +static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id, const NR_RRCReestablishmentRequest_IEs_t *req, const f1ap_initial_ul_rrc_message_t *msg) +{ + const NR_ReestablishmentCause_t cause = req->reestablishmentCause; + const long physCellId = req->ue_Identity.physCellId; + LOG_I(NR_RRC, + "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n", + msg->crnti, + physCellId, + cause == NR_ReestablishmentCause_otherFailure + ? "Other Failure" + : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); + + const nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id); + if (du == NULL) { + LOG_E(RRC, "received CCCH message, but no corresponding DU found\n"); + return; + } + const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; + if (physCellId != cell_info->nr_pci) { + /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ + LOG_E(NR_RRC, + " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC " + "establishment\n", + physCellId, + cell_info->nr_pci); + /* 38.401 8.7: "If the UE accessed from a gNB-DU other than the + * original one, the gNB-CU should trigger the UE Context Setup + * procedure" we did not implement this yet; TBD for Multi-DU */ + AssertFatal(false, "not implemented\n"); + return; + } + + rnti_t old_rnti = req->ue_Identity.c_RNTI; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, assoc_id, old_rnti); + /* in case we need to do RRC Setup, give the UE a new random identity */ + uint64_t random_value; + fill_random(&random_value, sizeof(random_value)); + random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ + if (ue_context_p == NULL) { + LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); + return; + } + + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values + if (req->ue_Identity.c_RNTI < 0x1 || req->ue_Identity.c_RNTI > 0xffef) { + /* c_RNTI range error should not happen */ + LOG_E(NR_RRC, + "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", + req->ue_Identity.c_RNTI); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); + return; + } + + /* TODO: start timer in ITTI and drop UE if it does not come back */ + + // update with new RNTI, and update secondary UE association + UE->rnti = msg->crnti; + cu_remove_f1_ue_data(UE->rrc_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id, .du_assoc_id = assoc_id}; + cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); + + UE->reestablishment_cause = cause; + LOG_D(NR_RRC, "Accept req-> UE physCellId %ld cause %ld\n", physCellId, cause); + + rrc_gNB_generate_RRCReestablishment(ue_context_p, msg->du2cu_rrc_container, old_rnti, du); } /*! \fn uint64_t bitStr_to_uint64(BIT_STRING_t *) @@ -1369,7 +1321,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r *\param[in] pointer to the BIT_STRING_t object. *\return the extracted value. */ -static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn) { +static inline uint64_t bitStr_to_uint64(const BIT_STRING_t *asn) { uint64_t result = 0; int index; int shift; @@ -1636,6 +1588,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ gNB_RRC_INST *rrc = RC.nrrrc[0]; f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -1646,7 +1599,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ .servCellId = 0, /* TODO: correct value? */ .ReconfigComplOutcome = successful_reconfig ? RRCreconf_success : RRCreconf_failure, }; - rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } //----------------------------------------------------------------------------- int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, @@ -1795,155 +1748,60 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, return 0; } -static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell_info_t *info) +void rrc_gNB_process_initial_ul_rrc_message(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { - const gNB_RrcConfigurationReq *conf = &rrc->configuration; - return conf->num_plmn == 1 // F1 supports only one - && conf->mcc[0] == info->plmn.mcc - && conf->mnc[0] == info->plmn.mnc - && rrc->nr_cellid == info->nr_cellid; -} + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); -static void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) -{ gNB_RRC_INST *rrc = RC.nrrrc[0]; - DevAssert(rrc); - - LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); - - // check: - // - it is the first DU - // - it is one cell - // - PLMN and Cell ID matches - // else reject - f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; - if (rrc->du != NULL) { - const f1ap_setup_req_t *other = rrc->du->setup_req; - LOG_E(NR_RRC, "can only handle one DU, but already serving DU %ld (%s)\n", other->gNB_DU_id, other->gNB_DU_name); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - if (req->num_cells_available != 1) { - LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - f1ap_served_cell_info_t *cell_info = &req->cell[0].info; - if (!rrc_gNB_plmn_matches(rrc, cell_info)) { - LOG_E(NR_RRC, - "PLMN mismatch: CU %d%d cellID %ld, DU %d%d cellID %ld\n", - rrc->configuration.mcc[0], - rrc->configuration.mnc[0], - rrc->nr_cellid, - cell_info->plmn.mcc, - cell_info->plmn.mnc, - cell_info->nr_cellid); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it - const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; - if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) { - LOG_E(NR_RRC, "no system information provided by DU, rejecting\n"); - rrc->mac_rrc.f1_setup_failure(&fail); + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", ul_rrc->crnti, ul_rrc->rrc_container_length); + NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_UL_CCCH_Message, + (void **)&ul_ccch_msg, + ul_rrc->rrc_container, + ul_rrc->rrc_container_length, + 0, + 0); + if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { + LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); return; } - /* do we need the MIB? for the moment, just check it is valid, then drop it */ - NR_BCCH_BCH_Message_t *mib = NULL; - asn_dec_rval_t dec_rval = - uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length); - if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib - || mib->message.choice.messageClassExtension == NULL) { - LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); - rrc->mac_rrc.f1_setup_failure(&fail); - ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib); - return; - } + if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { + switch (ul_ccch_msg->message.choice.c1->present) { + case NR_UL_CCCH_MessageType__c1_PR_NOTHING: + LOG_W(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message, ignoring message\n"); + break; - NR_SIB1_t *sib1 = NULL; - if (sys_info->sib1) { - dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length); - if (dec_rval.code != RC_OK) { - LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); - rrc->mac_rrc.f1_setup_failure(&fail); - ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1); - return; + case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: + LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", ul_rrc->crnti); + rrc_handle_RRCSetupRequest(rrc, assoc_id, &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest, ul_rrc); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: + LOG_E(NR_RRC, "Received rrcResumeRequest message, but handling is not implemented\n"); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { + LOG_D(NR_RRC, "Received RRCReestablishmentRequest on UL-CCCH-Message (UE RNTI %04x)\n", ul_rrc->crnti); + rrc_handle_RRCReestablishmentRequest( + rrc, + assoc_id, + &ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest, + ul_rrc); + } break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: + LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", ul_rrc->crnti); + /* TODO */ + break; + + default: + LOG_E(NR_RRC, "UE %04x Unknown message\n", ul_rrc->crnti); + break; } - if (LOG_DEBUGFLAG(DEBUG_ASN1)) - xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1); } - - LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name); - - // we accept the DU - rrc->du = calloc(1, sizeof(*rrc->du)); - AssertFatal(rrc->du != NULL, "out of memory\n"); - rrc->du->assoc_id = assoc_id; - - /* ITTI will free the setup request message via free(). So the memory - * "inside" of the message will remain, but the "outside" container no, so - * allocate memory and copy it in */ - rrc->du->setup_req = malloc(sizeof(*rrc->du->setup_req)); - AssertFatal(rrc->du->setup_req != NULL, "out of memory\n"); - *rrc->du->setup_req = *req; - rrc->du->mib = mib->message.choice.mib; - mib->message.choice.mib = NULL; - ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib); - rrc->du->sib1 = sib1; - - served_cells_to_activate_t cell = { - .plmn = cell_info->plmn, - .nr_cellid = cell_info->nr_cellid, - .nrpci = cell_info->nr_pci, - .num_SI = 0, - }; - f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell}; - if (rrc->node_name != NULL) - resp.gNB_CU_name = strdup(rrc->node_name); - rrc->mac_rrc.f1_setup_response(&resp); - - /* - MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE); - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0]; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0]; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0]; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci; - int num_SI = 0; - - if (rrc->carrier.SIB23) { - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23; - num_SI++; - } - - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1; - // send - itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2); - */ -} - -void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t *ul_rrc) -{ - // first get RRC instance (note, no the ITTI instance) - module_id_t i = 0; - for (i=0; i < RC.nb_nr_inst; i++) { - gNB_RRC_INST *rrc = RC.nrrrc[i]; - if (rrc->nr_cellid == ul_rrc->nr_cellid) - break; - } - //AssertFatal(i != RC.nb_nr_inst, "Cell_id not found\n"); - // TODO REMOVE_DU_RRC in monolithic mode, the MAC does not have the - // nr_cellid. Thus, the above check would fail. For the time being, just put - // a warning, as we handle one DU only anyway - if (i == RC.nb_nr_inst) { - i = 0; - LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); - } - nr_rrc_gNB_decode_ccch(i, ul_rrc); + ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); if (ul_rrc->rrc_container) free(ul_rrc->rrc_container); @@ -2111,7 +1969,7 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p) .cause = F1AP_CAUSE_RADIO_NETWORK, .cause_value = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_cu_ue_f1ap_id, }; - rrc->mac_rrc.ue_context_modification_refuse(&refuse); + rrc->mac_rrc.ue_context_modification_refuse(msg_p->ittiMsgHeader.originInstance, &refuse); return; } @@ -2136,7 +1994,7 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p) .cause = F1AP_CAUSE_PROTOCOL, .cause_value = F1AP_CauseProtocol_transfer_syntax_error, }; - rrc->mac_rrc.ue_context_modification_refuse(&refuse); + rrc->mac_rrc.ue_context_modification_refuse(msg_p->ittiMsgHeader.originInstance, &refuse); return; } @@ -2164,158 +2022,6 @@ unsigned int mask_flip(unsigned int x) { return((((x>>8) + (x<<8))&0xffff)>>6); } -static unsigned int get_dl_bw_mask(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_band = get_dl_band(cell_info); - int common_scs = get_ssb_scs(cell_info); - for (int i=0;irf_Parameters.supportedBandListNR.list.count;i++) { - NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; - if (bandNRinfo->bandNR == common_band) { - if (common_band < 257) { // FR1 - switch (common_scs) { - case NR_SubcarrierSpacing_kHz15 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr1 && - bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz30 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr1 && - bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr1 && - bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz->buf)); - break; - } - } - else { - switch (common_scs) { - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr2 && - bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz120 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr2 && - bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz->buf)); - break; - } - } - } - } - return(0); -} - -static unsigned int get_ul_bw_mask(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_band = get_ul_band(cell_info); - int common_scs = get_ssb_scs(cell_info); - for (int i=0;irf_Parameters.supportedBandListNR.list.count;i++) { - NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; - if (bandNRinfo->bandNR == common_band) { - if (common_band < 257) { // FR1 - switch (common_scs) { - case NR_SubcarrierSpacing_kHz15 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr1 && - bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz30 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr1 && - bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr1 && - bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz->buf)); - break; - } - } - else { - switch (common_scs) { - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr2 && - bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz120 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr2 && - bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz->buf)); - break; - } - } - } - } - return(0); -} - -static int get_ul_mimo_layersCB(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_scs = get_ssb_scs(cell_info); - - // check featureSet - NR_FeatureSets_t *fs=cap->featureSets; - if (fs) { - // go through UL feature sets and look for one with current SCS - for (int i=0;ifeatureSetsUplinkPerCC->list.count;i++) { - if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && - fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH && - fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) - return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH); - } - } - return(1); -} - -static int get_ul_mimo_layers(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_scs = get_ssb_scs(cell_info); - - // check featureSet - NR_FeatureSets_t *fs=cap->featureSets; - if (fs) { - // go through UL feature sets and look for one with current SCS - for (int i=0;ifeatureSetsUplinkPerCC->list.count;i++) { - if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && - fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH) - return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH); - } - } - return(1); -} - -static int get_dl_mimo_layers(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_scs = get_ssb_scs(cell_info); - - // check featureSet - NR_FeatureSets_t *fs=cap->featureSets; - if (fs) { - // go through UL feature sets and look for one with current SCS - for (int i=0;ifeatureSetsDownlinkPerCC->list.count;i++) { - if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && - fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH) - return(2<<*fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH); - } - } - return(1); -} - void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -2379,6 +2085,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp } f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2393,7 +2100,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp .drbs_to_be_setup = drbs, .cu_to_du_rrc_information = cu2du_p, }; - rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp) @@ -2421,21 +2128,6 @@ void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cp LOG_I(RRC, "UE %d: received bearer release complete\n", cplt->gNB_cu_cp_ue_id); } -static void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) -{ - AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); - AssertFatal(rrc->du->assoc_id == assoc_id, - "previously connected DU (%d) does not match DU for which connection has been lost (%d)\n", - rrc->du->assoc_id, - assoc_id); - (void) lc; // unused for the moment - ASN_STRUCT_FREE(asn_DEF_NR_MIB, rrc->du->mib); - ASN_STRUCT_FREE(asn_DEF_NR_SIB1, rrc->du->sib1); - free(rrc->du); - rrc->du = NULL; - LOG_I(RRC, "dropping DU with assoc_id %d (UE connections remain, if any)\n", assoc_id); -} - static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults) { DevAssert(measresults->measResultServingMOList.list.count >= 1); @@ -2524,26 +2216,23 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) fprintf(f, " PDU session %d ID %d status %s\n", nb_pdu, pdu->param.pdusession_id, get_pdusession_status_text(pdu->status)); } - /* currently, we support only one DU. If we support multiple, need to - * search for the DU corresponding to this UE here */ - const nr_rrc_du_container_t *du = rrc->du; - if (du != NULL && ue_ctxt->UE_Capability_nr) { - AssertFatal(du->setup_req->num_cells_available == 1, "only one cell supported at the moment\n"); - const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; - fprintf(f, - " UE cap: BW DL %x. BW UL %x, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n", - get_dl_bw_mask(cell_info, ue_ctxt->UE_Capability_nr), - get_ul_bw_mask(cell_info, ue_ctxt->UE_Capability_nr), - get_dl_mimo_layers(cell_info, ue_ctxt->UE_Capability_nr), - get_ul_mimo_layersCB(cell_info, ue_ctxt->UE_Capability_nr), - get_ul_mimo_layers(cell_info, ue_ctxt->UE_Capability_nr)); - } + fprintf(f, " associated DU: "); + if (ue_data.du_assoc_id == -1) + fprintf(f, " (local/integrated CU-DU)"); + else if (ue_data.du_assoc_id == 0) + fprintf(f, " DU offline/unavailable"); + else + fprintf(f, " DU assoc ID %d", ue_data.du_assoc_id); + fprintf(f, "\n"); if (ue_ctxt->measResults) print_rrc_meas(f, ue_ctxt->measResults); ++i; } + fprintf(f, "\n"); + dump_du_info(rrc, f); + fclose(f); } @@ -2587,7 +2276,7 @@ void *rrc_gnb_task(void *args_p) { case F1AP_INITIAL_UL_RRC_MESSAGE: AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type), "should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n"); - rrc_gNB_process_initial_ul_rrc_message(&F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); + rrc_gNB_process_initial_ul_rrc_message(msg_p->ittiMsgHeader.originInstance, &F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); break; /* Messages from PDCP */ @@ -2723,6 +2412,7 @@ void *rrc_gnb_task(void *args_p) { typedef struct deliver_ue_ctxt_setup_data_t { gNB_RRC_INST *rrc; f1ap_ue_context_setup_t *setup_req; + sctp_assoc_t assoc_id; } deliver_ue_ctxt_setup_data_t; static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { @@ -2730,7 +2420,7 @@ static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, deliver_ue_ctxt_setup_data_t *data = deliver_pdu_data; data->setup_req->rrc_container = (uint8_t*)buf; data->setup_req->rrc_container_length = size; - data->rrc->mac_rrc.ue_context_setup_request(data->setup_req); + data->rrc->mac_rrc.ue_context_setup_request(data->assoc_id, data->setup_req); } //----------------------------------------------------------------------------- @@ -2762,11 +2452,9 @@ rrc_gNB_generate_SecurityModeCommand( cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len; } - const nr_rrc_du_container_t *du = rrc->du; - DevAssert(du != NULL); - /* the callback will fill the UE context setup request and forward it */ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_setup_t ue_context_setup_req = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2779,7 +2467,7 @@ rrc_gNB_generate_SecurityModeCommand( .drbs_to_be_setup = 0, /* no new DRBs */ .cu_to_du_rrc_information = cu2du_p, }; - deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req}; + deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req, .assoc_id = ue_data.du_assoc_id }; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, &data); } @@ -2813,6 +2501,7 @@ rrc_gNB_generate_UECapabilityEnquiry( typedef struct deliver_ue_ctxt_release_data_t { gNB_RRC_INST *rrc; f1ap_ue_context_release_cmd_t *release_cmd; + sctp_assoc_t assoc_id; } deliver_ue_ctxt_release_data_t; static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { @@ -2820,7 +2509,7 @@ static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_i deliver_ue_ctxt_release_data_t *data = deliver_pdu_data; data->release_cmd->rrc_container = (uint8_t*) buf; data->release_cmd->rrc_container_length = size; - data->rrc->mac_rrc.ue_context_release_command(data->release_cmd); + data->rrc->mac_rrc.ue_context_release_command(data->assoc_id, data->release_cmd); } //----------------------------------------------------------------------------- @@ -2846,6 +2535,7 @@ rrc_gNB_generate_RRCRelease( gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_release_cmd_t ue_context_release_cmd = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2853,7 +2543,7 @@ rrc_gNB_generate_RRCRelease( .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release .srb_id = DCCH, }; - deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd}; + deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = ue_data.du_assoc_id}; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); @@ -2870,7 +2560,7 @@ void rrc_gNB_trigger_new_bearer(int rnti) { /* get RRC and UE */ gNB_RRC_INST *rrc = RC.nrrrc[0]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti); if (ue_context_p == NULL) { LOG_E(RRC, "unknown UE RNTI %04x\n", rnti); return; @@ -2952,7 +2642,7 @@ void rrc_gNB_trigger_release_bearer(int rnti) { /* get RRC and UE */ gNB_RRC_INST *rrc = RC.nrrrc[0]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti); if (ue_context_p == NULL) { LOG_E(RRC, "unknown UE RNTI %04x\n", rnti); return; @@ -2990,6 +2680,7 @@ void rrc_gNB_trigger_release_bearer(int rnti) f1ap_drb_to_be_released_t drbs_to_be_released[1] = {{.rb_id = drb_id}}; f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = ue->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -3005,10 +2696,13 @@ void rrc_gNB_trigger_release_bearer(int rnti) .drbs_to_be_released_length = 1, .drbs_to_be_released = drbs_to_be_released, }; - rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } -int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){ +int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx) +{ + instance_t instance = 0; + uint8_t CC_id = 0; const unsigned int Ttab[4] = {32,64,128,256}; uint8_t Tc; uint8_t Tue; @@ -3019,9 +2713,6 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst uint32_t T; /* DRX cycle */ uint32_t length; uint8_t buffer[RRC_BUF_SIZE]; - const nr_rrc_du_container_t *du = RC.nrrrc[0]->du; - DevAssert(du != NULL); - struct NR_SIB1 *sib1 = du->sib1; /* get default DRX cycle from configuration */ Tc = sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle; @@ -3129,6 +2820,7 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst return -1; } // TODO, send message to pdcp + (void) assoc_id; return 0; } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index d60586e2c9..57bb9b1bdf 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1355,6 +1355,7 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance) && RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc && RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) { for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + AssertFatal(false, "to be implemented properly\n"); if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) { MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND); F1AP_PAGING_IND(m).plmn.mcc = RC.nrrrc[j]->configuration.mcc[0]; @@ -1367,7 +1368,7 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance) LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx); itti_send_msg_to_task(TASK_CU_F1, instance, m); } else { - rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); + //rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); } // end of nodetype check } // end of cc loop } // end of mcc mnc check diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 8a8c0bdd2e..db082c1965 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -87,7 +87,19 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_i return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); } -rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) +rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP) +{ + rrc_gNB_ue_context_t *ue_context_p; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_context_p->ue_context.rrc_ue_id); + if (ue_data.du_assoc_id == assoc_id && ue_context_p->ue_context.rnti == rntiP) + return ue_context_p; + } + LOG_W(NR_RRC, "search by RNTI %04x and assoc_id %d: no UE found\n", rntiP, assoc_id); + return NULL; +} + +rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) { rrc_gNB_ue_context_t *ue_context_p; RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) @@ -157,7 +169,8 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, rnti not found in collection -rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, +rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id, + rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP, uint32_t du_ue_id) @@ -170,7 +183,7 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_UE_t *ue = &ue_context_p->ue_context; ue->rnti = rnti; ue->random_ue_identity = ue_identityP; - f1_ue_data_t ue_data = {.secondary_ue = du_ue_id}; + f1_ue_data_t ue_data = {.secondary_ue = du_ue_id, .du_assoc_id = assoc_id}; AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id), "UE F1 Context for ID %d already exists, logic bug\n", ue->rrc_ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 3ec0852af6..af40b33981 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -41,7 +41,8 @@ RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance_pP); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue); -rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); +rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP); +rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP); @@ -50,7 +51,8 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); -rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, +rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(sctp_assoc_t assoc_id, + rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP, uint32_t du_ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c new file mode 100644 index 0000000000..25763c7ae7 --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -0,0 +1,278 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "rrc_gNB_du.h" +#include "common/ran_context.h" +#include "nr_rrc_defs.h" +#include "rrc_gNB_UE_context.h" +#include "openair2/F1AP/f1ap_common.h" +#include "openair2/F1AP/f1ap_ids.h" +#include "executables/softmodem-common.h" + + +static int du_compare(const nr_rrc_du_container_t *a, const nr_rrc_du_container_t *b) +{ + if (a->assoc_id > b->assoc_id) + return 1; + if (a->assoc_id == b->assoc_id) + return 0; + return -1; /* a->assoc_id < b->assoc_id */ +} + +/* Tree management functions */ +RB_GENERATE/*_STATIC*/(rrc_du_tree, nr_rrc_du_container_t, entries, du_compare); + +static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell_info_t *info) +{ + const gNB_RrcConfigurationReq *conf = &rrc->configuration; + return conf->num_plmn == 1 // F1 supports only one + && conf->mcc[0] == info->plmn.mcc + && conf->mnc[0] == info->plmn.mnc; +} + +void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) +{ + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); + gNB_RRC_INST *rrc = RC.nrrrc[0]; + DevAssert(rrc); + + LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); + + // check: + // - it is one cell + // - PLMN and Cell ID matches + // - no previous DU with the same ID + // else reject + if (req->num_cells_available != 1) { + LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + f1ap_served_cell_info_t *cell_info = &req->cell[0].info; + if (!rrc_gNB_plmn_matches(rrc, cell_info)) { + LOG_E(NR_RRC, + "PLMN mismatch: CU %d%d, DU %d%d\n", + rrc->configuration.mcc[0], + rrc->configuration.mnc[0], + cell_info->plmn.mcc, + cell_info->plmn.mnc); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + nr_rrc_du_container_t *it = NULL; + RB_FOREACH(it, rrc_du_tree, &rrc->dus) { + if (it->setup_req->gNB_DU_id == req->gNB_DU_id) { + LOG_E(NR_RRC, + "gNB-DU ID: existing DU %s on assoc_id %d already has ID %ld, rejecting requesting gNB-DU\n", + it->setup_req->gNB_DU_name, + it->assoc_id, + it->setup_req->gNB_DU_id); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + // note: we assume that each DU contains only one cell; otherwise, we would + // need to check every cell in the requesting DU to any existing cell. + const f1ap_served_cell_info_t *exist_info = &it->setup_req->cell[0].info; + const f1ap_served_cell_info_t *new_info = &req->cell[0].info; + if (exist_info->nr_cellid == new_info->nr_cellid || exist_info->nr_pci == new_info->nr_pci) { + LOG_E(NR_RRC, + "existing DU %s on assoc_id %d already has cellID %ld/physCellId %d, rejecting requesting gNB-DU with cellID %ld/physCellId %d\n", + it->setup_req->gNB_DU_name, + it->assoc_id, + exist_info->nr_cellid, + exist_info->nr_pci, + new_info->nr_cellid, + new_info->nr_pci); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + } + + // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it + const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; + if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) { + LOG_E(NR_RRC, "no system information provided by DU, rejecting\n"); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + + /* do we need the MIB? for the moment, just check it is valid, then drop it */ + NR_BCCH_BCH_Message_t *mib = NULL; + asn_dec_rval_t dec_rval = + uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length); + if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib + || mib->message.choice.messageClassExtension == NULL) { + LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib); + return; + } + + NR_SIB1_t *sib1 = NULL; + if (sys_info->sib1) { + dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length); + if (dec_rval.code != RC_OK) { + LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1); + return; + } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1); + } + + LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name); + + // we accept the DU + nr_rrc_du_container_t *du = calloc(1, sizeof(*du)); + AssertFatal(du != NULL, "out of memory\n"); + du->assoc_id = assoc_id; + + /* ITTI will free the setup request message via free(). So the memory + * "inside" of the message will remain, but the "outside" container no, so + * allocate memory and copy it in */ + du->setup_req = malloc(sizeof(*du->setup_req)); + AssertFatal(du->setup_req != NULL, "out of memory\n"); + *du->setup_req = *req; + du->mib = mib->message.choice.mib; + mib->message.choice.mib = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib); + du->sib1 = sib1; + RB_INSERT(rrc_du_tree, &rrc->dus, du); + rrc->num_dus++; + + served_cells_to_activate_t cell = { + .plmn = cell_info->plmn, + .nr_cellid = cell_info->nr_cellid, + .nrpci = cell_info->nr_pci, + .num_SI = 0, + }; + f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell}; + if (rrc->node_name != NULL) + resp.gNB_CU_name = strdup(rrc->node_name); + rrc->mac_rrc.f1_setup_response(assoc_id, &resp); + + /* + MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE); + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0]; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0]; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0]; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci; + int num_SI = 0; + + if (rrc->carrier.SIB23) { + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23; + num_SI++; + } + + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1; + // send + itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2); + */ +} + +static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) +{ + int count = 0; + rrc_gNB_ue_context_t *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) { + uint32_t ue_id = ue_context_p->ue_context.rrc_ue_id; + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); + if (ue_data.du_assoc_id == assoc_id) { + /* this UE belongs to the DU that disconnected, set du_assoc_id to 0, + * meaning DU is offline */ + cu_remove_f1_ue_data(ue_id); + f1_ue_data_t new = {.secondary_ue = ue_data.secondary_ue, .du_assoc_id = 0 }; + cu_add_f1_ue_data(ue_id, &new); + count++; + } + } + return count; +} + +void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) +{ + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); + (void) lc; // unused for the moment + + nr_rrc_du_container_t e = {.assoc_id = assoc_id}; + nr_rrc_du_container_t *du = RB_FIND(rrc_du_tree, &rrc->dus, &e); + if (du == NULL) { + LOG_W(NR_RRC, "no DU connected or not found for assoc_id %d: F1 Setup Failed?\n", assoc_id); + return; + } + + f1ap_setup_req_t *req = du->setup_req; + LOG_I(RRC, "releasing DU ID %ld (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); + ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib); + ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1); + /* TODO: free setup request */ + nr_rrc_du_container_t *removed = RB_REMOVE(rrc_du_tree, &rrc->dus, du); + DevAssert(removed != NULL); + rrc->num_dus--; + + int num = invalidate_du_connections(rrc, assoc_id); + if (num > 0) { + LOG_I(NR_RRC, "%d UEs lost through DU disconnect\n", num); + } +} + +nr_rrc_du_container_t *get_du_for_ue(gNB_RRC_INST *rrc, uint32_t ue_id) +{ + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); + return get_du_by_assoc_id(rrc, ue_data.du_assoc_id); +} + +nr_rrc_du_container_t *get_du_by_assoc_id(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) +{ + nr_rrc_du_container_t e = {.assoc_id = assoc_id}; + return RB_FIND(rrc_du_tree, &rrc->dus, &e); +} + +void dump_du_info(const gNB_RRC_INST *rrc, FILE *f) +{ + fprintf(f, "%ld connected DUs \n", rrc->num_dus); + int i = 1; + nr_rrc_du_container_t *du = NULL; + /* cast is necessary to eliminate warning "discards ‘const’ qualifier" */ + RB_FOREACH(du, rrc_du_tree, &((gNB_RRC_INST *)rrc)->dus) { + const f1ap_setup_req_t *sr = du->setup_req; + fprintf(f, "[%d] DU ID %ld (%s) ", i++, sr->gNB_DU_id, sr->gNB_DU_name); + if (du->assoc_id == -1) { + fprintf(f, "integrated DU-CU"); + } else { + fprintf(f, "assoc_id %d", du->assoc_id); + } + const f1ap_served_cell_info_t *info = &sr->cell[0].info; + fprintf(f, ": nrCellID %ld, PCI %d\n", info->nr_cellid, info->nr_pci); + } +} diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h new file mode 100644 index 0000000000..c57faf3802 --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef RRC_GNB_DU_H_ +#define RRC_GNB_DU_H_ + +#include +#include +#include +#include + +struct f1ap_setup_req_s; +struct f1ap_lost_connection_t; +struct gNB_RRC_INST_s; +struct nr_rrc_du_container_t; + +void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id); +void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); + +struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id); +struct nr_rrc_du_container_t *get_du_by_assoc_id(struct gNB_RRC_INST_s *rrc, sctp_assoc_t assoc_id); + +void dump_du_info(const struct gNB_RRC_INST_s *rrc, FILE *f); + +#endif /* RRC_GNB_DU_H_ */ diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index aa39239f88..448de0eb95 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -414,7 +414,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id); - ue_context = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); + ue_context = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti); if (ue_context == NULL) { LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti); return; diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index d542dd4b30..69db8caa4a 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -510,27 +510,6 @@ static int udpServerSocket(openAddr_s addr) { freeaddrinfo(servinfo); // all done with this structure - if (false) { - struct addrinfo hints; - memset(&hints,0,sizeof(hints)); - hints.ai_family=AF_UNSPEC; - hints.ai_socktype=SOCK_DGRAM; - hints.ai_protocol=0; - hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG; - struct addrinfo *res=0; - int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res); - - if (err==0) { - for(p = res; p != NULL; p = p->ai_next) { - if ((err=connect(sockfd, p->ai_addr, p->ai_addrlen))==0) - break; - } - } - - if (err) - LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService); - } - int sendbuff = 1000*1000*10; AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); LOG_D(GTPU,"[%d] Created listener for paquets to: %s:%s, send buffer size: %d\n", sockfd, addr.originHost, addr.originService,sendbuff); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 4628ee54fe..ebeeb25572 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -278,7 +278,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "enb"; - serverport = "4043"; + serverport = 4043; options = ("saviq"); modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index e951754bf0..eaad417c9b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -240,7 +240,7 @@ THREAD_STRUCT = ( #rfsimulator : #{ # serveraddr = "server"; -# serverport = "4043"; +# serverport = 4043; # options = ("chanmod"); # modelname = "AWGN"; #}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf index 3007cb2af8..67fa7726dc 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf @@ -215,7 +215,7 @@ THREAD_STRUCT = ( ); rfsimulator: { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 073a1c5d17..60077f4ab4 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -228,7 +228,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf index 430c2ddd53..97405a073b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf @@ -236,7 +236,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf index cf60b9b764..21d9a1233f 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -228,7 +228,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf index 88bc9429cc..aa0c090395 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf @@ -254,7 +254,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index f9b7bf13fc..f8057be015 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -255,7 +255,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index f5baeba81c..f9646c4aed 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -255,7 +255,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf index bcbbe101ca..ab6c5b7ffb 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf @@ -234,7 +234,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf index 6d6dc4d281..70bab1c6f7 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf @@ -234,7 +234,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf index 32a6c8b65f..1d64c6fedf 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf index 0ad8b6066d..6958213f05 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 3b7fadf3bc..665771288b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf index 60a29c50e4..b40df581d4 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf @@ -239,7 +239,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf index ff29e1f572..0ed70dea8b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf @@ -234,7 +234,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf index b5101c1112..31c32a4d1d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf @@ -232,7 +232,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf index a982ed59cd..7593d64465 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -231,7 +231,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf index aa3e5de456..d448ad8cbc 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf @@ -292,7 +292,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf index 65a2a49d50..21bb04ed25 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf @@ -291,7 +291,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf index 06bb23309e..1e729f7d02 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf @@ -33,7 +33,7 @@ RUs = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs";