diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d06d30c17..948f623f2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -413,6 +413,7 @@ target_link_libraries(x2ap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
set(F1AP_DIR ${OPENAIR2_DIR}/F1AP)
add_library(f1ap
${F1AP_DIR}/f1ap_common.c
+ ${F1AP_DIR}/f1ap_ids.c
${F1AP_DIR}/f1ap_cu_interface_management.c
${F1AP_DIR}/f1ap_cu_paging.c
${F1AP_DIR}/f1ap_cu_rrc_message_transfer.c
@@ -431,7 +432,7 @@ add_library(f1ap
${F1AP_DIR}/f1ap_itti_messaging.c)
target_include_directories(f1ap PUBLIC F1AP_DIR)
target_link_libraries(f1ap PUBLIC asn1_f1ap)
-target_link_libraries(f1ap PRIVATE ngap nr_rrc)
+target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE)
# LPP
##############
diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml
index 121b836769..0296ecfe93 100644
--- a/ci-scripts/xml_files/container_sa_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml
@@ -111,7 +111,7 @@
IdleSleep
Sleep
- 20
+ 10
@@ -168,14 +168,14 @@
Custom_Command
Trigger Reestablishment
ofqot
- echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment'
+ echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
yes
Custom_Command
Verify Reestablishment
ofqot
- echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1'
+ echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
yes
diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml
index a20ea8845e..1f28fce309 100644
--- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml
@@ -39,6 +39,10 @@
110011
110001
150001
+ 160001
+ 100002
+ 160002
+ 150001
110011
110001
150000
@@ -114,7 +118,7 @@
IdleSleep
Sleep
- 20
+ 10
@@ -184,6 +188,21 @@
single-ue
+
+ Custom_Command
+ Trigger Reestablishment (on DU)
+ ofqot
+ echo ci force_reestab | nc -N 192.168.68.195 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
+ yes
+
+
+ Custom_Command
+ Verify Reestablishment (on CU)
+ ofqot
+ echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
+ yes
+
+
Undeploy_Object
Undeploy CU-DU
diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml
index 0d4dd8f27e..d603b3f1ea 100644
--- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml
@@ -105,7 +105,7 @@
IdleSleep
Sleep
- 20
+ 10
@@ -162,14 +162,14 @@
Custom_Command
Trigger Reestablishment
ofqot
- echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment'
+ echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'
yes
Custom_Command
Verify Reestablishment
ofqot
- echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1'
+ echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'
yes
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index 1c4faaf99f..b07bd2b6dd 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --rrc_config_path . --log_config.global_log_options level,nocolor,time
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --log_config.global_log_options level,nocolor,time
NR
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
index 2122f8651c..dfc088fc34 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path . --log_config.global_log_options level,nocolor,time
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --log_config.global_log_options level,nocolor,time
NR
diff --git a/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml
index a23c823019..5ead5b485e 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml
@@ -23,7 +23,7 @@ services:
privileged: true
container_name: rfsim5g-oai-nr-ue
environment:
- USE_ADDITIONAL_OPTIONS: --phy-test --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: --phy-test --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/
diff --git a/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml
index 4875f88eb9..10d57983b8 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml
@@ -23,7 +23,7 @@ services:
privileged: true
container_name: rfsim5g-oai-nr-ue
environment:
- USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/
diff --git a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml
index da3f8eaf31..dc1998dffa 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml
@@ -23,7 +23,7 @@ services:
privileged: true
container_name: rfsim5g-oai-nr-ue
environment:
- USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/
diff --git a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml
index e40dc686d7..2be92cdb38 100644
--- a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml
+++ b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml
@@ -6,7 +6,7 @@ services:
privileged: true
container_name: sa-cu-gnb
environment:
- USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function
+ USE_ADDITIONAL_OPTIONS: --sa --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function
volumes:
- ../../conf_files/gnb-cu.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
networks:
@@ -26,7 +26,7 @@ services:
container_name: sa-du-b200-gnb
environment:
USE_B2XX: 'yes'
- USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
+ USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
volumes:
- ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
- /dev:/dev
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index a9241bf3b3..246c45dcda 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -529,7 +529,7 @@ function main() {
echo_info "Doxygen generation log is located here: $doxygen_log"
echo_info "Generating Doxygen files....please wait"
(
- cmake --build . --target doc
+ $CMAKE --build . --target doc
) >& $doxygen_log
fi
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 22905e1a3b..4f1ea858a4 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -32,7 +32,7 @@ OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g")
OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g")
case "$OS_DISTRO" in
fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
- rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
+ rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake3" ;;
rocky) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
centos) OS_BASEDISTRO="centos"; INSTALLER="yum"; CMAKE="cmake3" ;;
debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
@@ -226,11 +226,11 @@ compilations() {
local verbose=$([ "$VERBOSE_COMPILE" == "1" ] && echo "-v" || echo "")
echo cd $OPENAIR_DIR/cmake_targets/$dir/build
cd $OPENAIR_DIR/cmake_targets/$dir/build
- echo_info "Running \"cmake --build . $verbose --target $targets -- -j$(nproc)\"" $green
+ echo_info "Running \"$CMAKE --build . $verbose --target $targets -- -j$(nproc)\"" $green
echo "Log file for compilation is being written to: $dlog/$logfile"
set +e
{
- cmake --build . $verbose --target $targets -- -j$(nproc)
+ $CMAKE --build . $verbose --target $targets -- -j$(nproc)
ret=$?
} > $dlog/$logfile 2>&1
if [ "$VERBOSE_CI" == "1" ]; then
diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c
index 3f4930d02b..2d7019b00e 100644
--- a/common/utils/telnetsrv/telnetsrv_ci.c
+++ b/common/utils/telnetsrv/telnetsrv_ci.c
@@ -28,15 +28,17 @@
#include
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
-#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
+#include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h"
+#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0)
-static int get_single_ue_rnti(void)
+static int get_single_ue_rnti_mac(void)
{
NR_UE_info_t *ue = NULL;
UE_iterator(RC.nrmac[0]->UE_info.list, it) {
@@ -48,11 +50,6 @@ static int get_single_ue_rnti(void)
if (!ue)
return -1;
- // verify it exists in RRC as well
- rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti);
- if (!rrcue)
- return -1;
-
return ue->rnti;
}
@@ -61,7 +58,7 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
if (buf)
ERROR_MSG_RET("no parameter allowed\n");
- int rnti = get_single_ue_rnti();
+ int rnti = get_single_ue_rnti_mac();
if (rnti < 1)
ERROR_MSG_RET("different number of UEs\n");
@@ -71,23 +68,32 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
{
+ if (!RC.nrrrc)
+ ERROR_MSG_RET("no RRC present, cannot list counts\n");
+ rrc_gNB_ue_context_t *ue = NULL;
int rnti = -1;
if (!buf) {
- rnti = get_single_ue_rnti();
- if (rnti < 1)
- ERROR_MSG_RET("no UE found\n");
+ rrc_gNB_ue_context_t *l = NULL;
+ int n = 0;
+ RB_FOREACH(l, rrc_nr_ue_tree_s, &RC.nrrrc[0]->rrc_ue_head) {
+ if (ue == NULL) ue = l;
+ n++;
+ }
+ if (!ue)
+ ERROR_MSG_RET("could not find any UE in RRC\n");
+ if (n > 1)
+ ERROR_MSG_RET("more than one UE in RRC present\n");
} else {
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);
+ if (!ue)
+ ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n");
}
- rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
- if (!ue)
- ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
-
prnt("UE RNTI %04x reestab %d reconf_after_reestab %d\n",
- rnti,
+ ue->ue_context.rnti,
ue->ue_context.ue_reestablishment_counter,
ue->ue_context.ue_reconfiguration_after_reestablishment_counter);
return 0;
@@ -95,9 +101,11 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
{
+ if (!RC.nrmac)
+ ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n");
int rnti = -1;
if (!buf) {
- rnti = get_single_ue_rnti();
+ rnti = get_single_ue_rnti_mac();
if (rnti < 1)
ERROR_MSG_RET("no UE found\n");
} else {
@@ -106,13 +114,9 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
}
- // verify it exists in RRC as well
- rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
- if (!rrcue)
- ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
+ nr_rlc_test_trigger_reestablishment(rnti);
- nr_rlc_remove_ue(rnti);
- prnt("force-remove UE RNTI %04x from RLC to trigger reestablishment\n", rnti);
+ prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti);
return 0;
}
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
index 66e1152f48..1a78e20134 100644
--- a/common/utils/threadPool/thread-pool.h
+++ b/common/utils/threadPool/thread-pool.h
@@ -26,6 +26,8 @@
#define THREAD_POOL_H
#include
#include
+#include
+#include
#include
#include
#include
@@ -64,7 +66,10 @@ typedef struct notifiedFIFO_elt_s {
oai_cputime_t startProcessingTime;
oai_cputime_t endProcessingTime;
oai_cputime_t returnTime;
- void *msgData;
+ // use alignas(32) to align msgData to 32b
+ // user data behind it will be aligned to 32b as well
+ // important! this needs to be the last member in the struct
+ alignas(32) void *msgData;
} notifiedFIFO_elt_t;
typedef struct notifiedFIFO_s {
@@ -80,14 +85,15 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
uint64_t key,
notifiedFIFO_t *reponseFifo,
void (*processingFunc)(void *)) {
- notifiedFIFO_elt_t *ret;
- AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) calloc(1, sizeof(notifiedFIFO_elt_t)+size+32)), "");
+ notifiedFIFO_elt_t *ret = (notifiedFIFO_elt_t *)memalign(32, sizeof(notifiedFIFO_elt_t) + size);
+ AssertFatal(NULL != ret, "out of memory\n");
ret->next=NULL;
ret->key=key;
ret->reponseFifo=reponseFifo;
ret->processingFunc=processingFunc;
// We set user data piece aligend 32 bytes to be able to process it with SIMD
- ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32);
+ // msgData is aligned to 32bytes, so everything after will be as well
+ ret->msgData = ((uint8_t *)ret) + sizeof(notifiedFIFO_elt_t);
ret->malloced=true;
return ret;
}
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 28df446291..f7321c4ad1 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -127,27 +127,30 @@ Some other useful paramters of the UE are
## phy-test setup with OAI UE
-The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following
+The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC and circumventing random access. In this case both gNB and eNB need to be run with the `--phy-test` flag. At the gNB this flag does the following
- it reads the RRC configuration from the configuration file
- - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
- - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload
-
-At the UE the --phy-test flag will
- - read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them.
+ - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files `rbconfig.raw` and `reconfig.raw` in the current directory
+ - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload instead of the standard scheduler. The options `-m`, `-l`, `-t`, `-M`, `-T`, `-D`, and `-U` can be used to configure this scheduler. See `./nr-softmodem -h` for more information.
+At the UE, the `--phy-test` flag will read the binary files `rbconfig.raw` and `reconfig.raw` from the current directory and process them. If you wish to provide a different path for these files, please use the options `--reconfig-file` and `--rbconfig-file`.
```bash
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test
```
-In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB by passing through the command line parameter `--uecap_file` the location and file name of the input UE Capability file, e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml` (1 layer) or `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml` (2 layers).
-
```bash
-sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files]
+sudo ./nr-uesoftmodem --phy-test [--reconfig-file ../../../ci-scripts/rrc-files/reconfig.raw --rbconfig-file ../../../ci-scripts/rrc-files/rbconfig.raw]
```
-You need to provide `--rrc_config_path` if you don't start the UE after the gNB
-in the same directory.
+In summary:
+- If you are running on the same machine and launched the 2 executables (`nr-softmodem` and `nr-uesoftmodem`) from the same directory, nothing has to be done.
+- If you launched the 2 executables from 2 different folders, just point to the location where you launched the `nr-softmodem`:
+ * `sudo ./nr-uesoftmodem --rfsim --phy-test --reconfig-file /the/path/where/you/launched/nr-softmodem/reconfig-file --rbconfig-file /the/path/where/you/launched/nr-softmodem/rbconfig-file --rfsimulator.serveraddr `
+- If you are not running on the same machine, you need to **COPY** the two raw files
+ * `scp usera@machineA:/the/path/where/you/launched/nr-softmodem/r*config.raw userb@machineB:/the/path/where/you/will/launch/nr-uesoftmodem/`
+ * Obviously this operation should be done before launching the `nr-uesoftmodem` executable.
+
+In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB by passing through the command line parameter `--uecap_file` the location and file name of the input UE Capability file, e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml` (1 layer) or `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml` (2 layers).
## noS1 setup with OAI UE
diff --git a/doc/RUN_NR_NFAPI.md b/doc/RUN_NR_NFAPI.md
index 503fead0ed..5b597aa326 100644
--- a/doc/RUN_NR_NFAPI.md
+++ b/doc/RUN_NR_NFAPI.md
@@ -31,7 +31,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap
```
### UE command
```
-sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d --rfsimulator.serveraddr 127.0.0.1
+sudo ./nr-uesoftmodem --rfsim --phy-test -d --rfsimulator.serveraddr 127.0.0.1
```
## Procedure to run NR nFAPI using Hardware (tested with USRP x310)
@@ -48,7 +48,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap
```
### UE command
```
-sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test --rrc_config_path ../../../ci-scripts/rrc-files
+sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test
```
diff --git a/doc/RUN_NR_PRS.md b/doc/RUN_NR_PRS.md
index 64e754cb0f..af2f5f0325 100644
--- a/doc/RUN_NR_PRS.md
+++ b/doc/RUN_NR_PRS.md
@@ -21,8 +21,8 @@ After you have [built the softmodem executables](BUILD.md), go to the build dire
| **Mode** | **gNB config** | **nrUE config** |
|----------------------------- |------------------------------------------------------------------------------------------- |--------------------------- |
-| **FR1 40MHz
30kHz SCS** | gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf
gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf | ue.nr.prs.fr1.106prb.conf |
-| **FR2 100MHz
120kHz SCS** | gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf
gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf | ue.nr.prs.fr2.64prb.conf |
+| **FR1 40MHz
30kHz SCS** | gnb0.prs.band78.fr1.106PRB.usrpx310.conf
gnb1.prs.band78.fr1.106PRB.usrpx310.conf | ue.nr.prs.fr1.106prb.conf |
+| **FR2 100MHz
120kHz SCS** | gnb0.prs.band261.fr2.64PRB.usrpx310.conf
gnb1.prs.band261.fr2.64PRB.usrpx310.conf | ue.nr.prs.fr2.64prb.conf |
Under gNB and nrUE config files, parameters are configured under `prs_config` section. nrUE is capable to receive downlink PRS signal from multiple gNB simultaneously and therefore nrUE config file contains multiple `prs_config` sections, corresponding to each gNB. These parameters can be changed as per the test scenario.
@@ -64,26 +64,26 @@ In our case the output is 0 and hence we use `numactl --cpunodebind=0 --membind=
## FR1 test
Open a terminal on the host machine, and execute below command to launch gNB with **X310 USRPs**
-```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf --phy-test```
+```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --phy-test```
If **N310 USRPs** are used, then run above command `without -E option` i.e without 3/4 sampling rate.
To run using **rfsimulator**, execute following command:
-```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
+```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
## FR2 test
In FR2 mode, we need RF beamforming module to transmit signal in mmWave frequency range. **X310 USRPs** can be used with BasicTx daughtercard to transmit baseband signal at **Intermediate Frequncy(IF)** and then RF beamforming module would perform beamforming and the upconversion to FR2 frequencies. IF can be specified using `if_freq` in the RU section of gNB config.
If RF beamforming module is NOT present, gNB can still be launched with USRP alone; to transmit at supported `if_freq`.
-```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf --phy-test```
+```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf --phy-test```
To run using **rfsimulator**, execute following command:
-```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
+```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
## Multiple gNB scenario
PRS is primarily used for positioning and localization of the UE with multiple gNBs transmitting simultaneously. OAI PRS implementation supports multiple gNB transmission provided all the gNBs are tightely synchronized using GPSDO clock. Therefore before running this scenario, make sure the USRPs has built-in GPSDO and the GPS antennas are connected with good satellite visibility. Also every time a gNB is launched, wait until `GPS LOCKED` is printed on the terminal during gNB startup. If USRP fails to lock with GPSDO, try again until its locked.
diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c
index ffa50a766b..81d255b87d 100644
--- a/executables/nr-cuup.c
+++ b/executables/nr-cuup.c
@@ -27,6 +27,7 @@
#include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/F1AP/f1ap_common.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/GNB_APP/gnb_config.h"
#include "nr_pdcp/nr_pdcp_oai_api.h"
@@ -134,6 +135,7 @@ int main(int argc, char **argv)
rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL);
AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n");
nr_pdcp_layer_init();
+ cu_init_f1_ue_data(); // for CU-UP/CP mapping: we use the same
MessageDef *msg = RCconfig_NR_CU_E1(true);
AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n");
itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 7d2b11cf65..fb3b8a2e6c 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -777,8 +777,13 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
void *txp[ru->nb_tx];
unsigned int txs;
int i;
- T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot),
- T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4));
+ T(T_ENB_PHY_OUTPUT_SIGNAL,
+ T_INT(0),
+ T_INT(0),
+ T_INT(frame),
+ T_INT(slot),
+ T_INT(0),
+ T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot, fp, 0)], fp->get_samples_per_slot(slot, fp) * 4));
int sf_extension = 0;
int siglen=fp->get_samples_per_slot(slot,fp);
radio_tx_burst_flag_t flags_burst = TX_BURST_INVALID;
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index fe56f14ee4..2550001956 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -88,6 +88,8 @@
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n"
#define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n"
+#define CONFIG_HLP_RE_CFG_FILE "filename for reconfig.raw in phy-test mode\n"
+#define CONFIG_HLP_RB_CFG_FILE "filename for rbconfig.raw in phy-test mode\n"
#define CONFIG_HLP_UECAP_FILE "path for UE Capabilities file\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8b1f6b969f..8d0f6418e2 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -496,8 +496,9 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
void *txp[NB_ANTENNAS_TX];
- for (int i=0; iframe_parms.nb_antennas_tx; i++)
- txp[i] = (void *)&UE->common_vars.txData[i][UE->frame_parms.get_samples_slot_timestamp(proc->nr_slot_tx, &UE->frame_parms, 0)];
+ int slot = proc->nr_slot_tx;
+ for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++)
+ txp[i] = (void *)&UE->common_vars.txData[i][UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0)];
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
@@ -506,19 +507,18 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
openair0_cfg[0].duplex_mode == duplex_mode_TDD &&
!get_softmodem_params()->continuous_tx) {
- uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
- int nrofUplinkSlots = mac->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
- int nrofUplinkSymbols = mac->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
- int slot_tx_usrp = proc->nr_slot_tx;
- uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSymbols != 0);
- uint8_t first_tx_slot = tdd_period - num_UL_slots;
-
- if (slot_tx_usrp % tdd_period == first_tx_slot)
- flags = TX_BURST_START;
- else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1)
- flags = TX_BURST_END;
- else if (slot_tx_usrp % tdd_period > first_tx_slot)
- flags = TX_BURST_MIDDLE;
+ int slots_frame = UE->frame_parms.slots_per_frame;
+ int curr_slot = nr_ue_slot_select(&UE->nrUE_config, slot);
+ if (curr_slot != NR_DOWNLINK_SLOT) {
+ int next_slot = nr_ue_slot_select(&UE->nrUE_config, (slot + 1) % slots_frame);
+ int prev_slot = nr_ue_slot_select(&UE->nrUE_config, (slot + slots_frame - 1) % slots_frame);
+ if (prev_slot == NR_DOWNLINK_SLOT)
+ flags = TX_BURST_START;
+ else if (next_slot == NR_DOWNLINK_SLOT)
+ flags = TX_BURST_END;
+ else
+ flags = TX_BURST_MIDDLE;
+ }
} else {
flags = TX_BURST_MIDDLE;
}
@@ -851,8 +851,8 @@ void *UE_thread(void *arg)
curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER;
if (mac->phy_config_request_sent) {
- curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx);
- curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx);
+ curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_rx);
+ curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_tx);
}
else {
curMsg.proc.rx_slot_type = NR_DOWNLINK_SLOT;
@@ -944,15 +944,14 @@ void *UE_thread(void *arg)
return NULL;
}
-void init_NR_UE(int nb_inst,
- char* uecap_file,
- char* rrc_config_path) {
+void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
+{
int inst;
NR_UE_MAC_INST_t *mac_inst;
NR_UE_RRC_INST_t* rrc_inst;
for (inst=0; inst < nb_inst; inst++) {
- AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file,rrc_config_path)) != NULL, "can not initialize RRC module\n");
+ AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n");
AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
}
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 1c147047c1..35a9f9a473 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -123,6 +123,8 @@ char *usrp_args = NULL;
char *tx_subdev = NULL;
char *rx_subdev = NULL;
char *rrc_config_path = NULL;
+char *reconfig_file = NULL;
+char *rbconfig_file = NULL;
char *uecap_file = NULL;
int dumpframe = 0;
@@ -262,6 +264,8 @@ static void get_options(void) {
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_get(cmdline_params,numparams,NULL);
+ AssertFatal(rrc_config_path == NULL, "the option \"rrc_config_path\" is deprecated. Please use --reconfig-file and --rbconfig-file separately to point to files reconfig.raw and rbconfig.raw\n");
+
if (vcdflag > 0)
ouput_vcd = 1;
}
@@ -472,7 +476,7 @@ int main( int argc, char **argv ) {
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
- init_NR_UE(1,uecap_file,rrc_config_path);
+ init_NR_UE(1, uecap_file, reconfig_file, rbconfig_file);
int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1;
uint16_t node_number = get_softmodem_params()->node_number;
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 418373ccb4..3549a7fae1 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -36,11 +36,13 @@
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \
- {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \
+ {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
- {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \
+ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval=NULL, TYPE_STRING, 0}, \
+ {"reconfig-file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&reconfig_file, .defstrval="./reconfig.raw", TYPE_STRING, 0}, \
+ {"rbconfig-file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&rbconfig_file, .defstrval="./rbconfig.raw", TYPE_STRING, 0}, \
{"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
@@ -91,7 +93,7 @@ extern nrUE_params_t *get_nrUE_params(void);
// In nr-ue.c
extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
-extern void init_NR_UE(int, char*, char*);
+extern void init_NR_UE(int, char *, char *, char *);
extern void init_NR_UE_threads(int);
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 4acd5e0d5f..1220293e12 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -636,13 +636,12 @@ typedef struct
typedef struct
{
- fapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list;
+ fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list;
} fapi_nr_max_tdd_periodicity_t;
typedef struct
{
- uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
uint8_t tdd_period_in_slots;
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
@@ -683,7 +682,8 @@ typedef struct {
fapi_nr_cell_config_t cell_config;
fapi_nr_ssb_config_t ssb_config;
fapi_nr_ssb_table_t ssb_table;
- fapi_nr_tdd_table_t tdd_table;
+ fapi_nr_tdd_table_t tdd_table_1;
+ fapi_nr_tdd_table_t *tdd_table_2;
fapi_nr_prach_config_t prach_config;
} fapi_nr_config_request_t;
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 60d2368a48..0de7dbaa9c 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -34,6 +34,7 @@
#include "filt16a_32.h"
#include "T.h"
#include
+extern openair0_config_t openair0_cfg[];
//#define DEBUG_PDSCH
//#define DEBUG_PDCCH
@@ -45,7 +46,7 @@
#define NO_INTERP 1
/* Generic function to find the peak of channel estimation buffer */
-void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val)
+void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val)
{
int32_t max_val = 0, max_idx = 0, abs_val = 0;
for(int k = 0; k < buf_len; k++)
@@ -57,18 +58,26 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t
max_idx = k;
}
}
- *peak_val = max_val;
- *peak_idx = max_idx;
+
+ // Check for detection threshold
+ LOG_D(PHY, "PRS ToA estimator: max_val %d, mean_val %d, max_idx %d\n", max_val, mean_val, max_idx);
+ if ((mean_val != 0) && (max_val / mean_val > 10)) {
+ *peak_val = max_val;
+ *peak_idx = max_idx;
+ } else {
+ *peak_val = 0;
+ *peak_idx = 0;
+ }
}
-int nr_prs_channel_estimation(uint8_t rsc_id,
+int nr_prs_channel_estimation(uint8_t gNB_id,
+ uint8_t rsc_id,
uint8_t rep_num,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_DL_FRAME_PARMS *frame_params,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
- int gNB_id = proc->gNB_id;
uint8_t rxAnt = 0, idx = 0;
prs_config_t *prs_cfg = &ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg;
prs_meas_t **prs_meas = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas;
@@ -85,15 +94,19 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1];
const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
int16_t ch[2] = {0}, noiseFig[2] = {0};
- int16_t k_prime = 0, k = 0, re_offset = 0, first_half = 0, second_half = 0;
- int32_t ch_pwr = 0, snr = 0;
+ int16_t k_prime = 0, k = 0;
+ int32_t ch_pwr = 0, snr = 0, rsrp = 0, mean_val = 0, prs_toa = 0;
+ double ch_pwr_dbm = 0.0f;
#ifdef DEBUG_PRS_CHEST
char filename[64] = {0}, varname[64] = {0};
#endif
int16_t *ch_tmp = (int16_t *)ch_tmp_buf;
int16_t scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15);
int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB;
- int16_t start_offset = (NR_PRS_IDFT_OVERSAMP_FACTOR-1)*frame_params->ofdm_symbol_size>>1;
+ int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset;
+ int16_t second_half = (prs_cfg->NumRB * 12) - first_half;
+ int16_t start_offset = NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size - first_half;
+ LOG_D(PHY, "start_offset %d, first_half %d, second_half %d\n", start_offset, first_half, second_half);
int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE;
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++)
@@ -125,10 +138,12 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++)
{
+ // reset variables
snr = 0;
-
+ rsrp = 0;
+
// calculate RE offset
- k = re_offset = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_params->first_carrier_offset;
+ k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset;
// Channel estimation and interpolation
pil = (int16_t *)&mod_prs[0];
@@ -170,7 +185,8 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch_tmp,
8);
- //SNR estimation
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig));
@@ -200,8 +216,9 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch_tmp,
8);
}
-
- //SNR estimation
+
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig));
@@ -228,8 +245,9 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch_tmp,
8);
}
-
- //SNR estimation
+
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
@@ -250,16 +268,24 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch_tmp,
8);
- //SNR estimation
- noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
- noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
- snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
+ noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0] * pil[0] - (int32_t)ch[1] * pil[1]) >> 15);
+ noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1] * pil[0] + (int32_t)ch[0] * pil[1]) >> 15);
+ snr += 10 * log10(squaredMod(*((c16_t *)rxF)) - squaredMod(*((c16_t *)noiseFig))) - 10 * log10(squaredMod(*((c16_t *)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
- printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
+ printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n",
+ rxAnt,
+ num_pilots - 1,
+ snr / num_pilots,
+ rxF[0],
+ rxF[1],
+ &rxF[0],
+ ch[0],
+ ch[1],
+ pil[0],
+ pil[1]);
#endif
- // average out the SNR computed
- snr = snr/num_pilots;
- prs_meas[rxAnt]->snr = snr;
}
else if(prs_cfg->CombSize == 4)
{
@@ -314,8 +340,9 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch,
ch_tmp,
16);
-
- //SNR estimation
+
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
@@ -333,7 +360,8 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch_tmp,
16);
- //SNR estimation
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
@@ -354,8 +382,9 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch,
ch_tmp,
16);
-
- //SNR estimation
+
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
@@ -375,8 +404,9 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch,
ch_tmp,
16);
-
- //SNR estimation
+
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
@@ -393,23 +423,25 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
ch,
ch_tmp,
16);
-
- //SNR estimation
+
+ // SNR & RSRP estimation
+ rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, +%d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
- // average out the SNR computed
- snr = snr/num_pilots;
- prs_meas[rxAnt]->snr = snr;
}
else
{
AssertFatal((prs_cfg->CombSize == 2)||(prs_cfg->CombSize == 4), "[%s] DL PRS CombSize other than 2 and 4 are NOT supported currently. Exiting!!!", __FUNCTION__);
}
+ // average out the SNR and RSRP computed
+ prs_meas[rxAnt]->snr = snr / (float)num_pilots;
+ prs_meas[rxAnt]->rsrp = rsrp / (float)num_pilots;
+
//reset channel pointer
ch_tmp = (int16_t*)ch_tmp_buf;
} // for rxAnt
@@ -438,12 +470,10 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
#endif
// Place PRS channel estimates in FFT shifted format
- first_half = frame_params->ofdm_symbol_size - re_offset;
- second_half = (prs_cfg->NumRB*12) - first_half;
if(first_half > 0)
- memcpy((int16_t *)&chF_interpol[rxAnt][start_offset+re_offset], &ch_tmp[0], first_half*sizeof(int32_t));
+ memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half * sizeof(int32_t));
if(second_half > 0)
- memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[(first_half<<1)], second_half*sizeof(int32_t));
+ memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half << 1], second_half * sizeof(int32_t));
// Time domain IMPULSE response
idft_size_idx_t idftsizeidx;
@@ -527,10 +557,14 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
(int16_t *)&chT_interpol[rxAnt][0],1);
// peak estimator
- peak_estimator(&chT_interpol[rxAnt][start_offset],
- frame_params->ofdm_symbol_size,
- &prs_meas[rxAnt]->dl_toa,
- &ch_pwr);
+ mean_val = squaredMod(((c16_t *)ch_tmp)[(prs_cfg->NumRB * 12) >> 1]);
+ peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, &ch_pwr, mean_val);
+
+ // adjusting the rx_gains for channel peak power
+ ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - 10 * log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size);
+
+ prs_meas[rxAnt]->rsrp_dBm =
+ 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - 10 * log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
//prs measurements
prs_meas[rxAnt]->gNB_id = gNB_id;
@@ -538,7 +572,21 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
prs_meas[rxAnt]->slot = proc->nr_slot_rx;
prs_meas[rxAnt]->rxAnt_idx = rxAnt;
prs_meas[rxAnt]->dl_aoa = rsc_id;
- LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %d / %d samples, peak channel power %.1f dBm, SNR %+2d dB\n", gNB_id, rsc_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, prs_meas[rxAnt]->dl_toa, frame_params->ofdm_symbol_size, 10*log10(ch_pwr/frame_params->ofdm_symbol_size)-30, prs_meas[rxAnt]->snr);
+ prs_meas[rxAnt]->dl_toa = prs_toa / (float)NR_PRS_IDFT_OVERSAMP_FACTOR;
+ if ((frame_params->ofdm_symbol_size - prs_meas[rxAnt]->dl_toa) < frame_params->ofdm_symbol_size / 2)
+ prs_meas[rxAnt]->dl_toa -= (frame_params->ofdm_symbol_size);
+ LOG_I(PHY,
+ "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %.1f / %d samples, peak channel power %.1f dBm, SNR %+.1f dB, rsrp %+.1f dBm\n",
+ gNB_id,
+ rsc_id,
+ rxAnt,
+ proc->frame_rx,
+ proc->nr_slot_rx,
+ prs_meas[rxAnt]->dl_toa,
+ frame_params->ofdm_symbol_size,
+ ch_pwr_dbm,
+ prs_meas[rxAnt]->snr,
+ prs_meas[rxAnt]->rsrp_dBm);
#ifdef DEBUG_PRS_CHEST
sprintf(filename, "%s%i%s", "PRSpilot_", rxAnt, ".m");
@@ -559,13 +607,21 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx),
T_INT(rxAnt), T_BUFFER(&rxdataF[rxAnt][0], frame_params->samples_per_slot_wCP*sizeof(int32_t)));
- T(T_UE_PHY_DL_CHANNEL_ESTIMATE_FREQ, T_INT(gNB_id), T_INT(rsc_id),
- T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx),
- T_INT(rxAnt), T_BUFFER(&chF_interpol[rxAnt][start_offset], frame_params->ofdm_symbol_size*sizeof(int32_t)));
+ T(T_UE_PHY_DL_CHANNEL_ESTIMATE_FREQ,
+ T_INT(gNB_id),
+ T_INT(rsc_id),
+ T_INT(proc->frame_rx),
+ T_INT(proc->nr_slot_rx),
+ T_INT(rxAnt),
+ T_BUFFER(&chF_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(int32_t)));
- T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(gNB_id), T_INT(rsc_id),
- T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx),
- T_INT(rxAnt), T_BUFFER(&chT_interpol[rxAnt][start_offset], frame_params->ofdm_symbol_size*sizeof(int32_t)));
+ T(T_UE_PHY_DL_CHANNEL_ESTIMATE,
+ T_INT(gNB_id),
+ T_INT(rsc_id),
+ T_INT(proc->frame_rx),
+ T_INT(proc->nr_slot_rx),
+ T_INT(rxAnt),
+ T_BUFFER(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(int32_t)));
}
return(0);
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 19bc2f410c..8ac877a29e 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -33,7 +33,8 @@
#define SYNCH_HYST 2
/* A function to perform the channel estimation of DL PRS signal */
-int nr_prs_channel_estimation(uint8_t rsc_id,
+int nr_prs_channel_estimation(uint8_t gNB_id,
+ uint8_t rsc_id,
uint8_t rep_num,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
@@ -41,7 +42,7 @@ int nr_prs_channel_estimation(uint8_t rsc_id,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
/* Generic function to find the peak of channel estimation buffer */
-void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val);
+void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val);
/*!
\brief This function performs channel estimation including frequency and temporal interpolation
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index a800d3b8d7..a03555f772 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -187,7 +187,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
#ifdef DEBUG_INITIAL_SYNCH
- LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
+ LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
#endif
return(0);
} else {
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index d07bf07076..79ac95ef73 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -193,7 +193,9 @@ void websrv_setpoint(int x, int y, websrv_scopedata_msg_t *msg)
msg->data_xy[msg->data_xy[0]] = (int16_t)y;
}
#endif
-static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor)
+{
+ memset(graph, 0, sizeof(*graph));
if (type==WATERFALL) {
graph->waterFallh=h-15;
graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh);
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 13a75aaf44..0741291fb4 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -289,9 +289,11 @@ typedef struct {
int32_t sfn;
int8_t slot;
int8_t rxAnt_idx;
- int32_t dl_toa;
+ float dl_toa;
int32_t dl_aoa;
- int32_t snr;
+ float snr;
+ float rsrp;
+ float rsrp_dBm;
int32_t reserved;
} prs_meas_t;
diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
index fcc2fa5838..59df0ba959 100644
--- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h
+++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
@@ -72,7 +72,7 @@ int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_slot);
* @param nr_slot : slot number
@returns int : downlink, uplink or mixed slot type */
-int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot);
+int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_slot);
/** \brief This function frees tdd configuration for nr
* @param frame_parms NR DL Frame parameters
diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c
index 696828a970..be1f39ab67 100644
--- a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c
@@ -39,63 +39,40 @@
*
*********************************************************************/
-int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot) {
- /* for FFD all slot can be considered as an uplink */
- int mu = cfg->ssb_config.scs_common, check_slot = 0;
+int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_slot)
+{
+ if (cfg->cell_config.frame_duplex_type == FDD)
+ return NR_UPLINK_SLOT | NR_DOWNLINK_SLOT;
- if (cfg->cell_config.frame_duplex_type == FDD) {
- return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
+ int period = cfg->tdd_table_1.tdd_period_in_slots +
+ (cfg->tdd_table_2 ? cfg->tdd_table_2->tdd_period_in_slots : 0);
+ int rel_slot = nr_slot % period;
+ fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table_1;
+ if (cfg->tdd_table_2 && rel_slot >= tdd_table->tdd_period_in_slots) {
+ rel_slot -= tdd_table->tdd_period_in_slots;
+ tdd_table = cfg->tdd_table_2;
}
- if (cfg->tdd_table.max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration
- return (NR_DOWNLINK_SLOT);
- if (nr_frame%2 == 0) {
- for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
- check_slot++;
- }
- }
+ if (tdd_table->max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration
+ return NR_DOWNLINK_SLOT;
- if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
- return (NR_UPLINK_SLOT);
- }
+ fapi_nr_max_tdd_periodicity_t *current_slot = &tdd_table->max_tdd_periodicity_list[rel_slot];
- check_slot = 0;
+ // if the 1st symbol is UL the whole slot is UL
+ if (current_slot->max_num_of_symbol_per_slot_list[0].slot_config == 1)
+ return NR_UPLINK_SLOT;
- for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
- check_slot++;
- }
- }
+ // if the 1st symbol is flexible the whole slot is mixed
+ if (current_slot->max_num_of_symbol_per_slot_list[0].slot_config == 2)
+ return NR_MIXED_SLOT;
- if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
- return (NR_DOWNLINK_SLOT);
- } else {
- return (NR_MIXED_SLOT);
- }
- } else {
- for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<max_num_of_symbol_per_slot_list[i].slot_config != 0) {
+ return NR_MIXED_SLOT;
}
}
+
+ // if here, all the symbols where DL
+ return NR_DOWNLINK_SLOT;
}
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 21b344d901..3c5c7e250a 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -943,12 +943,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
(j%fp->symbols_per_slot),
rxdataF);
}
- nr_prs_channel_estimation(rsc_id,
- i,
- ue,
- proc,
- fp,
- rxdataF);
+ nr_prs_channel_estimation(gNB_id, rsc_id, i, ue, proc, fp, rxdataF);
}
} // for i
} // for rsc_id
diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index 7a88344efc..7a1a8b2698 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -156,7 +156,6 @@ typedef struct pdu_session_to_setup_s {
typedef struct e1ap_bearer_setup_req_s {
uint32_t gNB_cu_cp_ue_id;
uint32_t gNB_cu_up_ue_id;
- rnti_t rnti;
uint64_t cipheringAlgorithm;
uint64_t integrityProtectionAlgorithm;
char encryptionKey[128];
@@ -216,8 +215,8 @@ typedef struct pdu_session_setup_s {
} pdu_session_setup_t;
typedef struct e1ap_bearer_setup_resp_s {
- uint64_t gNB_cu_cp_ue_id;
- uint64_t gNB_cu_up_ue_id;
+ uint32_t gNB_cu_cp_ue_id;
+ uint32_t gNB_cu_up_ue_id;
int numDRBs;
drb_setup_t DRBList[E1AP_MAX_NUM_DRBS];
int numPDUSessions;
diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
index 08cc03c4fa..3d594a695e 100644
--- a/openair2/COMMON/f1ap_messages_types.h
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -286,8 +286,7 @@ typedef struct f1ap_dl_rrc_message_s {
uint32_t gNB_CU_ue_id;
uint32_t gNB_DU_ue_id;
- uint32_t old_gNB_DU_ue_id;
- uint16_t rnti;
+ uint32_t *old_gNB_DU_ue_id;
uint8_t srb_id;
uint8_t execute_duplication;
uint8_t *rrc_container;
@@ -318,7 +317,8 @@ typedef struct f1ap_initial_ul_rrc_message_s {
} f1ap_initial_ul_rrc_message_t;
typedef struct f1ap_ul_rrc_message_s {
- uint16_t rnti;
+ uint32_t gNB_CU_ue_id;
+ uint32_t gNB_DU_ue_id;
uint8_t srb_id;
uint8_t *rrc_container;
int rrc_container_length;
@@ -378,9 +378,8 @@ typedef enum ReconfigurationCompl_e {
} ReconfigurationCompl_t;
typedef struct f1ap_ue_context_setup_s {
- uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti
+ uint32_t gNB_CU_ue_id;
uint32_t gNB_DU_ue_id;
- uint16_t rnti;
// SpCell Info
uint16_t mcc;
uint16_t mnc;
@@ -419,7 +418,8 @@ typedef enum F1ap_Cause_e {
} f1ap_Cause_t;
typedef struct f1ap_ue_context_release_s {
- uint16_t rnti;
+ uint32_t gNB_CU_ue_id;
+ uint32_t gNB_DU_ue_id;
f1ap_Cause_t cause;
long cause_value;
uint8_t *rrc_container;
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index 6c33ddf973..27eb9f5848 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -1095,7 +1095,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq,
ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
ieC2->criticality = E1AP_Criticality_reject;
ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
- ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id;
+ ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id;
/* optional */
/* */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3);
diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c
index cf167f64e8..9cec6b69f3 100644
--- a/openair2/E1AP/e1ap_api.c
+++ b/openair2/E1AP/e1ap_api.c
@@ -30,6 +30,7 @@
#include "openair2/RRC/LTE/MESSAGES/asn1_msg.h"
#include "openair3/SECU/key_nas_deriver.h"
#include "openair3/ocp-gtpu/gtp_itf.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "e1ap_asnc.h"
#include "e1ap_common.h"
#include "e1ap.h"
@@ -109,7 +110,7 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req,
fill_DRB_configList_e1(&DRB_configList, pdu);
}
create_tunnel_req.num_tunnels = req->numPDUSessions;
- create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
+ create_tunnel_req.ue_id = req->gNB_cu_cp_ue_id;
// Create N3 tunnel
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req);
@@ -136,6 +137,11 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_
AssertFatal(inst, "");
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
+ uint32_t gNB_cu_up_ue_id = req ->gNB_cu_cp_ue_id;
+ LOG_I(E1AP, "adding UE with CU-CP UE ID %d and CU-UP UE ID %d\n", req->gNB_cu_cp_ue_id, gNB_cu_up_ue_id);
+ f1_ue_data_t ue_data = {.secondary_ue = req->gNB_cu_cp_ue_id};
+ cu_add_f1_ue_data(gNB_cu_up_ue_id, &ue_data);
+
// GTP tunnel for UL
drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3);
@@ -148,6 +154,7 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_
fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr);
resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id;
+ resp->gNB_cu_up_ue_id = gNB_cu_up_ue_id;
resp->numPDUSessions = req->numPDUSessions;
for (int i=0; i < req->numPDUSessions; i++) {
pdu_session_setup_t *pduSetup = resp->pduSession + i;
diff --git a/openair2/F1AP/CMakeLists.txt b/openair2/F1AP/CMakeLists.txt
index 7537bd661d..e6490b96b0 100644
--- a/openair2/F1AP/CMakeLists.txt
+++ b/openair2/F1AP/CMakeLists.txt
@@ -1 +1,8 @@
add_subdirectory(MESSAGES)
+
+if(ENABLE_TESTS)
+ add_executable(f1ap_ids_test f1ap_ids_test.c f1ap_ids.c)
+ target_link_libraries(f1ap_ids_test UTIL HASHTABLE minimal_lib)
+ add_dependencies(tests f1ap_ids_test)
+ add_test(NAME F1AP_ID_test COMMAND f1ap_ids_test)
+endif()
diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c
index f417a1c337..f396d570df 100644
--- a/openair2/F1AP/f1ap_common.c
+++ b/openair2/F1AP/f1ap_common.c
@@ -66,123 +66,6 @@ void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req) {
}
}
-int f1ap_add_ue(F1_t isCu,
- instance_t instanceP,
- rnti_t rntiP) {
- f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].rnti == rntiP) {
- f1_inst->f1ap_ue[i].f1ap_uid = i;
- LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
- return i;
- }
- }
-
- // We didn't find the rnti
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].rnti == 0 ) {
- f1_inst->f1ap_ue[i].rnti = rntiP;
- f1_inst->f1ap_ue[i].f1ap_uid = i;
- f1_inst->f1ap_ue[i].du_ue_f1ap_id = rntiP;
- f1_inst->f1ap_ue[i].cu_ue_f1ap_id = rntiP;
- f1_inst->num_ues++;
- LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
- return i;
- }
- }
-
- return -1;
-}
-
-
-int f1ap_remove_ue(F1_t isCu, instance_t instanceP,
- rnti_t rntiP) {
- f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].rnti == rntiP) {
- f1_inst->f1ap_ue[i].rnti = 0;
- break;
- }
- }
-
- f1_inst->num_ues--;
- return 0;
-}
-
-int f1ap_get_du_ue_f1ap_id(F1_t isCu, instance_t instanceP,
- rnti_t rntiP) {
- f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].rnti == rntiP) {
- return f1_inst->f1ap_ue[i].du_ue_f1ap_id;
- }
- }
-
- return -1;
-}
-
-int f1ap_get_cu_ue_f1ap_id(F1_t isCu, instance_t instanceP,
- rnti_t rntiP) {
- f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].rnti == rntiP) {
- return f1_inst->f1ap_ue[i].cu_ue_f1ap_id;
- }
- }
-
- return -1;
-}
-
-int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP,
- instance_t du_ue_f1ap_id ) {
- f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) {
- return f1_inst->f1ap_ue[i].rnti;
- }
- }
-
- return -1;
-}
-
-int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP,
- instance_t cu_ue_f1ap_id ) {
- f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) {
- return f1_inst->f1ap_ue[i].rnti;
- }
- }
-
- return -1;
-}
-
-int f1ap_du_add_cu_ue_id(instance_t instanceP,
- instance_t du_ue_f1ap_id,
- instance_t cu_ue_f1ap_id) {
- f1ap_cudu_inst_t *f1_inst=getCxt(DUtype, instanceP);
- instance_t f1ap_uid=-1;
-
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) {
- f1ap_uid=i;
- break;
- }
- }
-
- if (f1ap_uid < 0 || f1ap_uid >= MAX_MOBILES_PER_GNB)
- return -1;
-
- f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id;
- LOG_D(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti);
- return 0;
-}
int f1ap_assoc_id(F1_t isCu, instance_t instanceP) {
f1ap_setup_req_t *f1_inst=f1ap_req(isCu, instanceP);
diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h
index ff492820d7..a346d9682a 100644
--- a/openair2/F1AP/f1ap_common.h
+++ b/openair2/F1AP/f1ap_common.h
@@ -427,30 +427,6 @@ uint8_t F1AP_get_next_transaction_identifier(instance_t mod_idP, instance_t cu_m
f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP);
void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req);
-int f1ap_add_ue(F1_t isCu,
- instance_t instanceP,
- rnti_t rntiP);
-
-int f1ap_remove_ue(F1_t isCu, instance_t instanceP,
- rnti_t rntiP);
-
-int f1ap_get_du_ue_f1ap_id (F1_t isCu, instance_t instanceP,
- rnti_t rntiP);
-
-int f1ap_get_cu_ue_f1ap_id (F1_t isCu, instance_t instanceP,
- rnti_t rntiP);
-
-
-int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP,
- instance_t du_ue_f1ap_id );
-
-
-int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP,
- instance_t cu_ue_f1ap_id );
-
-int f1ap_du_add_cu_ue_id(instance_t instanceP,
- instance_t du_ue_f1ap_id,
- instance_t cu_ue_f1ap_id);
int f1ap_assoc_id(F1_t isCu, instance_t instanceP);
diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
index 5c3b100efd..13bc9954a3 100644
--- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
@@ -32,6 +32,7 @@
#include "f1ap_common.h"
#include "f1ap_encoder.h"
+#include "f1ap_ids.h"
#include "f1ap_itti_messaging.h"
#include "f1ap_cu_rrc_message_transfer.h"
#include "common/ran_context.h"
@@ -53,9 +54,6 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
MessageDef *message_p;
F1AP_InitialULRRCMessageTransfer_t *container;
F1AP_InitialULRRCMessageTransferIEs_t *ie;
- rnti_t rnti;
- sdu_size_t ccch_sdu_len;
- int CC_id =0;
DevAssert(pdu != NULL);
if (stream != 0) {
@@ -68,6 +66,8 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+ uint32_t du_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+
/* NRCGI
* Fixme: process NRCGI
*/
@@ -78,7 +78,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
/* RNTI */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_C_RNTI, true);
- rnti = ie->value.choice.C_RNTI;
+ rnti_t rnti = ie->value.choice.C_RNTI;
F1AP_InitialULRRCMessageTransferIEs_t *rrccont;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container,
F1AP_ProtocolIE_ID_id_RRCContainer, true);
@@ -88,51 +88,22 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container,
F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false);
- int f1ap_uid = f1ap_add_ue(CUtype, instance, rnti);
-
- if (f1ap_uid < 0 ) {
- LOG_E(F1AP, "Failed to add UE \n");
- return -1;
- }
-
// create an ITTI message and copy SDU
- if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) {
- message_p = itti_alloc_new_message (TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
- f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p);
- ul_rrc->nr_cellid = nr_cellid; // CU instance
- ul_rrc->crnti = rnti;
- ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size;
- ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length);
- memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length);
- AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n");
- ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size;
- ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length);
- memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length);
- itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p);
- } else {
- message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND);
- memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
- ccch_sdu_len = rrccont->value.choice.RRCContainer.size;
- memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf,
- ccch_sdu_len);
- NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0;
- NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = 0;
- NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len;
- NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance
- NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti;
- NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
- if (du2cu) {
- NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t));
- NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size;
- NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(du2cu->value.choice.DUtoCURRCContainer.size);
- memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf,
- du2cu->value.choice.DUtoCURRCContainer.buf,
- du2cu->value.choice.DUtoCURRCContainer.size);
- }
- itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);
- }
+ AssertFatal(f1ap_req(true, instance)->cell_type == CELL_MACRO_GNB, "illegal cell type %d\n", f1ap_req(true, instance)->cell_type);
+ message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
+ 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
+ ul_rrc->crnti = rnti;
+ ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size;
+ ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length);
+ memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length);
+ AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n");
+ ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size;
+ ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length);
+ memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length);
+ itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p);
- //getCxt(true,ITTI_MSG_DESTINATION_ID(message_p))->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
return 0;
}
@@ -161,26 +132,28 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti);
- LOG_D(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %ld)\n",
- (unsigned long long int)ie1->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance);
+ DevAssert(f1ap_dl_rrc->gNB_CU_ue_id != 0);
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_dl_rrc->gNB_CU_ue_id;
+
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti);
- LOG_D(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie2->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti);
+ DevAssert(f1ap_dl_rrc->gNB_DU_ue_id != 0);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_dl_rrc->gNB_DU_ue_id;
+
/* optional */
/* c3. oldgNB_DU_UE_F1AP_ID */
- /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) {
- asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3);
- ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
- ie3->criticality = F1AP_Criticality_reject;
- ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING;
- ie3->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id;
- }*/
+ if (f1ap_dl_rrc->old_gNB_DU_ue_id != NULL) {
+ asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3);
+ ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
+ ie3->criticality = F1AP_Criticality_reject;
+ ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1;
+ ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *f1ap_dl_rrc->old_gNB_DU_ue_id;
+ }
+
/* mandatory */
/* c4. SRBID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4);
@@ -267,14 +240,19 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
- LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n",
- cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id));
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
- LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n",
- du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, du_ue_f1ap_id));
+ /* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here.
+ * For the moment, let's hope this won't become relevant; to sleep in peace,
+ * let's put an assert to check that it is the expected DU UE ID. */
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(cu_ue_f1ap_id);
+ AssertFatal(ue_data.secondary_ue == du_ue_f1ap_id,
+ "unexpected DU UE ID %d received, expected it to be %ld\n",
+ ue_data.secondary_ue,
+ du_ue_f1ap_id);
+
/* mandatory */
/* SRBID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
@@ -294,7 +272,7 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
protocol_ctxt_t ctxt={0};
ctxt.instance = instance;
ctxt.module_id = instance;
- ctxt.rntiMaybeUEid = f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id);
+ ctxt.rntiMaybeUEid = cu_ue_f1ap_id;
ctxt.enb_flag = 1;
ctxt.eNB_index = 0;
mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__);
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index 8fdee52abb..a72a359c5b 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -82,7 +82,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_setup_req->rnti); //f1ap_ue_context_setup_req->gNB_CU_ue_id;
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id;
/* optional */
/* c2. GNB_DU_UE_F1AP_ID */
@@ -91,7 +91,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_ignore;
ie2->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_setup_req->rnti); //*f1ap_ue_context_setup_req->gNB_DU_ue_id;
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_DU_ue_id;
}
/* mandatory */
@@ -510,7 +510,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
/* 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(CUtype, instance)->gtpInst,
- f1ap_ue_context_setup_req->rnti,
+ 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,
0xFFFF, // We will set the right value from DU answer
@@ -654,8 +654,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
f1ap_ue_context_setup_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_setup_resp->gNB_DU_ue_id);
- f1ap_ue_context_setup_resp->rnti =
- f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_setup_resp->gNB_DU_ue_id);
// DUtoCURRCInformation
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, true);
@@ -695,7 +693,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance,
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst,
- f1ap_ue_context_setup_resp->rnti,
+ f1ap_ue_context_setup_resp->gNB_DU_ue_id,
(ebi_t)drbs_setup_item_p->dRBID,
drb_p->up_dl_tnl[0].tl_address,
drb_p->up_dl_tnl[0].teid);
@@ -786,17 +784,12 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t assoc_id,
/* GNB_CU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
- const rnti_t rnti = f1ap_get_rnti_by_cu_id(true, instance,
- ie->value.choice.GNB_CU_UE_F1AP_ID);
- req->rnti = rnti;
+ req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
- const rnti_t rnti2 = f1ap_get_rnti_by_du_id(CUtype, instance,
- ie->value.choice.GNB_DU_UE_F1AP_ID);
- AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
- rnti2, rnti);
+ req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
/* Cause */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
@@ -857,14 +850,14 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, cmd->rnti);
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = cmd->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, cmd->rnti);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = cmd->gNB_DU_ue_id;
/* mandatory */
/* c3. Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie3);
@@ -933,19 +926,18 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
F1AP_UEContextReleaseComplete_t *container;
F1AP_UEContextReleaseCompleteIEs_t *ie;
DevAssert(pdu);
+ MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE);
+ 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 */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
- const rnti_t rnti = f1ap_get_rnti_by_cu_id(CUtype, instance,
- ie->value.choice.GNB_CU_UE_F1AP_ID);
+ complete->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
- const rnti_t rnti2 = f1ap_get_rnti_by_du_id(CUtype, instance,
- ie->value.choice.GNB_DU_UE_F1AP_ID);
- AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
- rnti2, rnti);
+ complete->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+
/* Optional*/
/* CriticalityDiagnostics */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
@@ -959,24 +951,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
// F1AP_CriticalityDiagnostics_IE_List
}
- protocol_ctxt_t ctxt;
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, GNB_FLAG_YES, rnti, 0, 0, instance);
+ itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], rnti);
-
- if (ue_context_p) {
- MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
- NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
- itti_send_msg_to_task(TASK_NGAP, instance, msg);
- rrc_gNB_remove_ue_context(RC.nrrrc[instance], ue_context_p);
- } else {
- LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
- }
-
- nr_pdcp_remove_UE(ctxt.rntiMaybeUEid);
-
- LOG_I(F1AP, "Received UE CONTEXT RELEASE COMPLETE: Removing CU UE entry for RNTI %x\n", rnti);
- f1ap_remove_ue(CUtype, instance, rnti);
return 0;
}
@@ -1002,14 +978,14 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);;
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);;
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_DU_ue_id;
/* optional */
/* c3. NRCGI */
@@ -1618,9 +1594,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id);
- f1ap_ue_context_modification_resp->rnti =
- f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id);
-
// DUtoCURRCInformation
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false);
@@ -1656,7 +1629,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst,
- f1ap_ue_context_modification_resp->rnti,
+ f1ap_ue_context_modification_resp->gNB_CU_ue_id,
(ebi_t)drbs_setupmod_item_p->dRBID,
drb_p->up_dl_tnl[0].tl_address,
drb_p->up_dl_tnl[0].teid);
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
index 5fc8daef3f..bcb38029cd 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -50,6 +50,7 @@
#include "asn1_msg.h"
#include "intertask_interface.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
@@ -60,8 +61,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
F1AP_F1AP_PDU_t *pdu) {
F1AP_DLRRCMessageTransfer_t *container;
F1AP_DLRRCMessageTransferIEs_t *ie;
- uint64_t cu_ue_f1ap_id;
- uint64_t du_ue_f1ap_id;
int executeDuplication;
//uint64_t subscriberProfileIDforRFP;
//uint64_t rAT_FrequencySelectionPriority;
@@ -70,26 +69,23 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
/* GNB_CU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
- cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
- LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id);
+ uint32_t cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
- du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
- LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n",
- du_ue_f1ap_id,
- f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer
-
- if (f1ap_du_add_cu_ue_id(instance,du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) {
- LOG_E(F1AP, "Failed to find the F1AP UID \n");
- //return -1;
- }
+ uint32_t du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
/* optional */
/* oldgNB_DU_UE_F1AP_ID */
- if (0) {
- F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
- F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true);
+ uint32_t *old_gNB_DU_ue_id = NULL;
+ uint32_t old_gNB_DU_ue_id_stack = 0;
+ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+ F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false);
+ if (ie) {
+ /* strange: it is not named OLD_GNB_DU_UE... */
+ old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1;
+ old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack;
+ gtpv1u_update_ue_id(getCxt(false, instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id);
}
/* mandatory */
@@ -135,34 +131,24 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
}
f1ap_dl_rrc_message_t dl_rrc = {
+ .gNB_CU_ue_id = cu_ue_f1ap_id,
+ .gNB_DU_ue_id = du_ue_f1ap_id,
+ .old_gNB_DU_ue_id = old_gNB_DU_ue_id,
.rrc_container_length = ie->value.choice.RRCContainer.size,
.rrc_container = ie->value.choice.RRCContainer.buf,
- .rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id),
.srb_id = srb_id
};
- dl_rrc_message(instance, &dl_rrc);
+ dl_rrc_message_transfer(&dl_rrc);
return 0;
}
/* UL RRC Message Transfer */
-int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
- int CC_idP,
- int UE_id,
- rnti_t rntiP,
- const uint8_t *sduP,
- sdu_size_t sdu_lenP,
- const uint8_t *sdu2P,
- sdu_size_t sdu2_lenP) {
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg)
+{
F1AP_F1AP_PDU_t pdu= {0};
F1AP_InitialULRRCMessageTransfer_t *out;
uint8_t *buffer=NULL;
uint32_t len=0;
- int f1ap_uid = f1ap_add_ue (DUtype, instanceP, rntiP);
-
- if (f1ap_uid < 0 ) {
- LOG_E(F1AP, "Failed to add UE \n");
- return -1;
- }
/* Create */
/* 0. Message Type */
@@ -178,7 +164,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie1->value.choice.GNB_DU_UE_F1AP_ID = getCxt(DUtype, instanceP)->f1ap_ue[f1ap_uid].du_ue_f1ap_id;
+ ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* mandatory */
/* c2. NRCGI */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2);
@@ -193,25 +179,25 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI;
- ie3->value.choice.C_RNTI=rntiP;
+ ie3->value.choice.C_RNTI = msg->crnti;
/* mandatory */
/* c4. RRCContainer */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4);
ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer;
ie4->criticality = F1AP_Criticality_reject;
ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer;
- OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)sduP, sdu_lenP);
+ OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length);
/* optional */
/* c5. DUtoCURRCContainer */
- if (sdu2P) {
+ if (msg->du2cu_rrc_container != NULL) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5);
ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer;
ie5->criticality = F1AP_Criticality_reject;
ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer;
OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer,
- (const char *)sdu2P,
- sdu2_lenP);
+ (const char *)msg->du2cu_rrc_container,
+ msg->du2cu_rrc_container_length);
}
/* mandatory */
/* c6. Transaction ID (integer value) */
@@ -231,16 +217,19 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
return 0;
}
-
-int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
- const f1ap_ul_rrc_message_t *msg) {
- const rnti_t rnti = msg->rnti;
+int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, 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__, msg->rrc_container_length, rnti, msg->srb_id);
+ LOG_D(F1AP,
+ "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n",
+ instance,
+ __func__,
+ msg->rrc_container_length,
+ msg->gNB_DU_ue_id,
+ msg->srb_id);
//for (int i = 0;i < msg->rrc_container_length; i++)
// printf("%02x ", msg->rrc_container[i]);
//printf("\n");
@@ -258,14 +247,14 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, rnti);
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, rnti);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* mandatory */
/* c3. SRBID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie3);
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h
index 7a0c1f8974..f784b7a0cf 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h
@@ -43,13 +43,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg);
-int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
- int CC_idP,
- int UE_id,
- rnti_t rntiP,
- const uint8_t *sduP,
- sdu_size_t sdu_lenP,
- const uint8_t *sdu2P,
- sdu_size_t sdu2_lenP);
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, 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 098f957194..a7af049c2a 100644
--- a/openair2/F1AP/f1ap_du_task.c
+++ b/openair2/F1AP/f1ap_du_task.c
@@ -145,7 +145,7 @@ void *F1AP_DU_task(void *arg) {
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(0, 0, 0, msgRrc->crnti, msgRrc->rrc_container, msgRrc->rrc_container_length, msgRrc->du2cu_rrc_container, msgRrc->du2cu_rrc_container_length);
+ DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(myInstance, msgRrc);
} break;
case F1AP_UL_RRC_MESSAGE: // to rrc
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index 05833e3fad..2430b2f870 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -77,21 +77,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
/* GNB_DU_UE_F1AP_ID */
F1AP_UEContextSetupRequestIEs_t *ieDU_UE;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDU_UE, container,
- F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false);
-
- if (ieDU_UE) {
- f1ap_ue_context_setup_req->gNB_DU_ue_id =
- ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID;
- f1ap_ue_context_setup_req->rnti =
- f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_setup_req->gNB_DU_ue_id);
- } else {
- f1ap_ue_context_setup_req->gNB_DU_ue_id = -1;
- f1ap_ue_context_setup_req->rnti =
- f1ap_get_rnti_by_cu_id(DUtype, instance, f1ap_ue_context_setup_req->gNB_CU_ue_id);
- }
-
- if(f1ap_ue_context_setup_req->rnti<0)
- LOG_E(F1AP, "Could not retrieve UE rnti based on the CU/DU UE id \n");
+ F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+ f1ap_ue_context_setup_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID;
/* SpCell_ID */
F1AP_UEContextSetupRequestIEs_t *ieNet;
@@ -247,7 +234,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id;
/* mandatory */
/* c3. DUtoCURRCInformation */
@@ -285,7 +272,8 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup
ie4->criticality = F1AP_Criticality_ignore;
ie4->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI;
//C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI);
- ie4->value.choice.C_RNTI=resp->rnti;
+ ie4->value.choice.C_RNTI=0;
+ AssertFatal(false, "not implemented\n");
LOG_E(F1AP,"RNTI to code!\n");
}
@@ -586,14 +574,14 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, req->rnti);
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = req->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, req->rnti);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = req->gNB_DU_ue_id;
/* mandatory */
/* c3. Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie3);
@@ -654,13 +642,11 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id,
// GNB_CU_UE_F1AP_ID
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
- f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID);
+ f1ap_ue_context_release_cmd->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
// GNB_DU_UE_F1AP_ID
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
- const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance,
- ie->value.choice.GNB_DU_UE_F1AP_ID);
- AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", rnti, f1ap_ue_context_release_cmd->rnti);
+ f1ap_ue_context_release_cmd->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
// We don't need the Cause
// Optional RRC Container: if present, send to UE
@@ -721,14 +707,14 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID;
- ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, complete->rnti);
+ ie1->value.choice.GNB_CU_UE_F1AP_ID = complete->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list,F1AP_UEContextReleaseCompleteIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, complete->rnti);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = complete->gNB_DU_ue_id;
/* optional -> currently not used */
/* c3. CriticalityDiagnostics */
//if (0) {
@@ -790,7 +776,6 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel
buffer,
len,
getCxt(false, instance)->default_sctp_stream_id);
- f1ap_remove_ue(DUtype, instance, complete->rnti);
return 0;
}
@@ -825,12 +810,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDU_UE, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
f1ap_ue_context_modification_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID;
- f1ap_ue_context_modification_req->rnti = f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_modification_req->gNB_DU_ue_id);
-
- if(f1ap_ue_context_modification_req->rnti<0)
- LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n");
- else
- LOG_D(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti);
/* SRB */
F1AP_UEContextModificationRequestIEs_t *ieSrb;
@@ -944,7 +923,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso
ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size);
protocol_ctxt_t ctxt;
// decode RRC Container and act on the message type
- ctxt.rntiMaybeUEid = f1ap_ue_context_modification_req->rnti;
+ ctxt.rntiMaybeUEid = f1ap_ue_context_modification_req->gNB_DU_ue_id;
ctxt.instance = instance;
ctxt.module_id = instance;
ctxt.enb_flag = 1;
@@ -991,7 +970,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
- ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti);
+ ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id;
/* optional */
/* c3. ResourceCoordinationTransferContainer */
@@ -1057,7 +1036,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
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(false, instance)->gtpInst,
- resp->rnti,
+ resp->gNB_DU_ue_id,
drb->drb_id,
drb->drb_id,
drb->up_ul_tnl[j].teid,
diff --git a/openair2/F1AP/f1ap_ids.c b/openair2/F1AP/f1ap_ids.c
new file mode 100644
index 0000000000..e467e074fd
--- /dev/null
+++ b/openair2/F1AP/f1ap_ids.c
@@ -0,0 +1,157 @@
+/*
+ * 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
+ */
+
+/* "standalone" module to store a "secondary" UE ID for each UE in DU/CU.
+ * Separate from the rest of F1, as it is also relevant for monolithic. */
+
+#include "f1ap_ids.h"
+
+#include
+#include "common/utils/hashtable/hashtable.h"
+#include "common/utils/assertions.h"
+
+
+/* we have separate versions for CU and DU, as both CU&DU might coexist in the
+ * same process */
+static hash_table_t *cu2du_ue_mapping;
+static pthread_mutex_t cu2du_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void cu_init_f1_ue_data(void)
+{
+ pthread_mutex_lock(&cu2du_mutex);
+ DevAssert(cu2du_ue_mapping == NULL);
+ cu2du_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free()
+ DevAssert(cu2du_ue_mapping != NULL);
+ pthread_mutex_unlock(&cu2du_mutex);
+}
+
+bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data)
+{
+ pthread_mutex_lock(&cu2du_mutex);
+ DevAssert(cu2du_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ if (hashtable_is_key_exists(cu2du_ue_mapping, key) == HASH_TABLE_OK) {
+ pthread_mutex_unlock(&cu2du_mutex);
+ return false;
+ }
+ f1_ue_data_t *idata = malloc(sizeof(*idata));
+ AssertFatal(idata != NULL, "cannot allocate memory\n");
+ *idata = *data;
+ hashtable_rc_t ret = hashtable_insert(cu2du_ue_mapping, key, idata);
+ pthread_mutex_unlock(&cu2du_mutex);
+ return ret == HASH_TABLE_OK;
+}
+
+bool cu_exists_f1_ue_data(uint32_t ue_id)
+{
+ pthread_mutex_lock(&cu2du_mutex);
+ DevAssert(cu2du_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ hashtable_rc_t ret = hashtable_is_key_exists(cu2du_ue_mapping, key);
+ pthread_mutex_unlock(&cu2du_mutex);
+ return ret == HASH_TABLE_OK;
+}
+
+f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id)
+{
+ pthread_mutex_lock(&cu2du_mutex);
+ DevAssert(cu2du_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ void *data = NULL;
+ hashtable_rc_t ret = hashtable_get(cu2du_ue_mapping, key, &data);
+ AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ue_id);
+ f1_ue_data_t ued = *(f1_ue_data_t *)data;
+ pthread_mutex_unlock(&cu2du_mutex);
+ return ued;
+}
+
+bool cu_remove_f1_ue_data(uint32_t ue_id)
+{
+ pthread_mutex_lock(&cu2du_mutex);
+ DevAssert(cu2du_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ hashtable_rc_t ret = hashtable_remove(cu2du_ue_mapping, key);
+ pthread_mutex_unlock(&cu2du_mutex);
+ return ret == HASH_TABLE_OK;
+}
+
+/* DU version below */
+static hash_table_t *du2cu_ue_mapping;
+static pthread_mutex_t du2cu_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void du_init_f1_ue_data(void)
+{
+ pthread_mutex_lock(&du2cu_mutex);
+ DevAssert(du2cu_ue_mapping == NULL);
+ du2cu_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free()
+ DevAssert(du2cu_ue_mapping != NULL);
+ pthread_mutex_unlock(&du2cu_mutex);
+}
+
+bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data)
+{
+ pthread_mutex_lock(&du2cu_mutex);
+ DevAssert(du2cu_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ if (hashtable_is_key_exists(du2cu_ue_mapping, key) == HASH_TABLE_OK) {
+ pthread_mutex_unlock(&du2cu_mutex);
+ return false;
+ }
+ f1_ue_data_t *idata = malloc(sizeof(*idata));
+ AssertFatal(idata != NULL, "cannot allocate memory\n");
+ *idata = *data;
+ hashtable_rc_t ret = hashtable_insert(du2cu_ue_mapping, key, idata);
+ pthread_mutex_unlock(&du2cu_mutex);
+ return ret == HASH_TABLE_OK;
+}
+
+bool du_exists_f1_ue_data(uint32_t ue_id)
+{
+ pthread_mutex_lock(&du2cu_mutex);
+ DevAssert(du2cu_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ hashtable_rc_t ret = hashtable_is_key_exists(du2cu_ue_mapping, key);
+ pthread_mutex_unlock(&du2cu_mutex);
+ return ret == HASH_TABLE_OK;
+}
+
+f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id)
+{
+ pthread_mutex_lock(&du2cu_mutex);
+ DevAssert(du2cu_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ void *data = NULL;
+ hashtable_rc_t ret = hashtable_get(du2cu_ue_mapping, key, &data);
+ AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ue_id);
+ f1_ue_data_t ued = *(f1_ue_data_t *)data;
+ pthread_mutex_unlock(&du2cu_mutex);
+ return ued;
+}
+
+bool du_remove_f1_ue_data(uint32_t ue_id)
+{
+ pthread_mutex_lock(&du2cu_mutex);
+ DevAssert(du2cu_ue_mapping != NULL);
+ uint64_t key = ue_id;
+ hashtable_rc_t ret = hashtable_remove(du2cu_ue_mapping, key);
+ pthread_mutex_unlock(&du2cu_mutex);
+ return ret == HASH_TABLE_OK;
+}
diff --git a/openair2/F1AP/f1ap_ids.h b/openair2/F1AP/f1ap_ids.h
new file mode 100644
index 0000000000..96b146f6ba
--- /dev/null
+++ b/openair2/F1AP/f1ap_ids.h
@@ -0,0 +1,48 @@
+/*
+ * 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
+ */
+
+/* "standalone" module to store a "secondary" UE ID for each UE in DU/CU.
+ * Separate from the rest of F1, as it is also relevant for monolithic. */
+
+#ifndef F1AP_IDS_H_
+#define F1AP_IDS_H_
+
+#include
+#include
+
+typedef struct f1_ue_data_t {
+ uint32_t secondary_ue;
+ /* can be extended with F1-specific data also relevant for monolithic */
+} f1_ue_data_t;
+
+void cu_init_f1_ue_data(void);
+bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data);
+bool cu_exists_f1_ue_data(uint32_t ue_id);
+f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id);
+bool cu_remove_f1_ue_data(uint32_t ue_id);
+
+void du_init_f1_ue_data(void);
+bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data);
+bool du_exists_f1_ue_data(uint32_t ue_id);
+f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id);
+bool du_remove_f1_ue_data(uint32_t ue_id);
+
+#endif /* F1AP_IDS_H_ */
diff --git a/openair2/F1AP/f1ap_ids_test.c b/openair2/F1AP/f1ap_ids_test.c
new file mode 100644
index 0000000000..3007db566a
--- /dev/null
+++ b/openair2/F1AP/f1ap_ids_test.c
@@ -0,0 +1,42 @@
+/*
+ * 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
+#include
+#include
+#include "common/utils/assertions.h"
+#include "f1ap_ids.h"
+
+int main()
+{
+ du_init_f1_ue_data();
+ int rnti = 13;
+ f1_ue_data_t data = {.secondary_ue = 1};
+ bool ret = du_add_f1_ue_data(rnti, &data);
+ DevAssert(ret);
+ ret = du_add_f1_ue_data(rnti, &data);
+ DevAssert(!ret);
+ bool exists = du_exists_f1_ue_data(rnti);
+ DevAssert(exists);
+ f1_ue_data_t rdata = du_get_f1_ue_data(rnti);
+ DevAssert(rdata.secondary_ue == data.secondary_ue);
+ return 0;
+}
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index e7b6259284..0067c546ba 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -3635,7 +3635,7 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec
int tdd_period_to_num[8] = {500,625,1000,1250,2000,2500,5000,10000};
-bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slot)
+bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot)
{
if (tdd_UL_DL_ConfigurationCommon == NULL)
return true;
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index 8798213b4c..da26cae863 100644
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -39,21 +39,19 @@
#include "executables/softmodem-common.h"
#include "SCHED_NR/phy_frame_config_nr.h"
-void set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
+void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
int mu,
- NR_TDD_UL_DL_ConfigCommon_t *tdd_config) {
+ NR_TDD_UL_DL_Pattern_t *pattern)
+{
+ const int nrofDownlinkSlots = pattern->nrofDownlinkSlots;
+ const int nrofDownlinkSymbols = pattern->nrofDownlinkSymbols;
+ const int nrofUplinkSlots = pattern->nrofUplinkSlots;
+ const int nrofUplinkSymbols = pattern->nrofUplinkSymbols;
+ const int nb_periods_per_frame = get_nb_periods_per_frame(pattern->dl_UL_TransmissionPeriodicity);
+ const int nb_slots_per_period = ((1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) / nb_periods_per_frame;
+ tdd_table->tdd_period_in_slots = nb_slots_per_period;
- const int nrofDownlinkSlots = tdd_config->pattern1.nrofDownlinkSlots;
- const int nrofDownlinkSymbols = tdd_config->pattern1.nrofDownlinkSymbols;
- const int nrofUplinkSlots = tdd_config->pattern1.nrofUplinkSlots;
- const int nrofUplinkSymbols = tdd_config->pattern1.nrofUplinkSymbols;
- int slot_number = 0;
- const int nb_periods_per_frame = get_nb_periods_per_frame(tdd_config->pattern1.dl_UL_TransmissionPeriodicity);
- const int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(1<tdd_table.tdd_period_in_slots = nb_slots_per_period;
-
- if ( (nrofDownlinkSymbols + nrofUplinkSymbols) == 0 )
+ if ((nrofDownlinkSymbols + nrofUplinkSymbols) == 0)
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots),
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nb_slots_per_period %d \n",
nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period);
@@ -64,57 +62,43 @@ void set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period);
}
- cfg->tdd_table.max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_to_set*sizeof(fapi_nr_max_tdd_periodicity_t));
+ tdd_table->max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_per_period * sizeof(fapi_nr_max_tdd_periodicity_t));
- for(int memory_alloc =0 ; memory_alloctdd_table.max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list = (fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof(
- fapi_nr_max_num_of_symbol_per_slot_t));
+ for(int memory_alloc = 0 ; memory_alloc < nb_slots_per_period; memory_alloc++)
+ tdd_table->max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list =
+ (fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof(fapi_nr_max_num_of_symbol_per_slot_t));
- while(slot_number != nb_slots_to_set) {
+ int slot_number = 0;
+ while(slot_number != nb_slots_per_period) {
if(nrofDownlinkSlots != 0) {
- for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
- cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config= 0;
-
- if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
+ for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
+ tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 0;
+ if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
slot_number++;
}
}
if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) {
- for(int number_of_symbol =0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) {
- cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 0;
+ for(int number_of_symbol = 0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) {
+ tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 0;
}
-
- for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol++) {
- cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 2;
+ for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol++) {
+ tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 2;
}
-
- for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
- cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 1;
+ for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
+ tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 1;
}
-
slot_number++;
}
if(nrofUplinkSlots != 0) {
- for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
- cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config= 1;
-
- if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
+ for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
+ tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 1;
+ if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
slot_number++;
}
}
}
-
- if (tdd_config->pattern1.ext1 == NULL) {
- cfg->tdd_table.tdd_period = tdd_config->pattern1.dl_UL_TransmissionPeriodicity;
- } else {
- AssertFatal(tdd_config->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL, "scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
- cfg->tdd_table.tdd_period = *tdd_config->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
- }
-
- LOG_I(NR_MAC, "TDD has been properly configured\n");
-
}
void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
@@ -204,9 +188,15 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
// TDD Table Configuration
if (cfg->cell_config.frame_duplex_type == TDD){
- set_tdd_config_nr_ue(cfg,
+ set_tdd_config_nr_ue(&cfg->tdd_table_1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
- mac->tdd_UL_DL_ConfigurationCommon);
+ &mac->tdd_UL_DL_ConfigurationCommon->pattern1);
+ if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) {
+ cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t));
+ set_tdd_config_nr_ue(cfg->tdd_table_2,
+ frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+ mac->tdd_UL_DL_ConfigurationCommon->pattern2);
+ }
}
// PRACH configuration
@@ -375,9 +365,15 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
// TDD Table Configuration
if (cfg->cell_config.frame_duplex_type == TDD){
- set_tdd_config_nr_ue(cfg,
+ set_tdd_config_nr_ue(&cfg->tdd_table_1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
- mac->tdd_UL_DL_ConfigurationCommon);
+ &mac->tdd_UL_DL_ConfigurationCommon->pattern1);
+ if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) {
+ cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t));
+ set_tdd_config_nr_ue(cfg->tdd_table_2,
+ frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+ mac->tdd_UL_DL_ConfigurationCommon->pattern2);
+ }
}
// PRACH configuration
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 5534e586b1..2259ae7cf1 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -246,10 +246,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
uint8_t *ulsch_buffer,
uint16_t buflen);
-void set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
- int mu,
- NR_TDD_UL_DL_ConfigCommon_t *tdd_config);
-
void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index 8899be18e6..3d980dd217 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -79,7 +79,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
// set up PDCP, RLC, MAC
nr_pdcp_layer_init();
- nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list);
+ nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list);
nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
nr_ue_mac_inst->logicalChannelBearer_exist[0] = true;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index e0c5879e9c..165251e9f4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -2083,7 +2083,7 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
// Pause scheduling according to:
// 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs
- const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL;
+ const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup && UE->CellGroup->spCellConfig ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL;
uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ?
NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 68a44fa0cf..81ea2edcb7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -47,6 +47,7 @@
#include "RRC/NR/MESSAGES/asn1_msg.h"
#include "intertask_interface.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "T.h"
@@ -1992,22 +1993,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
destroy_nr_list(&sched_ctrl->retrans_ul_harq);
uid_linear_allocator_free(uia, UE->uid);
LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti);
- const rnti_t rnti = UE->rnti;
free(UE);
-
- /* clear RA process(es?) associated to the UE */
- for (int cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
- for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
- NR_COMMON_channels_t *cc = &ccPtr[cc_id];
- if (cc->ra[i].rnti == rnti) {
- LOG_D(NR_MAC, "free RA process %d for rnti %04x\n", i, rnti);
- /* is it enough? */
- cc->ra[i].cfra = false;
- cc->ra[i].rnti = 0;
- cc->ra[i].crnti = 0;
- }
- }
- }
}
@@ -2922,6 +2908,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu
const f1ap_initial_ul_rrc_message_t ul_rrc_msg = {
/* TODO: add mcc, mnc, cell_id, ..., is not available at MAC yet */
+ .gNB_DU_ue_id = rnti,
.crnti = rnti,
.rrc_container = (uint8_t *) sdu,
.rrc_container_length = sdu_len,
@@ -2997,8 +2984,10 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct
/* to trigger only once: trigger when ul_failure_timer == 1, but timer will
* stop at 0 and we wait for a UE release command from upper layers */
if (sched_ctrl->ul_failure_timer == 1) {
+ f1_ue_data_t ue_data = du_get_f1_ue_data(rnti);
f1ap_ue_context_release_complete_t complete = {
- .rnti = rnti,
+ .gNB_CU_ue_id = ue_data.secondary_ue,
+ .gNB_DU_ue_id = rnti,
.cause = F1AP_CAUSE_RADIO_NETWORK,
.cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others
};
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
index 582420a0b4..0a450a1198 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
@@ -22,6 +22,7 @@
#include "mac_rrc_dl_handler.h"
#include "mac_proto.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
@@ -100,7 +101,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
f1ap_ue_context_setup_t resp = {
.gNB_CU_ue_id = req->gNB_CU_ue_id,
.gNB_DU_ue_id = req->gNB_DU_ue_id,
- .rnti = req->rnti,
};
if (req->cu_to_du_rrc_information != NULL) {
@@ -111,11 +111,11 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
NR_SCHED_LOCK(&mac->sched_lock);
- NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti);
- AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti);
+ NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id);
+ AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->gNB_DU_ue_id);
if (req->srbs_to_be_setup_length > 0) {
- resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti,
+ resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id,
req->srbs_to_be_setup_length,
req->srbs_to_be_setup,
&resp.srbs_to_be_setup,
@@ -123,7 +123,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
}
if (req->drbs_to_be_setup_length > 0) {
- resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti,
+ resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id,
req->drbs_to_be_setup_length,
req->drbs_to_be_setup,
&resp.drbs_to_be_setup,
@@ -131,7 +131,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
}
if (req->rrc_container != NULL)
- nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length);
+ nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length);
//nr_mac_update_cellgroup()
resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t));
@@ -171,7 +171,6 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
f1ap_ue_context_modif_resp_t resp = {
.gNB_CU_ue_id = req->gNB_CU_ue_id,
.gNB_DU_ue_id = req->gNB_DU_ue_id,
- .rnti = req->rnti,
};
if (req->cu_to_du_rrc_information != NULL) {
@@ -181,10 +180,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
}
NR_SCHED_LOCK(&mac->sched_lock);
- NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti);
+ NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id);
if (req->srbs_to_be_setup_length > 0) {
- resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti,
+ resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id,
req->srbs_to_be_setup_length,
req->srbs_to_be_setup,
&resp.srbs_to_be_setup,
@@ -192,7 +191,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
}
if (req->drbs_to_be_setup_length > 0) {
- resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti,
+ resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id,
req->drbs_to_be_setup_length,
req->drbs_to_be_setup,
&resp.drbs_to_be_setup,
@@ -200,7 +199,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
}
if (req->rrc_container != NULL)
- nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length);
+ nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length);
if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) {
LOG_E(NR_MAC,
@@ -224,7 +223,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
/* works? */
- nr_mac_update_cellgroup(RC.nrmac[0], req->rnti, UE->CellGroup);
+ nr_mac_update_cellgroup(RC.nrmac[0], req->gNB_DU_ue_id, UE->CellGroup);
}
NR_SCHED_UNLOCK(&mac->sched_lock);
@@ -249,32 +248,100 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
/* mark UE as to be deleted after PUSCH failure */
gNB_MAC_INST *mac = RC.nrmac[0];
pthread_mutex_lock(&mac->sched_lock);
- NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti);
+ NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->gNB_DU_ue_id);
if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) {
/* The UE is already not connected anymore or we have nothing to forward*/
- nr_rlc_remove_ue(cmd->rnti);
- mac_remove_nr_ue(mac, cmd->rnti);
+ nr_rlc_remove_ue(cmd->gNB_DU_ue_id);
+ mac_remove_nr_ue(mac, cmd->gNB_DU_ue_id);
} else {
/* UE is in sync: forward release message and mark to be deleted
* after UL failure */
- nr_rlc_srb_recv_sdu(cmd->rnti, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length);
+ nr_rlc_srb_recv_sdu(cmd->gNB_DU_ue_id, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length);
nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
}
pthread_mutex_unlock(&mac->sched_lock);
f1ap_ue_context_release_complete_t complete = {
- .rnti = cmd->rnti,
+ .gNB_CU_ue_id = cmd->gNB_CU_ue_id,
+ .gNB_DU_ue_id = cmd->gNB_DU_ue_id,
};
mac->mac_rrc.ue_context_release_complete(&complete);
- if (cmd->rrc_container)
- free(cmd->rrc_container);
+ du_remove_f1_ue_data(cmd->gNB_DU_ue_id);
}
-int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc)
+void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
{
- LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id);
+ LOG_D(NR_MAC,
+ "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n",
+ dl_rrc->rrc_container_length,
+ dl_rrc->gNB_DU_ue_id,
+ dl_rrc->srb_id);
- nr_rlc_srb_recv_sdu(dl_rrc->rnti, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length);
- return 0;
+ gNB_MAC_INST *mac = RC.nrmac[0];
+ pthread_mutex_lock(&mac->sched_lock);
+ /* check first that the scheduler knows such UE */
+ NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, dl_rrc->gNB_DU_ue_id);
+ if (UE == NULL) {
+ LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring DL RRC Message Transfer\n", dl_rrc->gNB_DU_ue_id);
+ pthread_mutex_unlock(&mac->sched_lock);
+ return;
+ }
+ pthread_mutex_unlock(&mac->sched_lock);
+
+ if (!du_exists_f1_ue_data(dl_rrc->gNB_DU_ue_id)) {
+ LOG_I(NR_MAC, "No CU UE ID stored for UE RNTI %04x, adding CU UE ID %d\n", dl_rrc->gNB_DU_ue_id, dl_rrc->gNB_CU_ue_id);
+ f1_ue_data_t new_ue_data = {.secondary_ue = dl_rrc->gNB_CU_ue_id};
+ du_add_f1_ue_data(dl_rrc->gNB_DU_ue_id, &new_ue_data);
+ }
+
+ if (UE->expect_reconfiguration && dl_rrc->srb_id == DCCH) {
+ /* we expected a reconfiguration, and this is on DCCH. We assume this is
+ * the reconfiguration; nr_mac_update_cellgroup() brings the config into
+ * the form expected by nr_mac_update_timers(), and we set the timer to
+ * apply the real configuration at expiration.
+ * Calling it nr_mac_update_cellgroup() is misleading, and using an
+ * intermediate buffer seems not necessary. This is for historical reasons,
+ * when we only had pointer to an RRC structure, and wanted to duplicate
+ * the contents to be applied later. The actually interesting function here
+ * is also configure_UE_BWP(), only called in nr_mac_update_timers().
+ * TODO: This should be cleaned up when the whole CellGroupConfig is
+ * handled entirely at the DU: no intermediate buffer, trigger the timer
+ * from a function (there is nr_mac_enable_ue_rrc_processing_timer(), which
+ * is called from the RRC, hence locks the scheduler, which we cannot use). */
+ LOG_I(NR_MAC, "triggering rrc_processing_timer time UE %04x\n", UE->rnti);
+ pthread_mutex_lock(&mac->sched_lock);
+ nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->reconfigCellGroup);
+ pthread_mutex_unlock(&mac->sched_lock);
+ const uint16_t sl_ahead = mac->if_inst->sl_ahead;
+ NR_SubcarrierSpacing_t scs = 1;
+ int delay = 10;
+ UE->UE_sched_ctrl.rrc_processing_timer = (delay << scs) + sl_ahead;
+ }
+
+ if (dl_rrc->old_gNB_DU_ue_id != NULL) {
+ AssertFatal(*dl_rrc->old_gNB_DU_ue_id != dl_rrc->gNB_DU_ue_id,
+ "logic bug: current and old gNB DU UE ID cannot be the same\n");
+ /* 38.401 says: "Find UE context based on old gNB-DU UE F1AP ID, replace
+ * old C-RNTI/PCI with new C-RNTI/PCI". So we delete the new contexts
+ * below, then change the C-RNTI of the old one to the new one */
+ NR_UE_info_t *oldUE = find_nr_UE(&mac->UE_info, *dl_rrc->old_gNB_DU_ue_id);
+ DevAssert(oldUE);
+ pthread_mutex_lock(&mac->sched_lock);
+ /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it
+ * from the current configuration. Also, expect the reconfiguration from
+ * the CU, so save the old UE's CellGroup for the new UE */
+ UE->CellGroup->spCellConfig = NULL;
+ nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->CellGroup);
+ UE->reconfigCellGroup = oldUE->CellGroup;
+ UE->expect_reconfiguration = true;
+ oldUE->CellGroup = NULL;
+ mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id);
+ pthread_mutex_unlock(&mac->sched_lock);
+ nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id);
+ nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
+ }
+
+ /* the DU ue id is the RNTI */
+ nr_rlc_srb_recv_sdu(dl_rrc->gNB_DU_ue_id, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
index 808277a7f4..859e128b4a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
@@ -29,6 +29,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req);
void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req);
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd);
-int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
+void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc);
#endif /* MAC_RRC_DL_HANDLER_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 6780fad873..a024abe6af 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
@@ -64,7 +64,6 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_
f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id;
f1ap_msg->gNB_DU_ue_id = resp->gNB_DU_ue_id;
- f1ap_msg->rnti = resp->rnti;
f1ap_msg->mcc = resp->mcc;
f1ap_msg->mnc = resp->mnc;
f1ap_msg->mnc_digit_length = resp->mnc_digit_length;
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
index f122a13c34..644decc21c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
@@ -106,7 +106,7 @@ static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t*
static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_complete_t *complete)
{
- newGtpuDeleteAllTunnels(0, complete->rnti);
+ newGtpuDeleteAllTunnels(0, complete->gNB_DU_ue_id);
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE);
f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg);
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index cdba0b676b..7fd559fdcd 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -40,6 +40,7 @@
#include "nr_rlc/nr_rlc_oai_api.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
//#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "common/ran_context.h"
#include "executables/softmodem-common.h"
@@ -283,7 +284,7 @@ void mac_top_init_gNB(ngran_node_t node_type)
* will output the packets at a local interface, which is in line with
* the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */
// setup PDCP, RLC
- nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list);
+ nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list);
nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
// free memory
@@ -301,5 +302,7 @@ void mac_top_init_gNB(ngran_node_t node_type)
memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info));
}
+ du_init_f1_ue_data();
+
srand48(0);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 4e30c74a5c..457497679a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -46,19 +46,19 @@
#define NR_SCHED_LOCK(lock) \
do { \
int rc = pthread_mutex_lock(lock); \
- AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \
+ AssertFatal(rc == 0, "error while locking scheduler mutex, pthread_mutex_lock() returned %d\n", rc); \
} while (0)
#define NR_SCHED_UNLOCK(lock) \
do { \
int rc = pthread_mutex_unlock(lock); \
- AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \
+ AssertFatal(rc == 0, "error while locking scheduler mutex, pthread_mutex_unlock() returned %d\n", rc); \
} while (0)
#define NR_SCHED_ENSURE_LOCKED(lock)\
do {\
int rc = pthread_mutex_trylock(lock); \
- AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked\n");\
+ AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked, pthread_mutex_trylock() returned %d\n", rc);\
} while (0)
/* Commmon */
@@ -675,7 +675,11 @@ typedef struct {
NR_UE_DL_BWP_t current_DL_BWP;
NR_UE_UL_BWP_t current_UL_BWP;
NR_mac_stats_t mac_stats;
+ /// currently active CellGroupConfig
NR_CellGroupConfig_t *CellGroup;
+ /// CellGroupConfig that is to be activated after the next reconfiguration
+ NR_CellGroupConfig_t *reconfigCellGroup;
+ bool expect_reconfiguration;
char cg_buf[32768]; /* arbitrary size */
asn_enc_rval_t enc_rval;
// UE selected beam index
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c
index d56c22f609..97370c5964 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c
@@ -32,7 +32,7 @@ void e1_add_drb(int is_gnb,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{
- add_drb_am(is_gnb, ue_id, 0, s, ciphering_algorithm, integrity_algorithm,
+ add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm,
ciphering_key, integrity_key);
LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id);
}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h
index f45f3f0458..3c16996126 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h
@@ -45,7 +45,7 @@ void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag,
uint8_t *const kUPenc,
uint8_t *const kUPint);
-void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s,
+void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 7a798d7b81..be22753026 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -36,6 +36,7 @@
#include "oai_asn1.h"
#include "nr_pdcp_oai_api.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
#include "nr_pdcp_e1_api.h"
@@ -632,7 +633,9 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) {
LOG_D(PDCP, "IP packet received with size %d, to be sent to SDAP interface, UE ID/RNTI: %ld\n", size, ue->rntiMaybeUEid);
- sdap_data_ind(entity->rb_id, entity->is_gnb, entity->has_sdap_rx, entity->pdusession_id, ue->rntiMaybeUEid, buf, size);
+ // in NoS1 mode: the SDAP should write() packets to an FD (TUN interface),
+ // so below, set is_gnb == 0 to do that
+ sdap_data_ind(entity->rb_id, 0, entity->has_sdap_rx, entity->pdusession_id, ue->rntiMaybeUEid, buf, size);
}
else{
for (i = 0; i < MAX_DRBS_PER_UE; i++) {
@@ -653,11 +656,24 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
}
}
-static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
- char *buf, int size, int sdu_id)
+static void deliver_pdu_drb_ue(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
+ char *buf, int size, int sdu_id)
{
DevAssert(deliver_pdu_data == NULL);
- protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id };
+ protocol_ctxt_t ctxt = { .enb_flag = 0, .rntiMaybeUEid = ue_id };
+
+ mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__);
+ memcpy(memblock->data, buf, size);
+ LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d UE %ld/%04lx\n", __func__, rb_id, size, ctxt.rntiMaybeUEid, ctxt.rntiMaybeUEid);
+ enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock);
+}
+
+static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
+ char *buf, int size, int sdu_id)
+{
+ DevAssert(deliver_pdu_data == NULL);
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id);
+ protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_data.secondary_ue };
if (NODE_IS_CU(node_type)) {
MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
@@ -668,12 +684,11 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
AssertFatal(message_p != NULL, "OUT OF MEMORY");
gtpv1u_tunnel_data_req_t *req=>PV1U_TUNNEL_DATA_REQ(message_p);
uint8_t *gtpu_buffer_p = (uint8_t*)(req+1);
- memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX,
- buf, size);
+ memcpy(gtpu_buffer_p + GTPU_HEADER_OVERHEAD_MAX, buf, size);
req->buffer = gtpu_buffer_p;
req->length = size;
req->offset = GTPU_HEADER_OVERHEAD_MAX;
- req->ue_id = ue_id;
+ req->ue_id = ue_id; // use CU UE ID as GTP will use that to look up TEID
req->bearer_id = rb_id;
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size);
extern instance_t CUuniqInstance;
@@ -682,8 +697,6 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__);
memcpy(memblock->data, buf, size);
LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
- //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
- //printf("\n");
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock);
}
}
@@ -710,7 +723,11 @@ srb_found:
MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_GNB, 0, F1AP_UL_RRC_MESSAGE);
AssertFatal(message_p != NULL, "OUT OF MEMORY\n");
f1ap_ul_rrc_message_t *ul_rrc = &F1AP_UL_RRC_MESSAGE(message_p);
- ul_rrc->rnti = ue->rntiMaybeUEid;
+ ul_rrc->gNB_CU_ue_id = ue->rntiMaybeUEid;
+ /* look up the correct secondary UE ID to provide complete information to
+ * RRC, the RLC-PDCP interface does not transport this information */
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rntiMaybeUEid);
+ ul_rrc->gNB_DU_ue_id = ue_data.secondary_ue;
ul_rrc->srb_id = srb_id;
ul_rrc->rrc_container = malloc(size);
AssertFatal(ul_rrc->rrc_container != NULL, "OUT OF MEMORY\n");
@@ -740,19 +757,6 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock);
}
-void deliver_pdu_srb_f1(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
- char *buf, int size, int sdu_id)
-{
- DevAssert(deliver_pdu_data != NULL);
- gNB_RRC_INST *rrc = deliver_pdu_data;
- f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF,
- .rrc_container = (uint8_t *)buf,
- .rrc_container_length = size,
- .rnti = ue_id,
- .srb_id = srb_id};
- rrc->mac_rrc.dl_rrc_message_transfer(0, &dl_rrc);
-}
-
static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key)
{
nr_pdcp_entity_t *pdcp_srb;
@@ -784,7 +788,7 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
-void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key)
+void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key)
{
nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue;
@@ -860,8 +864,10 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st
LOG_W(PDCP, "%s:%d:%s: warning DRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid);
} else {
pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id,
- has_sdap_rx, has_sdap_tx,
- deliver_sdu_drb, ue, deliver_pdu_drb, ue,
+ has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue,
+ is_gnb ?
+ deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
+ ue,
sn_size_dl, t_reordering, discard_timer,
has_ciphering ? ciphering_algorithm : 0,
has_integrity ? integrity_algorithm : 0,
@@ -869,14 +875,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st
has_integrity ? integrity_key : NULL);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
- if (reestablish_ue_id > 0) {
- nr_pdcp_ue_t *reestablish_ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, reestablish_ue_id);
- if (reestablish_ue != NULL) {
- pdcp_drb->tx_next = reestablish_ue->drb[drb_id - 1]->tx_next;
- LOG_I(PDCP, "Applying tx_next %d in DRB %d from old UEid %lx to new UEid %lx\n", reestablish_ue->drb[drb_id - 1]->tx_next, drb_id, reestablish_ue_id, rntiMaybeUEid);
- }
- }
-
LOG_D(PDCP, "%s:%d:%s: added drb %d to UE ID/RNTI %ld\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid);
new_nr_sdap_entity(is_gnb, has_sdap_rx, has_sdap_tx, rntiMaybeUEid, pdusession_id, is_sdap_DefaultDRB, drb_id, mappedQFIs2Add, mappedQFIs2AddCount);
@@ -886,7 +884,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st
static void add_drb(int is_gnb,
ue_id_t rntiMaybeUEid,
- ue_id_t reestablish_ue_id,
struct NR_DRB_ToAddMod *s,
NR_RLC_Config_t *rlc_Config,
int ciphering_algorithm,
@@ -896,12 +893,12 @@ static void add_drb(int is_gnb,
{
switch (rlc_Config->present) {
case NR_RLC_Config_PR_am:
- add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
+ add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
break;
case NR_RLC_Config_PR_um_Bi_Directional:
// add_drb_um(rntiMaybeUEid, s);
/* hack */
- add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
+ add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
break;
default:
LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
@@ -923,7 +920,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t rntiMaybeUEid,
- ue_id_t reestablish_ue_id,
NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP,
uint8_t *const kUPenc,
@@ -932,7 +928,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
{
if (drb2add_list != NULL) {
for (int i = 0; i < drb2add_list->list.count; i++) {
- add_drb(enb_flag, rntiMaybeUEid, reestablish_ue_id, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint);
+ add_drb(enb_flag, rntiMaybeUEid, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint);
}
} else
LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n");
@@ -1065,6 +1061,39 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id,
return 1;
}
+void nr_pdcp_reestablishment(ue_id_t ue_id)
+{
+ // TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+ nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
+ if (ue == NULL) {
+ LOG_E(PDCP, "Cannot find PDCP entity for UE %lx\n", ue_id);
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+ return;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ nr_pdcp_entity_t *srb = ue->srb[i];
+ if (srb != NULL) {
+ srb->tx_next = 0;
+ srb->rx_next = 0;
+ srb->rx_deliv = 0;
+ srb->rx_reord = 0;
+ }
+ }
+
+ for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
+ nr_pdcp_entity_t *drb = ue->drb[i];
+ if (drb != NULL) {
+ // drb->tx_next = 0; // Should continue from the previous value
+ drb->rx_next = 0;
+ //drb->rx_deliv = 0; // should continue from the previous value
+ drb->rx_reord = 0;
+ }
+ }
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+}
+
bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h
index 0fd23d2f6b..f00ab98422 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h
@@ -48,7 +48,6 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t rntiMaybeUEid,
- ue_id_t reestablish_ue_id,
NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP,
uint8_t *const kUPenc,
@@ -58,6 +57,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid);
bool nr_pdcp_remove_UE(ue_id_t ue_id);
+void nr_pdcp_reestablishment(ue_id_t ue_id);
void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id,
@@ -80,10 +80,7 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP,
typedef void (*deliver_pdu)(void *data, ue_id_t ue_id, int srb_id,
char *buf, int size, int sdu_id);
/* default implementation of deliver_pdu */
-void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf,
- int size, int sdu_id);
-void deliver_pdu_srb_f1(void *data, ue_id_t ue_id, int srb_id, char *buf,
- int size, int sdu_id);
+void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id);
bool nr_pdcp_data_req_srb(ue_id_t ue_id,
const rb_id_t rb_id,
const mui_t muiP,
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index f4097d721b..7d17829e4f 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -39,6 +39,7 @@
#include "NR_UL-CCCH-Message.h"
#include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
+#include "openair2/F1AP/f1ap_ids.h"
extern RAN_CONTEXT_t RC;
@@ -425,11 +426,18 @@ rb_found:
ctx.eNB_index = 0;
ctx.brOption = 0;
+ is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager);
+
/* used fields? */
ctx.module_id = 0;
+ /* CU (PDCP, RRC, SDAP) use a different ID than RNTI, so below set the CU UE
+ * ID if in gNB, else use RNTI normally */
ctx.rntiMaybeUEid = ue->rnti;
+ if (is_enb) {
+ f1_ue_data_t ue_data = du_get_f1_ue_data(ue->rnti);
+ ctx.rntiMaybeUEid = ue_data.secondary_ue;
+ }
- is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager);
ctx.enb_flag = is_enb;
if (is_enb) {
@@ -453,7 +461,8 @@ rb_found:
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size);
memcpy (message_buffer, buf, size);
- F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
+ F1AP_UL_RRC_MESSAGE(msg).gNB_CU_ue_id = ctx.rntiMaybeUEid;
+ F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti;
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer;
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
@@ -467,7 +476,7 @@ rb_found:
memcpy(req->buffer,buf,size);
req->length=size;
req->offset=0;
- req->ue_id=ue->rnti;
+ req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID
req->bearer_id=rb_id;
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
extern instance_t DUuniqInstance;
@@ -477,6 +486,7 @@ rb_found:
}
}
+ /* UE or monolithic gNB */
memblock = get_free_mem_block(size, __func__);
if (memblock == NULL) {
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
@@ -1000,6 +1010,45 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
return RLC_OP_STATUS_OK;
}
+bool nr_rlc_update_rnti(int from_rnti, int to_rnti)
+{
+ nr_rlc_manager_lock(nr_rlc_ue_manager);
+ nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_rnti);
+ if (ue == NULL) {
+ nr_rlc_manager_unlock(nr_rlc_ue_manager);
+ LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", from_rnti);
+ return false;
+ }
+ ue->rnti = to_rnti;
+ LOG_I(RLC, "Update old UE RNTI %04x context to RNTI %04x\n", from_rnti, to_rnti);
+ for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i)
+ if (ue->srb[i])
+ ue->srb[i]->reestablishment(ue->srb[i]);
+ for (int i = 0; i < sizeof(ue->drb) / sizeof(ue->drb[0]); ++i)
+ if (ue->drb[i])
+ ue->drb[i]->reestablishment(ue->drb[i]);
+ nr_rlc_manager_unlock(nr_rlc_ue_manager);
+ return true;
+}
+
+/* This function is for testing purposes. At least on a COTS UE, it will
+ * trigger a reestablishment. */
+void nr_rlc_test_trigger_reestablishment(int rnti)
+{
+ nr_rlc_manager_lock(nr_rlc_ue_manager);
+ nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
+ if (ue == NULL) {
+ nr_rlc_manager_unlock(nr_rlc_ue_manager);
+ LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", rnti);
+ return;
+ }
+ /* we simply assume the SRB exists, because the scheduler creates it as soon
+ * as the UE context is created. */
+ nr_rlc_entity_t *ent = ue->srb[0];
+ ent->reestablishment(ent);
+ nr_rlc_manager_unlock(nr_rlc_ue_manager);
+}
+
void nr_rlc_tick(int frame, int subframe)
{
if (frame != nr_rlc_current_time_last_frame ||
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
index 3b4bce7176..15fe286435 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
@@ -43,6 +43,10 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
void nr_rlc_remove_ue(int rnti);
+bool nr_rlc_update_rnti(int from_rnti, int to_rnti);
+
+/* test function for CI to trigger reestablishments */
+void nr_rlc_test_trigger_reestablishment(int rnti);
int nr_rlc_get_available_tx_space(
const rnti_t rntiP,
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 0f524a0241..3334842616 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -52,16 +52,6 @@
extern RAN_CONTEXT_t RC;
-void nr_rrc_mac_remove_ue(rnti_t rntiMaybeUEid)
-{
- nr_rlc_remove_ue(rntiMaybeUEid);
-
- gNB_MAC_INST *nrmac = RC.nrmac[0];
- NR_SCHED_LOCK(&nrmac->sched_lock);
- mac_remove_nr_ue(nrmac, rntiMaybeUEid);
- NR_SCHED_UNLOCK(&nrmac->sched_lock);
-}
-
void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc)
{
gNB_MAC_INST *nrmac = RC.nrmac[0];
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 75446708a9..3935c18bfe 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -783,7 +783,7 @@ int16_t do_RRCReconfiguration(
}
if(cellGroupConfig!=NULL){
- update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration);
+ update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.rrc_ue_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
NULL,
@@ -1100,8 +1100,7 @@ uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c
}
//------------------------------------------------------------------------------
-int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP,
- rrc_gNB_ue_context_t *const ue_context_pP,
+int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP,
int CC_id,
uint8_t *const buffer,
size_t buffer_size,
@@ -1126,7 +1125,8 @@ int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP,
rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_IEs_t));
- uint16_t pci = RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId;
+ int module_id = 0;
+ uint16_t pci = RC.nrrrc[module_id]->carrier.physCellId;
uint32_t nr_arfcn_dl = (uint64_t)*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB;
LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", pci, nr_arfcn_dl);
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 27782d8a97..5e9a9fa756 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -172,8 +172,7 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer,
uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti);
-int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP,
- rrc_gNB_ue_context_t *const ue_context_pP,
+int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP,
int CC_id,
uint8_t *const buffer,
size_t buffer_size,
diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c
index 9c4e6462a4..9dccef4286 100644
--- a/openair2/RRC/NR/cucp_cuup_direct.c
+++ b/openair2/RRC/NR/cucp_cuup_direct.c
@@ -61,7 +61,7 @@ void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp,
drbSetup->numUpParam = 1;
drbSetup->UpParamList[0].tlAddress = my_addr;
drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst,
- (ue_id & 0xFFFF),
+ ue_id,
drb2Setup->id,
drb2Setup->id,
0xFFFF, // We will set the right value from DU answer
@@ -117,7 +117,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid;
}
create_tunnel_req.num_tunnels = UE->nb_of_pdusessions;
- create_tunnel_req.ue_id = UE->rnti;
+ create_tunnel_req.ue_id = UE->rrc_ue_id;
int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3,
&create_tunnel_req,
&create_tunnel_resp,
@@ -150,8 +150,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti);
nr_pdcp_add_drbs(ctxt_p->enb_flag,
- ctxt_p->rntiMaybeUEid,
- 0,
+ UE->rrc_ue_id,
DRB_configList,
(UE->integrity_algorithm << 4) | UE->ciphering_algorithm,
kUPenc,
@@ -163,10 +162,10 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance)
{
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_cu_cp_ue_id);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
protocol_ctxt_t ctxt = {0};
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0, 0);
e1ap_bearer_setup_resp_t resp = {0};
resp.numPDUSessions = req->numPDUSessions;
@@ -198,7 +197,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const
in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
// GTP tunnel for DL
- fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr);
+ fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rrc_ue_id, remote_port, my_addr);
}
// actually, we should receive the corresponding context setup response
// message at the RRC and always react to this one. So in the following, we
@@ -212,7 +211,7 @@ static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const r
if (!NODE_IS_CU(RC.nrrrc[0]->node_type))
return;
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
- CU_update_UP_DL_tunnel(req, gtpInst, req->rnti);
+ CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id);
}
void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) {
diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h
index 2728174603..94920f6f64 100644
--- a/openair2/RRC/NR/mac_rrc_dl.h
+++ b/openair2/RRC/NR/mac_rrc_dl.h
@@ -29,7 +29,7 @@ typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *r
typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req);
typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd);
-typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
+typedef void (*dl_rrc_message_transfer_func_t)(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 2d436c19e3..eeec72e132 100644
--- a/openair2/RRC/NR/mac_rrc_dl_direct.c
+++ b/openair2/RRC/NR/mac_rrc_dl_direct.c
@@ -24,17 +24,10 @@
#include "mac_rrc_dl.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
-static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc)
-{
- /* TODO how to manage inter-thread communication? */
-
- dl_rrc_message(module_id, dl_rrc);
-}
-
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc->ue_context_setup_request = ue_context_setup_request;
mac_rrc->ue_context_modification_request = ue_context_modification_request;
mac_rrc->ue_context_release_command = ue_context_release_command;
- mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct;
+ mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer;
}
diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c
index 5bfeda2dc8..3f3b0f800f 100644
--- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c
+++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c
@@ -76,23 +76,34 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p);
*msg = *cmd;
+ if (cmd->rrc_container_length > 0) {
+ msg->rrc_container = calloc(cmd->rrc_container_length, sizeof(*msg->rrc_container));
+ AssertFatal(msg->rrc_container != NULL, "out of memory\n");
+ msg->rrc_container_length = cmd->rrc_container_length;
+ memcpy(msg->rrc_container, cmd->rrc_container, cmd->rrc_container_length);
+ }
itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
}
-static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc)
+static void dl_rrc_message_transfer_f1ap(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);
f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p);
*msg = *dl_rrc;
+ if (dl_rrc->old_gNB_DU_ue_id) {
+ msg->old_gNB_DU_ue_id = malloc(sizeof(*msg->old_gNB_DU_ue_id));
+ AssertFatal(msg->old_gNB_DU_ue_id != NULL, "out of memory\n");
+ *msg->old_gNB_DU_ue_id = *dl_rrc->old_gNB_DU_ue_id;
+ }
if (dl_rrc->rrc_container) {
msg->rrc_container = malloc(dl_rrc->rrc_container_length);
AssertFatal(msg->rrc_container != NULL, "out of memory\n");
msg->rrc_container_length = dl_rrc->rrc_container_length;
memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length);
}
- itti_send_msg_to_task (TASK_CU_F1, module_id, message_p);
+ itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
}
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 51ef9d0f8d..f9c821736c 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -235,7 +235,6 @@ typedef enum {
} rrc_action_t;
typedef struct gNB_RRC_UE_s {
- uint8_t primaryCC_id;
drb_t established_drbs[MAX_DRBS_PER_UE];
uint8_t DRB_active[MAX_DRBS_PER_UE];
@@ -255,9 +254,6 @@ typedef struct gNB_RRC_UE_s {
NR_RRCReconfiguration_t *reconfig;
NR_RadioBearerConfig_t *rb_config;
- /* Pointer to save spCellConfig during RRC Reestablishment procedures */
- NR_SpCellConfig_t *spCellConfigReestablishment;
-
ImsiMobileIdentity_t imsi;
/* KgNB as derived from KASME received from EPC */
@@ -283,12 +279,7 @@ typedef struct gNB_RRC_UE_s {
/* Information from UE RRCReestablishmentRequest */
NR_ReestablishmentCause_t reestablishment_cause;
- /* UE id for initial connection to S1AP */
- uint16_t ue_initial_id;
-
- /* Information from S1AP initial_context_setup_req */
- uint32_t gNB_ue_s1ap_id :24;
- uint32_t gNB_ue_ngap_id;
+ uint32_t rrc_ue_id;
uint64_t amf_ue_ngap_id;
nr_rrc_guami_t ue_guami;
@@ -383,11 +374,6 @@ typedef struct cucp_cuup_if_s {
cucp_cuup_bearer_context_setup_func_t bearer_context_mod;
} cucp_cuup_if_t;
-typedef struct nr_reestablish_rnti_map_s {
- ue_id_t ue_id;
- rnti_t c_rnti;
-} nr_reestablish_rnti_map_t;
-
//---NR---(completely change)---------------------
typedef struct gNB_RRC_INST_s {
@@ -435,8 +421,6 @@ typedef struct gNB_RRC_INST_s {
// security configuration (preferred algorithms)
nr_security_configuration_t security;
- nr_reestablish_rnti_map_t nr_reestablish_rnti_map[MAX_MOBILES_PER_GNB];
-
nr_mac_rrc_dl_if_t mac_rrc;
cucp_cuup_if_t cucp_cuup;
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index fd9f38a3fb..7502662da3 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -119,7 +119,6 @@ void *rrc_gnb_task(void *args_p);
\ *reOffset Pointer to RE Offset Value */
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset);
-void nr_rrc_mac_remove_ue(rnti_t rntiP);
void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc);
int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP,
@@ -164,7 +163,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t rntiMaybeUEid,
- ue_id_t reestablish_ue_id,
NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP,
uint8_t *const kUPenc,
@@ -172,4 +170,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id);
+
+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);
+
#endif
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index f731ed0fbe..1fa458a309 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -97,6 +97,7 @@
#include
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
#include "openair2/F1AP/f1ap_common.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#include "cucp_cuup_if.h"
@@ -186,26 +187,6 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list)
//ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list);
return;
}
-static void nr_rrc_addmod_srbs(int rnti,
- const NR_SRB_INFO_TABLE_ENTRY *srb_list,
- const int nb_srb,
- const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list)
-{
- if (srb_list == NULL || bearer_list == NULL)
- return;
-
- for (int i = 0; i < nb_srb; i++) {
- if (srb_list[i].Active)
- for (int j = 0; j < bearer_list->list.count; j++) {
- const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j];
- if (bearer->servedRadioBearer != NULL
- && bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity
- && i == bearer->servedRadioBearer->choice.srb_Identity) {
- nr_rlc_add_srb(rnti, i, bearer);
- }
- }
- }
-}
static void nr_rrc_addmod_drbs(int rnti,
const NR_DRB_ToAddModList_t *drb_list,
@@ -227,6 +208,29 @@ static void nr_rrc_addmod_drbs(int rnti,
}
}
+typedef struct deliver_dl_rrc_message_data_s {
+ const gNB_RRC_INST *rrc;
+ f1ap_dl_rrc_message_t *dl_rrc;
+} 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)
+{
+ DevAssert(deliver_pdu_data != NULL);
+ deliver_dl_rrc_message_data_t *data = (deliver_dl_rrc_message_data_t *)deliver_pdu_data;
+ 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);
+}
+
+
+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)
+{
+ DevAssert(size > 0);
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
+ 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};
+ 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);
+}
///---------------------------------------------------------------------------------------------------------------///
///---------------------------------------------------------------------------------------------------------------///
@@ -310,6 +314,7 @@ static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc)
AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type);
break;
}
+ cu_init_f1_ue_data();
}
static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration)
@@ -422,25 +427,6 @@ static void freeSRBlist(NR_SRB_ToAddModList_t *l)
LOG_E(NR_RRC, "Call free SRB list on NULL pointer\n");
}
-static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP)
-{
- NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL;
- gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- nr_rrc_mac_update_cellgroup(ue_p->rnti, cgc);
- nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, cgc->rlc_BearerToAddModList);
- NR_DRB_ToAddModList_t *DRBs = fill_DRB_configList(ue_p);
- nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, DRBs, cgc->rlc_BearerToAddModList);
- freeDRBlist(DRBs);
-}
-
-void apply_macrlc_config_reest(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP, ue_id_t ue_id)
-{
- gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- nr_rrc_mac_update_cellgroup(ue_id, ue_p->masterCellGroup);
-
- nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, ue_p->masterCellGroup->rlc_BearerToAddModList);
-}
-
//-----------------------------------------------------------------------------
static void rrc_gNB_generate_RRCSetup(instance_t instance,
rnti_t rnti,
@@ -466,74 +452,18 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance,
(char *)buf,
size,
"[MSG] RRC Setup\n");
- nr_pdcp_add_srbs(true, rnti, SRBs, 0, NULL, NULL);
+ nr_pdcp_add_srbs(true, ue_p->rrc_ue_id, SRBs, 0, NULL, NULL);
freeSRBlist(SRBs);
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
f1ap_dl_rrc_message_t dl_rrc = {
- .old_gNB_DU_ue_id = 0xFFFFFF,
+ .gNB_CU_ue_id = ue_p->rrc_ue_id,
+ .gNB_DU_ue_id = ue_data.secondary_ue,
.rrc_container = buf,
.rrc_container_length = size,
- .rnti = ue_p->rnti,
.srb_id = CCCH
};
- rrc->mac_rrc.dl_rrc_message_transfer(instance, &dl_rrc);
-}
-
-//-----------------------------------------------------------------------------
-static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id)
-//-----------------------------------------------------------------------------
-{
- LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n");
- rrc_gNB_ue_context_t *ue_context_pP = NULL;
- gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id];
-
- ue_context_pP = rrc_gNB_create_ue_context(rnti, rrc_instance_p, 0);
-
- gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- unsigned char buf[1024];
- uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id);
- ue_p->xids[xid] = RRC_SETUP_FOR_REESTABLISHMENT;
- NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true);
-
- int size = do_RRCSetup(ue_context_pP, buf, xid, NULL, 0, &rrc_instance_p->configuration, SRBs);
- AssertFatal(size > 0, "do_RRCSetup failed\n");
- AssertFatal(size <= 1024, "memory corruption\n");
-
- AssertFatal(size>0,"Error generating RRCSetup for RRCReestablishmentRequest\n");
-
- LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
- (char *)buf,
- size,
- "[MSG] RRC Setup\n");
-
- LOG_D(NR_RRC, "RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB for rnti %04x\n", rnti);
- freeSRBlist(SRBs);
-
- // update SCC and MIB/SIB (two calls)
- nr_mac_config_scc(RC.nrmac[rrc_instance_p->module_id],
- rrc_instance_p->configuration.pdsch_AntennaPorts,
- rrc_instance_p->configuration.pusch_AntennaPorts,
- rrc_instance_p->configuration.sib1_tda,
- rrc_instance_p->configuration.minRXTXTIME,
- rrc_instance_p->carrier.servingcellconfigcommon);
- nr_mac_config_mib(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.mib);
- nr_mac_config_sib1(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.siblock1);
-
- LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size);
- // configure MAC
- protocol_ctxt_t ctxt = {0};
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0);
- apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt);
-
- f1ap_dl_rrc_message_t dl_rrc = {
- .old_gNB_DU_ue_id = 0xFFFFFF,
- .rrc_container = buf,
- .rrc_container_length = size,
- .rnti = ue_p->rnti,
- .srb_id = CCCH
- };
- rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc);
- return xid;
+ rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc);
}
static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP)
@@ -554,18 +484,17 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context
"[MSG] RRCReject \n");
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);
f1ap_dl_rrc_message_t dl_rrc = {
- .gNB_CU_ue_id = 0,
- .gNB_DU_ue_id = 0,
- .old_gNB_DU_ue_id = 0xFFFFFF,
+ .gNB_CU_ue_id = ue_p->rrc_ue_id,
+ .gNB_DU_ue_id = ue_data.secondary_ue,
.rrc_container = buf,
.rrc_container_length = size,
- .rnti = ue_p->rnti,
.srb_id = CCCH,
.execute_duplication = 1,
.RAT_frequency_priority_information.en_dc = 0
};
- rrc->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc);
+ rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc);
}
//-----------------------------------------------------------------------------
@@ -580,6 +509,7 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p
ue_context_pP->ue_context.Srb[1].Active = 1;
ue_context_pP->ue_context.Srb[2].Active = 0;
ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
+ AssertFatal(ctxt_pP->rntiMaybeUEid == ue_context_pP->ue_context.rrc_ue_id, "logic bug: inconsistent IDs, must use CU UE ID!\n");
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
@@ -668,7 +598,7 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
ue_context_pP->ue_context.rnti);
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
+ nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
@@ -775,7 +705,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
ctxt_pP->module_id,
DCCH);
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
+ nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.masterCellGroup);
@@ -928,7 +858,7 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
DCCH);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
+ nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
@@ -1009,7 +939,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
DCCH);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
+ nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
@@ -1046,35 +976,18 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
/* Refresh SRBs/DRBs */
LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti);
- ue_id_t reestablish_ue_id = 0;
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i];
- if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
- ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++;
- reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti;
- LOG_D(NR_RRC,
- "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n",
- i,
- nr_reestablish_rnti_map->ue_id,
- nr_reestablish_rnti_map->c_rnti);
- // clear current C-RNTI from map
- nr_reestablish_rnti_map->ue_id = 0;
- nr_reestablish_rnti_map->c_rnti = 0;
- break;
- }
- }
- NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
+ ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++;
+ NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
nr_pdcp_add_srbs(ctxt_pP->enb_flag,
- ctxt_pP->rntiMaybeUEid,
+ ue_p->rrc_ue_id,
SRBs,
(ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm,
kRRCenc,
kRRCint);
freeSRBlist(SRBs);
nr_pdcp_add_drbs(ctxt_pP->enb_flag,
- ctxt_pP->rntiMaybeUEid,
- reestablish_ue_id,
+ ue_p->rrc_ue_id,
DRB_configList,
(ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm,
kUPenc,
@@ -1145,34 +1058,23 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
}
//-----------------------------------------------------------------------------
-void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
- rrc_gNB_ue_context_t *ue_context_pP,
- const uint8_t *masterCellGroup_from_DU,
- NR_ServingCellConfigCommon_t *scc,
- const int CC_id)
+static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context_pP,
+ const uint8_t *masterCellGroup_from_DU,
+ NR_ServingCellConfigCommon_t *scc,
+ const rnti_t old_rnti)
//-----------------------------------------------------------------------------
{
- // int UE_id = -1;
- // NR_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL;
- // NR_SRB_ToAddMod_t *SRB1_config = NULL;
- // rrc_gNB_carrier_data_t *carrier = NULL;
- module_id_t module_id = ctxt_pP->module_id;
- gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
+ module_id_t module_id = 0;
+ gNB_RRC_INST *rrc = RC.nrrrc[module_id];
int enable_ciphering = 0;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- // Need to drop spCellConfig when there is a RRCReestablishment
- // Save spCellConfig in spCellConfigReestablishment to recover after Reestablishment is completed
- ue_p->spCellConfigReestablishment = ue_p->masterCellGroup->spCellConfig;
- ue_p->masterCellGroup->spCellConfig = NULL;
-
uint8_t buffer[RRC_BUF_SIZE] = {0};
uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id);
ue_p->xids[xid] = RRC_REESTABLISH;
NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true);
- int size = do_RRCReestablishment(ctxt_pP,
- ue_context_pP,
- CC_id,
+ int size = do_RRCReestablishment(ue_context_pP,
+ 0 /* CC_id */,
buffer,
RRC_BUF_SIZE,
xid,
@@ -1192,101 +1094,27 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint);
-
- /* Configure SRB1 for UE */
- nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRBs, 0, NULL, NULL);
- LOG_D(NR_RRC, "UE %04x --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", ue_p->rnti);
freeSRBlist(SRBs);
- LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm);
+ LOG_I(NR_RRC, "Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", ue_p->rrc_ue_id, ue_p->rnti, ue_p->ciphering_algorithm, ue_p->integrity_algorithm);
uint8_t security_mode =
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4);
- nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid,
+ nr_pdcp_config_set_security(ue_p->rrc_ue_id,
DCCH,
security_mode,
kRRCenc,
kRRCint,
kUPenc);
+ nr_pdcp_reestablishment(ue_p->rrc_ue_id);
- if (!NODE_IS_CU(rrc->node_type)) {
- apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid);
- }
-
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
-}
-
-/// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels.
-/// @param reestablish_rnti is the old C-RNTI
-void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP,
- rrc_gNB_ue_context_t *ue_context_pP,
- const rnti_t reestablish_rnti)
-{
- gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- int i = 0;
- int j = 0;
- int ret = 0;
-
- if (get_softmodem_params()->sa) {
- LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n");
- gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0};
- /* Save e RAB information for later */
-
- for (j = 0, i = 0; i < NB_RB_MAX; i++) {
- if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) {
- create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id;
- create_tunnel_req.incoming_rb_id[j] = i + 1;
- create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid;
- // to be developped, use the first QFI only
- create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi;
- memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20);
- create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length;
- j++;
- }
- }
-
- create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above
- create_tunnel_req.num_tunnels = j;
- ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, &create_tunnel_req, reestablish_rnti);
-
- if (ret != 0) {
- LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti);
- AssertFatal(false, "not implemented\n");
- return;
- }
- }
-}
-
-/// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid.
-/// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid.
-/// @todo parameters yet to process inside the for loop.
-/// @todo should test if pdu session are Ok before! inside the for loop.
-void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid)
-{
- gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- /* Add all NAS PDUs to the list */
- for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
- ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
- ue_p->pduSession[i].xid = old_xid;
- LOG_D(NR_RRC,
- "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n",
- i,
- ue_p->pduSession[i].status,
- "PDU_SESSION_STATUS_DONE");
- }
-}
-
-/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers.
-void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP)
-{
- gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
- /* Free all NAS PDUs */
- for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
- if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
- /* Free the NAS PDU buffer and invalidate it */
- free(ue_p->pduSession[i].param.nas_pdu.buffer);
- ue_p->pduSession[i].param.nas_pdu.buffer = NULL;
- }
- }
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
+ 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};
+ 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);
}
/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request.
@@ -1294,10 +1122,9 @@ void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP
/// @param reestablish_rnti is the old C-RNTI
/// @param ue_context_pP UE context container information regarding the UE
/// @param xid Transaction Identifier used in RRC messages
-void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
- const rnti_t reestablish_rnti,
- rrc_gNB_ue_context_t *ue_context_pP,
- const uint8_t xid)
+static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
+ rrc_gNB_ue_context_t *ue_context_pP,
+ const uint8_t xid)
{
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
LOG_I(NR_RRC,
@@ -1316,19 +1143,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command);
LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n");
}
- RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti);
- RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid);
-
- /* Update RNTI in ue_context */
- LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid);
- rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
- // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment
- ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment;
- ue_p->spCellConfigReestablishment = NULL;
cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig;
cellGroupConfig->mac_CellGroupConfig = ue_p->masterCellGroup->mac_CellGroupConfig;
cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig;
@@ -1371,32 +1189,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
freeDRBlist(DRBs);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
- RRCReestablishmentComplete_nas_pdu_free(ue_context_pP);
-
- if (size < 0) {
- LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n");
- return;
- } else {
- LOG_I(NR_RRC,
- "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n",
- ctxt_pP->module_id,
- ctxt_pP->frame,
- size,
- ue_p->rnti);
- LOG_D(NR_RRC,
- "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD "
- "%u][RB %u]\n",
- ctxt_pP->frame,
- ctxt_pP->module_id,
- size,
- ue_p->rnti,
- rrc_gNB_mui,
- ctxt_pP->module_id,
- DCCH);
-
- nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, cellGroupConfig);
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
- }
+ AssertFatal(size > 0, "cannot encode RRC Reconfiguration\n");
+ LOG_I(NR_RRC,
+ "UE %d RNTI %04x: Generate NR_RRCReconfiguration after reestablishment complete (bytes %d)\n",
+ ue_p->rrc_ue_id,
+ ue_p->rnti,
+ size);
+ nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig
@@ -1451,7 +1250,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
+ nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
@@ -1466,17 +1265,18 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
}
/*------------------------------------------------------------------------------*/
-static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint8_t *buffer, int buffer_length, const uint8_t *du_to_cu_rrc_container, int du_to_cu_rrc_container_len)
+static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg)
{
- module_id_t Idx;
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;
- LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, buffer_length);
- dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0);
+ 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");
@@ -1492,12 +1292,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest:
LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti);
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti);
- if (ue_context_p != NULL) {
- LOG_W(NR_RRC, "Got RRC setup request for a already registered RNTI %x, dropping the old one and give up this rrcSetupRequest\n", ue_context_p->ue_context.rnti);
- rrc_gNB_remove_ue_context(gnb_rrc_inst, ue_context_p);
- } else {
+ {
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
@@ -1515,7 +1312,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
AssertFatal(false, "not implemented\n");
}
- ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value);
+ 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 */
@@ -1534,20 +1331,14 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
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);
-
- // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed.
- if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) {
- nr_rrc_mac_remove_ue(ue_context_p->ue_context.rnti);
- } else {
- AssertFatal(false, "not implemented: need to switch RNTI in MAC via DL RRC Message Transfer\n");
- }
+ 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);
+ ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1, msg->gNB_DU_ue_id);
if (ue_context_p == NULL) {
LOG_E(NR_RRC, "rrc_gNB_get_next_free_ue_context returned NULL\n");
return -1;
@@ -1561,7 +1352,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
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);
+ 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;
@@ -1572,9 +1363,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
UE->Srb[1].Active = 1;
rrc_gNB_generate_RRCSetup(module_id,
rnti,
- rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti),
- du_to_cu_rrc_container,
- du_to_cu_rrc_container_len);
+ ue_context_p,
+ msg->du2cu_rrc_container,
+ msg->du2cu_rrc_container_length);
}
break;
@@ -1583,86 +1374,81 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
break;
case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: {
- LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(buffer), buffer_length, "[MSG] RRC Reestablishment Request\n");
+ 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 NR_RRCReestablishmentRequest cause %s\n",
+ "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n",
rnti,
- ((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure"
- : (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure"
- : "reconfigurationFailure"));
- uint8_t xid = -1;
+ physCellId,
+ cause == NR_ReestablishmentCause_otherFailure
+ ? "Other Failure"
+ : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure"));
if (physCellId != gnb_rrc_inst->carrier.physCellId) {
/* 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(%ld), fallback to RRC establishment\n",
physCellId,
gnb_rrc_inst->carrier.physCellId);
- xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0);
+ /* 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;
}
- LOG_I(NR_RRC, "physCellId: %ld\n", physCellId);
-
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]);
}
- // 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 range error, fallback to RRC establishment\n");
- xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0);
+ 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;
}
- rnti_t c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI;
- LOG_I(NR_RRC, "c_RNTI: %04x\n", c_rnti);
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, c_rnti);
- gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- if (ue_context_p == NULL) {
- LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n");
- xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0);
- break;
- }
- // c-plane not end
- if ((UE->StatusRrc != NR_RRC_RECONFIGURED) && (UE->reestablishment_cause == NR_ReestablishmentCause_spare1)) {
- LOG_E(NR_RRC, "NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed\n", c_rnti);
- /* TODO RRC Release ? */
+ // 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 */
- (void) xid; /* xid currently not used */
- // Insert C-RNTI to map
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i];
- LOG_I(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti);
- if (nr_reestablish_rnti_map->ue_id == 0) {
- nr_reestablish_rnti_map->ue_id = rnti;
- nr_reestablish_rnti_map->c_rnti = c_rnti;
- LOG_W(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x bug in UEid to fix \n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti);
- break;
- }
- }
+ // 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);
- UE->primaryCC_id = 0;
- // LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH;
- Idx = DCCH;
- // SRB1
- UE->Srb[1].Active = 1;
- // SRB2: set it to go through SRB1 with id 1 (DCCH)
- UE->Srb[2].Active = 1;
- protocol_ctxt_t ctxt = {.rntiMaybeUEid = rnti, .module_id = module_id, .instance = module_id, .enb_flag = 1, .eNB_index = module_id};
- rrc_gNB_generate_RRCReestablishment(&ctxt, ue_context_p, du_to_cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, 0);
-
- LOG_I(NR_RRC, "CALLING RLC CONFIG SRB1 (rbid %d)\n", Idx);
+ rrc_gNB_generate_RRCReestablishment(ue_context_p,
+ msg->du2cu_rrc_container,
+ gnb_rrc_inst->carrier.servingcellconfigcommon,
+ old_rnti);
} break;
case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest:
@@ -1721,48 +1507,18 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
}
static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
+ rrc_gNB_ue_context_t *ue_context_p,
const NR_RRCReestablishmentComplete_t *reestablishment_complete)
{
- rnti_t reestablish_rnti = 0;
- gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
- rrc_gNB_ue_context_t *ue_context_p = NULL;
- gNB_RRC_UE_t *UE = NULL;
- // Select C-RNTI from map
- for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
- nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i];
- LOG_I(NR_RRC,
- "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n",
- i,
- nr_reestablish_rnti_map->ue_id,
- nr_reestablish_rnti_map->c_rnti,
- ctxt_pP->rntiMaybeUEid);
- if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
- LOG_I(NR_RRC,
- "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n",
- i,
- nr_reestablish_rnti_map->ue_id,
- nr_reestablish_rnti_map->c_rnti);
- reestablish_rnti = nr_reestablish_rnti_map->c_rnti;
- ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti);
- UE = &ue_context_p->ue_context;
- break;
- }
- }
-
- if (ue_context_p == NULL || UE == NULL) {
- LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n");
- return -1;
- }
+ DevAssert(ue_context_p != NULL);
+ gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
DevAssert(reestablishment_complete->criticalExtensions.present
== NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete);
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP,
- reestablish_rnti,
ue_context_p,
reestablishment_complete->rrc_TransactionIdentifier);
- nr_rrc_mac_remove_ue(reestablish_rnti);
-
UE->ue_reestablishment_counter++;
return 0;
}
@@ -1954,18 +1710,21 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
case RRC_DEFAULT_RECONF:
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
break;
+ case RRC_REESTABLISH_COMPLETE:
+ /* do nothing */
+ break;
default:
- LOG_E(RRC, "Received unexpected xid: %d\n", xid);
+ LOG_E(RRC, "Received unexpected transaction type %d for xid %d\n", UE->xids[xid], xid);
successful_reconfig = false;
break;
}
}
gNB_RRC_INST *rrc = RC.nrrrc[0];
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
f1ap_ue_context_modif_req_t ue_context_modif_req = {
- .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */
- .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */
- .rnti = UE->rnti,
+ .gNB_CU_ue_id = UE->rrc_ue_id,
+ .gNB_DU_ue_id = ue_data.secondary_ue,
.mcc = rrc->configuration.mcc[0],
.mnc = rrc->configuration.mnc[0],
.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
@@ -1984,6 +1743,13 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
{
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
+ /* we look up by CU UE ID! Do NOT change back to RNTI! */
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid);
+ if (!ue_context_p) {
+ LOG_E(RRC, "could not find UE context for CU UE ID %lu, aborting transaction\n", ctxt_pP->rntiMaybeUEid);
+ return -1;
+ }
+
if ((Srb_id != 1) && (Srb_id != 2)) {
LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id);
} else {
@@ -2011,8 +1777,6 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid);
-
if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) {
switch (ul_dcch_msg->message.choice.c1->present) {
case NR_UL_DCCH_MessageType__c1_PR_NOTHING:
@@ -2104,7 +1868,7 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
- if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete)
+ if (handle_rrcReestablishmentComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete)
== -1)
return -1;
break;
@@ -2222,7 +1986,7 @@ void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t
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->crnti, ul_rrc->rrc_container, ul_rrc->rrc_container_length, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length);
+ nr_rrc_gNB_decode_ccch(i, ul_rrc);
if (ul_rrc->rrc_container)
free(ul_rrc->rrc_container);
@@ -2246,7 +2010,11 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
{
f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti);
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id);
+ if (!ue_context_p) {
+ LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id);
+ return;
+ }
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
NR_CellGroupConfig_t *cellGroupConfig = NULL;
@@ -2275,10 +2043,14 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p)
const int instance = 0;
f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti);
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_CU_ue_id);
+ if (!ue_context_p) {
+ LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", req->gNB_CU_ue_id);
+ return;
+ }
/* TODO: marshall types correctly */
- LOG_I(NR_RRC, "received UE Context Release Request for UE %04x, forwarding to AMF\n", req->rnti);
+ LOG_I(NR_RRC, "received UE Context Release Request for UE %u, forwarding to AMF\n", req->gNB_CU_ue_id);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance,
ue_context_p,
NGAP_CAUSE_RADIO_NETWORK,
@@ -2290,29 +2062,37 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p)
const int instance = 0;
f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->rnti);
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, complete->gNB_CU_ue_id);
+ if (!ue_context_p) {
+ LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", complete->gNB_CU_ue_id);
+ return;
+ }
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- nr_pdcp_remove_UE(UE->rnti);
- newGtpuDeleteAllTunnels(instance, UE->rnti);
- rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->gNB_ue_ngap_id);
- LOG_I(NR_RRC, "removed UE %04x \n", UE->rnti);
+ nr_pdcp_remove_UE(UE->rrc_ue_id);
+ newGtpuDeleteAllTunnels(instance, UE->rrc_ue_id);
+ rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id);
+ LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti);
rrc_gNB_remove_ue_context(rrc, ue_context_p);
}
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
{
f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
- protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
+ protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti);
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id);
+ if (!ue_context_p) {
+ LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id);
+ return;
+ }
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if (resp->drbs_to_be_setup_length > 0) {
e1ap_bearer_setup_req_t req = {0};
req.numPDUSessionsMod = UE->nb_of_pdusessions;
- req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id;
- req.rnti = UE->rnti;
+ req.gNB_cu_cp_ue_id = UE->rrc_ue_id;
+ req.gNB_cu_up_ue_id = UE->rrc_ue_id;
for (int i = 0; i < req.numPDUSessionsMod; i++) {
req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length;
for (int j = 0; j < resp->drbs_to_be_setup_length; j++) {
@@ -2561,10 +2341,10 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex
srbs[0].lcid = 2;
}
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
f1ap_ue_context_modif_req_t ue_context_modif_req = {
- .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */
- .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */
- .rnti = UE->rnti,
+ .gNB_CU_ue_id = UE->rrc_ue_id,
+ .gNB_DU_ue_id = ue_data.secondary_ue,
.mcc = rrc->configuration.mcc[0],
.mnc = rrc->configuration.mnc[0],
.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
@@ -2582,9 +2362,16 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
// Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], resp->gNB_cu_cp_ue_id);
- gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
+ AssertFatal(ue_context_p != NULL, "did not find UE with CU UE ID %d\n", resp->gNB_cu_cp_ue_id);
protocol_ctxt_t ctxt = {0};
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, resp->gNB_cu_cp_ue_id, 0, 0, 0);
+
+ // currently: we don't have "infrastructure" to save the CU-UP UE ID, so we
+ // assume (and below check) that CU-UP UE ID == CU-CP UE ID
+ AssertFatal(resp->gNB_cu_cp_ue_id == resp->gNB_cu_up_ue_id,
+ "cannot handle CU-UP UE ID different from CU-CP UE ID (%d vs %d)\n",
+ resp->gNB_cu_cp_ue_id,
+ resp->gNB_cu_up_ue_id);
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
create_tunnel_resp.num_tunnels = resp->numPDUSessions;
@@ -2624,6 +2411,36 @@ static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults)
}
}
+static const char *get_rrc_connection_status_text(NR_UE_STATE_t state)
+{
+ switch (state) {
+ case NR_RRC_INACTIVE: return "inactive";
+ case NR_RRC_IDLE: return "idle";
+ case NR_RRC_SI_RECEIVED: return "SI-received";
+ case NR_RRC_CONNECTED: return "connected";
+ case NR_RRC_RECONFIGURED: return "reconfigured";
+ case NR_RRC_HO_EXECUTION: return "HO-execution";
+ default: AssertFatal(false, "illegal RRC state %d\n", state); return "illegal";
+ }
+ return "illegal";
+}
+
+static const char *get_pdusession_status_text(pdu_session_status_t status)
+{
+ switch (status) {
+ case PDU_SESSION_STATUS_NEW: return "new";
+ case PDU_SESSION_STATUS_DONE: return "done";
+ case PDU_SESSION_STATUS_ESTABLISHED: return "established";
+ case PDU_SESSION_STATUS_REESTABLISHED: return "reestablished";
+ case PDU_SESSION_STATUS_TOMODIFY: return "to-modify";
+ case PDU_SESSION_STATUS_FAILED: return "failed";
+ case PDU_SESSION_STATUS_TORELEASE: return "to-release";
+ case PDU_SESSION_STATUS_RELEASED: return "released";
+ default: AssertFatal(false, "illegal PDU status code %d\n", status); return "illegal";
+ }
+ return "illegal";
+}
+
static void write_rrc_stats(const gNB_RRC_INST *rrc)
{
const char *filename = "nrRRC_stats.log";
@@ -2633,19 +2450,33 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc)
return;
}
+ int i = 0;
rrc_gNB_ue_context_t *ue_context_p = NULL;
/* cast is necessary to eliminate warning "discards ‘const’ qualifier" */
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head)
{
const gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context;
- const rnti_t rnti = ue_ctxt->rnti;
-
- fprintf(f, "NR RRC UE rnti %04x:", rnti);
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_ctxt->rrc_ue_id);
+ fprintf(f,
+ "UE %d CU UE ID %d DU UE ID %d RNTI %04x random identity %016lx",
+ i,
+ ue_ctxt->rrc_ue_id,
+ ue_data.secondary_ue,
+ ue_ctxt->rnti,
+ ue_ctxt->random_ue_identity);
if (ue_ctxt->Initialue_identity_5g_s_TMSI.presence)
fprintf(f, " S-TMSI %x", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi);
+ fprintf(f, ":\n");
- fprintf(f, "\n");
+ fprintf(f, " RRC status %s\n", get_rrc_connection_status_text(ue_ctxt->StatusRrc));
+
+ if (ue_ctxt->nb_of_pdusessions == 0)
+ fprintf(f, " (no PDU sessions)\n");
+ for (int nb_pdu = 0; nb_pdu < ue_ctxt->nb_of_pdusessions; ++nb_pdu) {
+ const rrc_pdu_session_param_t *pdu = &ue_ctxt->pduSession[nb_pdu];
+ fprintf(f, " PDU session %d ID %d status %s\n", nb_pdu, pdu->param.pdusession_id, get_pdusession_status_text(pdu->status));
+ }
if (ue_ctxt->UE_Capability_nr) {
fprintf(f,
@@ -2659,6 +2490,7 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc)
if (ue_ctxt->measResults)
print_rrc_meas(f, ue_ctxt->measResults);
+ ++i;
}
fclose(f);
@@ -2714,7 +2546,7 @@ void *rrc_gnb_task(void *args_p) {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
instance,
GNB_FLAG_YES,
- F1AP_UL_RRC_MESSAGE(msg_p).rnti,
+ F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id,
0,
0);
LOG_D(NR_RRC,
@@ -2827,25 +2659,17 @@ 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;
+} 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)
{
DevAssert(deliver_pdu_data != NULL);
- gNB_RRC_INST *rrc = deliver_pdu_data;
- f1ap_ue_context_setup_t ue_context_setup_req = {
- .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */
- .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */
- .rnti = ue_id,
- .mcc = rrc->configuration.mcc[0],
- .mnc = rrc->configuration.mnc[0],
- .mnc_digit_length = rrc->configuration.mnc_digit_length[0],
- .nr_cellid = rrc->nr_cellid,
- .servCellId = 0, /* TODO: correct value? */
- .srbs_to_be_setup = 0, /* no new SRBs */
- .drbs_to_be_setup = 0, /* no new DRBs */
- .rrc_container = (uint8_t*) buf, /* security mode command */
- .rrc_container_length = size,
- };
- rrc->mac_rrc.ue_context_setup_request(&ue_context_setup_req);
+ 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);
}
//-----------------------------------------------------------------------------
@@ -2870,7 +2694,20 @@ rrc_gNB_generate_SecurityModeCommand(
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
/* the callback will fill the UE context setup request and forward it */
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, rrc);
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
+ 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,
+ .mcc = rrc->configuration.mcc[0],
+ .mnc = rrc->configuration.mnc[0],
+ .mnc_digit_length = rrc->configuration.mnc_digit_length[0],
+ .nr_cellid = rrc->nr_cellid,
+ .servCellId = 0, /* TODO: correct value? */
+ .srbs_to_be_setup = 0, /* no new SRBs */
+ .drbs_to_be_setup = 0, /* no new DRBs */
+ };
+ deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req};
+ nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, &data);
}
void
@@ -2896,25 +2733,21 @@ rrc_gNB_generate_UECapabilityEnquiry(
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
+ const gNB_RRC_UE_t *ue = &ue_context_pP->ue_context;
+ nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size);
}
+typedef struct deliver_ue_ctxt_release_data_t {
+ gNB_RRC_INST *rrc;
+ f1ap_ue_context_release_cmd_t *release_cmd;
+} 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)
{
DevAssert(deliver_pdu_data != NULL);
- gNB_RRC_INST *rrc = deliver_pdu_data;
- uint8_t *rrc_container = malloc(size);
- AssertFatal(rrc_container != NULL, "out of memory\n");
- memcpy(rrc_container, buf, size);
- f1ap_ue_context_release_cmd_t ue_context_release_cmd = {
- .rnti = ue_id, /* TODO: proper IDs! */
- .cause = F1AP_CAUSE_RADIO_NETWORK,
- .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release
- .srb_id = srb_id,
- .rrc_container = rrc_container,
- .rrc_container_length = size,
- };
- rrc->mac_rrc.ue_context_release_command(&ue_context_release_cmd);
+ 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);
}
//-----------------------------------------------------------------------------
@@ -2938,7 +2771,17 @@ rrc_gNB_generate_RRCRelease(
size);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
- nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, rrc);
+ 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);
+ 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,
+ .cause = F1AP_CAUSE_RADIO_NETWORK,
+ .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};
+ nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
/* UE will be freed after UE context release complete */
}
diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c
index e7bbe5835e..3ef3e62d51 100644
--- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c
+++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c
@@ -52,7 +52,8 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_
}
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
+ /* we look up by CU UE ID! Do NOT change back to RNTI! */
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
if (!ue_context_p) {
LOG_E(NR_RRC, "UE table error\n");
return -1;
@@ -83,7 +84,8 @@ int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ct
}
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
+ /* we look up by CU UE ID! Do NOT change back to RNTI! */
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
if (!ue_context_p) {
LOG_E(NR_RRC, "UE table error\n");
return -1;
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index f0a7f3b90f..8a9a08abd7 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -58,6 +58,7 @@
#include "NR_UE-CapabilityRAT-ContainerList.h"
#include "NGAP_CauseRadioNetwork.h"
#include "f1ap_messages_types.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/E1AP/e1ap_asnc.h"
#include "NGAP_asn_constant.h"
#include "NGAP_PDUSessionResourceSetupRequestTransfer.h"
@@ -182,7 +183,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
ngap_nas_first_req_t *req = &NGAP_NAS_FIRST_REQ(message_p);
memset(req, 0, sizeof(*req));
- req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ req->gNB_ue_ngap_id = UE->rrc_ue_id;
/* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */
AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d) for gNB %d!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST, ctxt_pP->module_id);
@@ -370,7 +371,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p);
return (-1);
}
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
+ PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
UE->amf_ue_ngap_id = req->amf_ue_ngap_id;
uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions;
if (nb_pdusessions_tosetup) {
@@ -391,7 +392,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
memcpy(create_tunnel_req.dst_addr[i].buffer, req->pdusession_param[i].upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[i].buffer));
LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[i], create_tunnel_req.pdusession_id[i]);
}
- create_tunnel_req.ue_id = UE->rnti;
+ create_tunnel_req.ue_id = UE->rrc_ue_id;
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0};
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req);
if (ret != 0) {
@@ -436,7 +437,7 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c
ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p);
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
- resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ resp->gNB_ue_ngap_id = UE->rrc_ue_id;
for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) {
rrc_pdu_session_param_t *session = &UE->pduSession[pdusession];
@@ -607,7 +608,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
+ PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
/* Create message for PDCP (DLInformationTransfer_t) */
length = do_NR_DLInformationTransfer(instance, &buffer, rrc_gNB_get_next_transaction_identifier(instance), req->nas_pdu.length, req->nas_pdu.buffer);
@@ -618,7 +619,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
AssertFatal(!NODE_IS_DU(RC.nrrrc[ctxt.module_id]->node_type), "illegal node type DU: receiving NGAP messages at this node\n");
/* Transfer data to PDCP */
rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH;
- nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, (*rrc_gNB_mui)++, length, buffer, deliver_pdu_srb_f1, RC.nrrrc[instance]);
+ nr_rrc_transfer_protected_rrc_message(RC.nrrrc[instance], UE, srb_id, buffer, length);
return 0;
}
@@ -641,7 +642,7 @@ rrc_gNB_send_NGAP_UPLINK_NAS(
pdu_length = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->size;
pdu_buffer = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->buf;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS);
- NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
NGAP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length;
NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer;
// extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer,
@@ -668,7 +669,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP);
ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_p);
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
- resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ resp->gNB_ue_ngap_id = UE->rrc_ue_id;
for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) {
rrc_pdu_session_param_t *session = &UE->pduSession[pdusession];
@@ -745,7 +746,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
return ;
}
- UE->gNB_ue_ngap_id = msg->gNB_ue_ngap_id;
+ UE->rrc_ue_id = msg->gNB_ue_ngap_id;
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
e1ap_bearer_setup_req_t bearer_req = {0};
@@ -759,7 +760,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer;
decodePDUSessionResourceSetup(session);
bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id;
- bearer_req.rnti = UE->rnti;
bearer_req.cipheringAlgorithm = UE->ciphering_algorithm;
bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm;
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)bearer_req.encryptionKey);
@@ -925,7 +925,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
return (-1);
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
+ PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
bool all_failed = true;
for (int i = 0; i < req->nb_pdusessions_tomodify; i++) {
@@ -1009,7 +1009,7 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
ngap_pdusession_modify_resp_t *resp = &NGAP_PDUSESSION_MODIFY_RESP(msg_p);
LOG_I(NR_RRC, "send message NGAP_PDUSESSION_MODIFY_RESP \n");
- resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ resp->gNB_ue_ngap_id = UE->rrc_ue_id;
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
if (xid != UE->pduSession[i].xid) {
@@ -1087,7 +1087,7 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, con
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_REQ);
ngap_ue_release_req_t *req = &NGAP_UE_CONTEXT_RELEASE_REQ(msg);
memset(req, 0, sizeof(*req));
- req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ req->gNB_ue_ngap_id = UE->rrc_ue_id;
req->cause = causeP;
req->cause_value = cause_valueP;
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
@@ -1152,7 +1152,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
+ PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
return 0;
@@ -1202,7 +1202,7 @@ void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND);
ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p);
memset(ind, 0, sizeof(*ind));
- ind->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ ind->gNB_ue_ngap_id = UE->rrc_ue_id;
ind->ue_radio_cap.length = encoded;
ind->ue_radio_cap.buffer = buf2;
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
@@ -1224,7 +1224,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE);
ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p);
memset(resp, 0, sizeof(*resp));
- resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
+ resp->gNB_ue_ngap_id = UE->rrc_ue_id;
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
if (xid == UE->pduSession[i].xid) {
@@ -1239,7 +1239,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
resp->nb_of_pdusessions_released = pdu_sessions_released;
resp->nb_of_pdusessions_failed = 0;
- LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released);
+ LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released);
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
}
@@ -1264,9 +1264,9 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
+ PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
LOG_I(
- NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease);
+ NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu rrc_ue_id %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease);
bool found = false;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
UE->xids[xid] = RRC_PDUSESSION_RELEASE;
diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c
index 2d2742aa4a..8a8c0bdd2e 100644
--- a/openair2/RRC/NR/rrc_gNB_UE_context.c
+++ b/openair2/RRC/NR/rrc_gNB_UE_context.c
@@ -35,17 +35,18 @@
#include "common/utils/LOG/log.h"
#include "rrc_gNB_UE_context.h"
+#include "openair2/F1AP/f1ap_ids.h"
//------------------------------------------------------------------------------
int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP)
//------------------------------------------------------------------------------
{
- if (c1_pP->ue_context.gNB_ue_ngap_id > c2_pP->ue_context.gNB_ue_ngap_id) {
+ if (c1_pP->ue_context.rrc_ue_id > c2_pP->ue_context.rrc_ue_id) {
return 1;
}
- if (c1_pP->ue_context.gNB_ue_ngap_id < c2_pP->ue_context.gNB_ue_ngap_id) {
+ if (c1_pP->ue_context.rrc_ue_id < c2_pP->ue_context.rrc_ue_id) {
return -1;
}
@@ -66,12 +67,12 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance
LOG_E(NR_RRC, "Cannot allocate new ue context\n");
return NULL;
}
- new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator);
+ new_p->ue_context.rrc_ue_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator) + 1;
for(int i = 0; i < NB_RB_MAX; i++)
new_p->ue_context.pduSession[i].xid = -1;
- LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id);
+ LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.rrc_ue_id);
return(new_p);
}
@@ -82,7 +83,7 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_i
{
rrc_gNB_ue_context_t temp;
/* gNB ue rrc id = 24 bits wide */
- temp.ue_context.gNB_ue_ngap_id = ue;
+ temp.ue_context.rrc_ue_id = ue;
return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
}
@@ -120,7 +121,8 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context
}
RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP);
- uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id);
+ uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.rrc_ue_id - 1);
+ cu_remove_f1_ue_data(ue_context_pP->ue_context.rrc_ue_id);
rrc_gNB_free_mem_ue_context(ue_context_pP);
LOG_I(NR_RRC, "Removed UE context\n");
}
@@ -153,35 +155,33 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta
return NULL;
}
-void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t gNB_ue_ngap_id)
-{
- // rnti will need to be a fast access key, with indexing, today it is sequential search
- // This function will update the index when it will be made
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, gNB_ue_ngap_id);
- if (ue_context_p)
- ue_context_p->ue_context.rnti = rnti;
- else
- LOG_E(NR_RRC, "update rnti on a wrong UE id\n");
-}
//-----------------------------------------------------------------------------
// 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, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP)
+rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti,
+ gNB_RRC_INST *rrc_instance_pP,
+ const uint64_t ue_identityP,
+ uint32_t du_ue_id)
//-----------------------------------------------------------------------------
{
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti);
-
- if (ue_context_p) {
- LOG_E(NR_RRC, "Cannot create new UE context, already exist rnti: %04x\n", rnti);
- return ue_context_p;
- }
-
- ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP);
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP);
if (ue_context_p == NULL)
return NULL;
- ue_context_p->ue_context.rnti = rnti;
- ue_context_p->ue_context.random_ue_identity = ue_identityP;
+ 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};
+ 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);
+ cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data);
+
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
- LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.gNB_ue_ngap_id);
+ LOG_I(NR_RRC,
+ "Created new UE context: CU UE ID %u DU UE ID %u (rnti: %04x, random ue id %lx)\n",
+ ue->rrc_ue_id,
+ du_ue_id,
+ ue->rnti,
+ ue->random_ue_identity);
return ue_context_p;
}
diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h
index 9c1ec2c164..3ec0852af6 100644
--- a/openair2/RRC/NR/rrc_gNB_UE_context.h
+++ b/openair2/RRC/NR/rrc_gNB_UE_context.h
@@ -50,7 +50,9 @@ 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);
-void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id);
-rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP);
+rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti,
+ gNB_RRC_INST* rrc_instance_pP,
+ const uint64_t ue_identityP,
+ uint32_t du_ue_id);
#endif
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 656c7d0663..f0d89051df 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -41,6 +41,7 @@
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
+#include "openair2/F1AP/f1ap_ids.h"
#include "executables/softmodem-common.h"
#include "executables/nr-softmodem.h"
#include
@@ -248,14 +249,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
1,
1,
configuration,
- ue_context_p->ue_context.gNB_ue_ngap_id);
+ ue_context_p->ue_context.rrc_ue_id);
AssertFatal(UE->secondaryCellGroup != NULL, "out of memory\n");
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup);
- fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.gNB_ue_ngap_id);
- // the UE context is not yet inserted in the RRC UE manager
- // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc,
- // UE->gNB_ue_ngap_id);
+ fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.rrc_ue_id);
UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
memset((void *)CG_Config,0,sizeof(*CG_Config));
@@ -288,7 +286,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
create_tunnel_req.sgw_S1u_teid[i]);
}
- create_tunnel_req.rnti = ue_context_p->ue_context.rnti;
+ create_tunnel_req.rnti = ue_context_p->ue_context.rrc_ue_id;
create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded;
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
@@ -343,20 +341,31 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
}
+ // below we configure the stack. In SA, we fully adopted F1, meaning that
+ // layers use different IDs (MAC/RLC use RNTI as DU UE ID, above use NGAP ID
+ // as CU UE ID.
+ uint32_t du_ue_id = ue_context_p->ue_context.rnti;
+ static uint32_t rrc_ue_id = 0;
+ rrc_ue_id++;
+ f1_ue_data_t du_ue_data = {.secondary_ue = rrc_ue_id};
+ du_add_f1_ue_data(du_ue_id, &du_ue_data);
+ f1_ue_data_t cu_ue_data = {.secondary_ue = du_ue_id};
+ cu_add_f1_ue_data(rrc_ue_id, &cu_ue_data);
+ LOG_I(RRC, "Assign CU UE ID %d and DU UE ID %d to UE RNTI %04x\n", rrc_ue_id, du_ue_id, ue_context_p->ue_context.rnti);
+
// configure MAC and RLC
bool ret = false;
if (get_softmodem_params()->phy_test) {
// phytest mode: we don't set up RA, etc
- ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id] , ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup);
+ ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup);
} else {
NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock);
- ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup);
+ ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup);
NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock);
}
AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n");
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
- if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0;
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rrc_ue_id, 0, 0, rrc->module_id);
LOG_W(RRC,
"Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n",
&ctxt,
@@ -367,14 +376,14 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
ctxt.eNB_index);
nr_pdcp_add_drbs(ctxt.enb_flag,
- ctxt.rntiMaybeUEid,
- 0,
+ rrc_ue_id,
ue_context_p->ue_context.rb_config->drb_ToAddModList,
(ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
kUPenc,
kUPint,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
+ ctxt.rntiMaybeUEid = du_ue_id;
// assume only a single bearer
const NR_DRB_ToAddModList_t *drb_list = ue_context_p->ue_context.rb_config->drb_ToAddModList;
DevAssert(drb_list->list.count == 1);
diff --git a/openair2/RRC/NR_UE/main_ue.c b/openair2/RRC/NR_UE/main_ue.c
index 5e2bc429eb..72853cd278 100644
--- a/openair2/RRC/NR_UE/main_ue.c
+++ b/openair2/RRC/NR_UE/main_ue.c
@@ -34,8 +34,9 @@
#include "rrc_proto.h"
#include "common/utils/LOG/log.h"
-NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path){
- //LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n");
+NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* reconfig_file, char* rbconfig_file)
+{
+ // LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n");
- return openair_rrc_top_init_ue_nr(uecap,rrc_config_path);
+ return openair_rrc_top_init_ue_nr(uecap, reconfig_file, rbconfig_file);
}
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index bf9861ecfb..73c3fa1593 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -344,8 +344,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
}
-
-NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path)
+NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file)
{
if(NB_NR_UE_INST > 0) {
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t));
@@ -368,30 +367,24 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
// read in files for RRCReconfiguration and RBconfig
- FILE *fd;
- char filename[1024];
- if (rrc_config_path)
- sprintf(filename,"%s/reconfig.raw",rrc_config_path);
- else
- sprintf(filename,"reconfig.raw");
- fd = fopen(filename,"r");
- char buffer[1024];
+
+ LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file);
+ FILE *fd = fopen(reconfig_file,"r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
- filename,
+ reconfig_file,
errno,
strerror(errno));
+ char buffer[1024];
int msg_len=fread(buffer,1,1024,fd);
fclose(fd);
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
- if (rrc_config_path)
- sprintf(filename,"%s/rbconfig.raw",rrc_config_path);
- else
- sprintf(filename,"rbconfig.raw");
- fd = fopen(filename,"r");
+
+ LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", rbconfig_file);
+ fd = fopen(rbconfig_file,"r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
- filename,
+ rbconfig_file,
errno,
strerror(errno));
msg_len=fread(buffer,1,1024,fd);
@@ -414,7 +407,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_
return NR_UE_rrc_inst;
}
-
int8_t nr_ue_process_rlc_bearer_list(NR_CellGroupConfig_t *cell_group_config){
return 0;
@@ -1683,7 +1675,6 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
// Refresh DRBs
nr_pdcp_add_drbs(ctxt_pP->enb_flag,
ctxt_pP->rntiMaybeUEid,
- 0,
radioBearerConfig->drb_ToAddModList,
ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4),
kUPenc,
diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index 55e025e0f1..df2d44a996 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -56,16 +56,14 @@ extern queue_t nr_ul_tti_req_queue;
// main_rrc.c
//
/**\brief Layer 3 initialization*/
-NR_UE_RRC_INST_t* nr_l3_init_ue(char*,char*);
+NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *);
//
// UE_rrc.c
//
/**\brief Initial the top level RRC structure instance*/
-NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*,char*);
-
-
+NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *);
/**\brief Decode RRC Connection Reconfiguration, sent from E-UTRA RRC Connection Reconfiguration v1510 carring EN-DC config
\param buffer encoded NR-RRC-Connection-Reconfiguration/Secondary-Cell-Group-Config message.
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index 5a75b8953a..d7cc496439 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -768,31 +768,31 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance,
return !GTPNOK;
}
-int gtpv1u_update_ngu_tunnel(const instance_t instanceP, const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, const ue_id_t prior_ue_id)
+int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id)
{
- LOG_D(GTPU, "[%ld] Update tunnels from UEid %lx to UEid %lx\n", instanceP, prior_ue_id, create_tunnel_req_pP->ue_id);
-
pthread_mutex_lock(&globGtp.gtp_lock);
auto inst = &globGtp.instances[compatInst(instanceP)];
- auto it = inst->ue2te_mapping.find(prior_ue_id);
+ auto it = inst->ue2te_mapping.find(old_ue_id);
if (it == inst->ue2te_mapping.end()) {
- LOG_W(GTPU, "[%ld] Delete GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, prior_ue_id);
+ LOG_W(GTPU, "[%ld] Update GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, old_ue_id);
pthread_mutex_unlock(&globGtp.gtp_lock);
return GTPNOK;
}
- for (int i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
- teid_t incoming_teid = inst->ue2te_mapping[prior_ue_id].bearers[create_tunnel_req_pP->pdusession_id[i]].teid_incoming;
- if (globGtp.te2ue_mapping[incoming_teid].ue_id == prior_ue_id) {
- globGtp.te2ue_mapping[incoming_teid].ue_id = create_tunnel_req_pP->ue_id;
+ for (unsigned i = 0; i < it->second.bearers.size(); ++i) {
+ teid_t incoming_teid = inst->ue2te_mapping[old_ue_id].bearers[i].teid_incoming;
+ if (globGtp.te2ue_mapping[incoming_teid].ue_id == old_ue_id) {
+ globGtp.te2ue_mapping[incoming_teid].ue_id = new_ue_id;
}
}
- inst->ue2te_mapping[create_tunnel_req_pP->ue_id] = it->second;
+ inst->ue2te_mapping[new_ue_id] = it->second;
inst->ue2te_mapping.erase(it);
pthread_mutex_unlock(&globGtp.gtp_lock);
+
+ LOG_I(GTPU, "[%ld] Updated tunnels from UEid %lx to UEid %lx\n", instanceP, old_ue_id, new_ue_id);
return !GTPNOK;
}
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
index 9592070ca9..f8228677fc 100644
--- a/openair3/ocp-gtpu/gtp_itf.h
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -76,11 +76,8 @@ extern "C" {
int gtpv1u_delete_ngu_tunnel( const instance_t instance,
gtpv1u_gnb_delete_tunnel_req_t *req);
-
- int gtpv1u_update_ngu_tunnel( const instance_t instanceP,
- const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
- const ue_id_t prior_rnti
- );
+
+ int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id);
// New API
teid_t newGtpuCreateTunnel(instance_t instance,
diff --git a/radio/ETHERNET/CMakeLists.txt b/radio/ETHERNET/CMakeLists.txt
index 52aebdcc1a..8c6590c6e9 100644
--- a/radio/ETHERNET/CMakeLists.txt
+++ b/radio/ETHERNET/CMakeLists.txt
@@ -3,6 +3,7 @@ add_library(oai_eth_transpro MODULE
eth_udp.c
eth_raw.c
)
+target_link_libraries(oai_eth_transpro PRIVATE ${T_LIB})
target_include_directories(oai_eth_transpro PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(oai_eth_transpro PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_command(TARGET oai_eth_transpro POST_BUILD
diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp
index 06b0c9bace..03058869e8 100644
--- a/radio/USRP/usrp_lib.cpp
+++ b/radio/USRP/usrp_lib.cpp
@@ -269,11 +269,6 @@ static void trx_usrp_start_interdigital_gpio(openair0_device *device, usrp_state
{
AssertFatal(device->type == USRP_X400_DEV,
"interdigital frontend device for beam management can only be used together with an X400\n");
-
- // s->gpio_bank="GPIO0";
- std::vector sxx{12, "DB0_RF0"};
- // set every pin on GPIO0 to be ocntrolled by DB1_RF0
- s->usrp->set_gpio_src(s->gpio_bank, sxx);
// set data direction register (DDR) to output
s->usrp->set_gpio_attr(s->gpio_bank, "DDR", 0xfff, 0xfff);
// set lower GPIO#1 to be controlled automatically by ATR (the rest bits are controlled manually)
diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md
index e8baff472c..1974e55f50 100644
--- a/radio/rfsimulator/README.md
+++ b/radio/rfsimulator/README.md
@@ -119,23 +119,15 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78
### Launch UE in another window
```bash
-sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . --rfsimulator.serveraddr
+sudo ./nr-uesoftmodem --rfsim --phy-test --rfsimulator.serveraddr
```
Notes:
-1. This starts the gNB and UE in the `phy-test` UP-only mode where the gNB is started as if a UE had already connected, and a configurable scheduler is used instead of the default one. The options `-m`, `-l`, `-t`, `-M`, `-T`, `-D`, and `-U` can be used to configure this scheduler.
+1. This starts the gNB and UE in the `phy-test` UP-only mode where the gNB is started as if a UE had already connected. See [RUNMODEM.md](../../doc/RUNMODEM.md) for more details.
2. can be 127.0.0.1 if both gNB and nrUE executables run on the same host, OR the IP interface address of the remote host running the gNB executable, if the gNB and nrUE run on separate hosts.
-3. The --rrc_config_path parameter SHALL specify where the 2 RAW files are located (`rbconfig.raw` and `reconfig.raw`).
- - If you are running on the same machine and launched the 2 executables (`nr-softmodem` and `nr-uesoftmodem`) from the same directory, nothing has to be done.
- - If you launched the 2 executables from 2 different folders, just point to the location where you launched the `nr-softmodem`:
- * `sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path /the/path/where/you/launched/nr-softmodem --rfsimulator.serveraddr `
- - If you are not running on the same machine or launched the 2 executables from 2 different folders, you need to **COPY** the 2 raw files
- * `scp usera@machineA:/the/path/where/you/launched/nr-softmodem/r*config.raw userb@machineB:/the/path/where/you/will/launch/nr-uesoftmodem/`
- * Obviously this operation SHALL be done before launching the `nr-uesoftmodem` executable.
-4. To enable the noS1 mode, `--noS1` option should be added to the command line.
-5. To operate the gNB/UE with a 5GC, start them using the `--sa` option. More information can be found [here](../../../doc/NR_SA_Tutorial_OAI_CN5G.md).
-
+3. To enable the noS1 mode, `--noS1` option should be added to the command line, see again [RUNMODEM.md](../../doc/RUNMODEM.md).
+4. To operate the gNB/UE with a 5GC, start them using the `--sa` option. More information can be found [here](../../../doc/NR_SA_Tutorial_OAI_CN5G.md).
In the UE, you can add `-d` option to get the softscope.
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf
similarity index 100%
rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf
rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf
similarity index 100%
rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf
rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band261.fr2.64PRB.usrpx310.conf
similarity index 100%
rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf
rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band261.fr2.64PRB.usrpx310.conf
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf
similarity index 100%
rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf
rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf