diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container
index 118eb844d4..ebb2fbd5e0 100644
--- a/ci-scripts/Jenkinsfile-GitLab-Container
+++ b/ci-scripts/Jenkinsfile-GitLab-Container
@@ -425,28 +425,26 @@ pipeline {
}
}
}
-
- //avra is offline, re-enable once it is available
- //stage ("T1-Offload-Test") {
- // when { expression {do5Gtest} }
- // steps {
- // script {
- // triggerSlaveJob ('RAN-T1-Offload-Test', 'T1-Offload-Test')
- // }
- // }
- // post {
- // always {
- // script {
- // finalizeSlaveJob('RAN-T1-Offload-Test')
- // }
- // }
- // failure {
- // script {
- // currentBuild.result = 'FAILURE'
- // }
- // }
- // }
- //}
+ stage ("Interop-F1") {
+ when { expression {do5Gtest} }
+ steps {
+ script {
+ triggerSlaveJob ('RAN-Interop-F1', 'Interop-F1')
+ }
+ }
+ post {
+ always {
+ script {
+ finalizeSlaveJob('RAN-Interop-F1')
+ }
+ }
+ failure {
+ script {
+ currentBuild.result = 'FAILURE'
+ }
+ }
+ }
+ }
}
}
stage ("DockerHub-Push") {
diff --git a/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran.xml b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran.xml
new file mode 100644
index 0000000000..d727fdfd1e
--- /dev/null
+++ b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran.xml
@@ -0,0 +1,74 @@
+
+
+ rfsim-5gnr-f1-accelleran
+ F1 DU Interop Accelleran CU
+ wrench
+
+ 111111
+ 000020
+ 000021
+ 020021
+ 100021
+ 100022
+
+
+
+
+ Pull_Local_Registry
+ Pull Images from Local Registry
+ 0
+ oai-gnb oai-nr-ue
+
+
+
+ DeployGenObject
+ Deploy OAI-DU
+ yaml_files/5g_rfsimulator_accelleran
+ oai-du
+ 1
+
+
+
+ DeployGenObject
+ Deploy nrUE
+ yaml_files/5g_rfsimulator_accelleran
+ oai-nr-ue
+ 2
+
+
+
+ PingFromContainer
+ Test Connectivity (ping)
+ rfsim5g-oai-nr-ue
+ -I oaitun_ue1 -c 20 12.1.1.1
+ 0
+
+
+
+ UndeployGenObject
+ Undeploy all OAI 5G stack
+ yaml_files/5g_rfsimulator_accelleran
+
+
+
diff --git a/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran_down.xml b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran_down.xml
new file mode 100644
index 0000000000..0a4f9fcbfa
--- /dev/null
+++ b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran_down.xml
@@ -0,0 +1,45 @@
+
+
+ rfsim-5gnr-down-f1-accelleran
+ CleanUp
+ trash
+
+ 100022
+ 222222
+
+
+
+
+ UndeployGenObject
+ Undeploy all OAI 5G stack
+ yaml_files/5g_rfsimulator_accelleran
+
+
+
+ Clean_Test_Server_Images
+ Clean Test Images on Test Server
+ 0
+
+
+
diff --git a/ci-scripts/yaml_files/5g_rfsimulator_accelleran/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_accelleran/docker-compose.yaml
new file mode 100644
index 0000000000..3551cc27c6
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator_accelleran/docker-compose.yaml
@@ -0,0 +1,38 @@
+version: '3.8'
+services:
+ oai-du:
+ image: oaisoftwarealliance/oai-gnb:develop
+ privileged: true
+ container_name: rfsim5g-oai-du
+ network_mode: "host"
+ environment:
+ RFSIMULATOR: server
+ USE_VOLUMED_CONF: 'yes'
+ USE_ADDITIONAL_OPTIONS: --sa --rfsim --MACRLCs.[0].local_n_address 172.21.16.109 --MACRLCs.[0].remote_n_address 172.21.6.22 --log_config.global_log_options level,nocolor,time
+ volumes:
+ - ../../conf_files/gnb-du.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/mounted.conf
+ healthcheck:
+ test: /bin/bash -c "pgrep nr-softmodem"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ oai-nr-ue:
+ image: oaisoftwarealliance/oai-nr-ue:develop
+ privileged: true
+ container_name: rfsim5g-oai-nr-ue
+ network_mode: "host"
+ environment:
+ RFSIMULATOR: 127.0.0.1
+ FULL_IMSI: '208990100001140'
+ FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+ OPC: 'C42449363BBAD02B66D16BC975D77CC1'
+ DNN: oai
+ NSSAI_SST: 1
+ USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 -C 3619200000 --log_config.global_log_options level,nocolor,time
+ depends_on:
+ - oai-du
+ healthcheck:
+ test: /bin/bash -c "pgrep nr-uesoftmodem"
+ interval: 10s
+ timeout: 5s
+ retries: 5
diff --git a/doc/F1-design.md b/doc/F1-design.md
index 80417b1ae3..7e491f5346 100644
--- a/doc/F1-design.md
+++ b/doc/F1-design.md
@@ -11,6 +11,7 @@
+
# 1. Introduction
We use OpenAirInterface source code, and it's regular deployment scheme.
@@ -208,3 +209,46 @@ DU rlc north output goes to du_pdcp_data_ind() that push a outgoing packet reque
CU pdcp south output calls cu_rlc_data_ind() that do the same symetric processing.
+# High-level F1-C code structure
+
+The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC)
+to exchange information. In DL, the CU sends messages as defined by the
+callbacks in `mac_rrc_dl.h`, whose implementation is defined in files
+`mac_rrc_dl_direct.c` (monolithic) and `mac_rrc_dl_f1ap.c` (for F1AP). In the
+monolithic case, the RRC calls directly into the message handler on the DU side
+(`mac_rrc_dl_handler.c`). In the F1 case, an ITTI message is sent to the CU
+task, sending an ASN.1-encoded F1AP message. The DU side's DU task decodes the
+message, and then calls the corresponding handler in `mac_rrc_dl_handler.c`.
+Thus, the message flow is the same in both F1 and monolithic cases, with the
+difference that F1AP encodes the messages using ASN.1 and sends over a socket.
+
+In UL, the callbacks defined in `mac_rrc_ul.h` are implemented by
+`mac_rrc_ul_direct.c` (monolithic) and `mac_rrc_ul_f1ap.c` (F1). In the direct
+case, an ITTI message is directly sent to the RRC task (hence, there is no
+dedicated handler). In F1, the DU task receives the ITTI message, encodes using
+ASN.1, and sends it over a network socket. The CU task decodes, and sends the
+same ITTI message to the RRC task as done directly in the monolithic case.
+
+```
+ +-------------+
+ | |
+ | CU/RRC |
+ | |
+ +-------------+
+ | ^
+ Callback def: mac_rrc_dl.h | | No handler needed:
+ F1 impl: mac_rrc_dl_f1ap.c | | RRC has ITTI
+Monolithic: mac_rrc_dl_direct.c | |
+ | |
+ DL | | UL
+ | |
+ | | Callback def: mac_rrc_ul.h
+ Message handler: | | F1 impl: mac_rrc_ul_f1ap.c
+ mac_rrc_dl_handler.c | | Monolithic: mac_rrc_ul_direct.c
+ v |
+ +-------------+
+ | |
+ | DU/MAC |
+ | |
+ +-------------+
+```
diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md
index aef3a7f63e..3f50abaa11 100644
--- a/doc/TESTBenches.md
+++ b/doc/TESTBenches.md
@@ -82,6 +82,9 @@ Webhook
- [RAN-gNB-N300-Timing-Phytest-LDPC](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-gNB-N300-Timing-Phytest-LDPC/)
- caracal + N310
- pure performance test through phy-test scheduler, see command line for more details
+- [RAN-Interop-F1](https://jenkins-oai.eurecom.fr/job/RAN-Interop-F1/)
+ - ofqot (DU, 1x UE)
+ - F1 interoperability testing: sets up connection to Accelleran CU, UE connection and connectivity test
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/)
- obelix (eNB, 1x UE, OAI EPC)
- L2simulator: skips physical layer and uses proxy between eNB and UE
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index a7465ad99b..0007a3b4d1 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -1010,7 +1010,10 @@ int main(int argc, char **argv)
UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
+ // nr_schedule_ue_spec() requires the mutex to be locked
+ NR_SCHED_LOCK(&gNB_mac->sched_lock);
nr_schedule_ue_spec(0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req);
+ NR_SCHED_UNLOCK(&gNB_mac->sched_lock);
Sched_INFO->module_id = 0;
Sched_INFO->CC_id = 0;
Sched_INFO->frame = frame;
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index fbe8388714..4c119dd8ad 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -35,6 +35,7 @@
#include "f1ap_decoder.h"
#include "f1ap_itti_messaging.h"
#include "f1ap_du_ue_context_management.h"
+#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
#include "rrc_extern.h"
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
@@ -65,13 +66,13 @@ bool lteDURecvCb(protocol_ctxt_t *ctxt_pP,
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
- F1AP_F1AP_PDU_t *pdu) {
- MessageDef *msg_p; // message to RRC
+ F1AP_F1AP_PDU_t *pdu)
+{
F1AP_UEContextSetupRequest_t *container;
int i;
DevAssert(pdu);
- msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_REQ);
- f1ap_ue_context_setup_t *f1ap_ue_context_setup_req = &F1AP_UE_CONTEXT_SETUP_REQ(msg_p);
+ f1ap_ue_context_setup_t ue_context_setup = {0};
+ f1ap_ue_context_setup_t *f1ap_ue_context_setup_req = &ue_context_setup;
container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest;
/* GNB_CU_UE_F1AP_ID */
F1AP_UEContextSetupRequestIEs_t *ieCU;
@@ -224,8 +225,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
LOG_W(F1AP, "can't find RRCContainer in UEContextSetupRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
}
- itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
-
+ ue_context_setup_request(f1ap_ue_context_setup_req);
return 0;
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 1a72fa951d..4ba189c4bd 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -99,73 +99,52 @@ static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddMo
static void process_drx_Config(NR_UE_sched_ctrl_t *sched_ctrl, NR_SetupRelease_DRX_Config_t *drx_Config)
{
-
- if (!drx_Config) return;
- AssertFatal(drx_Config->present != NR_SetupRelease_DRX_Config_PR_NOTHING, "Cannot have NR_SetupRelease_DRX_Config_PR_NOTHING\n");
-
- if (drx_Config->present == NR_SetupRelease_DRX_Config_PR_setup) {
- LOG_I(NR_MAC,"Adding DRX config\n");
- }
- else {
- LOG_I(NR_MAC,"Removing DRX config\n");
- }
+ AssertFatal(false, "%s() not implemented\n", __func__);
+ AssertFatal(drx_Config->present != NR_SetupRelease_DRX_Config_PR_NOTHING, "Cannot have NR_SetupRelease_DRX_Config_PR_NOTHING\n");
}
static void process_schedulingRequestConfig(NR_UE_sched_ctrl_t *sched_ctrl, NR_SchedulingRequestConfig_t *schedulingRequestConfig)
{
- if (!schedulingRequestConfig) return;
-
- LOG_I(NR_MAC,"Adding SchedulingRequestconfig\n");
+ AssertFatal(false, "%s() not implemented\n", __func__);
}
static void process_bsrConfig(NR_UE_sched_ctrl_t *sched_ctrl, NR_BSR_Config_t *bsr_Config)
{
- if (!bsr_Config) return;
- LOG_I(NR_MAC,"Adding BSR config\n");
+ AssertFatal(false, "%s() not implemented\n", __func__);
}
static void process_tag_Config(NR_UE_sched_ctrl_t *sched_ctrl, NR_TAG_Config_t *tag_Config)
{
- if (!tag_Config) return;
- LOG_I(NR_MAC,"Adding TAG config\n");
+ AssertFatal(false, "%s() not implemented\n", __func__);
}
static void process_phr_Config(NR_UE_sched_ctrl_t *sched_ctrl, NR_SetupRelease_PHR_Config_t *phr_Config)
{
- if (!phr_Config) return;
- AssertFatal(phr_Config->present != NR_SetupRelease_PHR_Config_PR_NOTHING, "Cannot have NR_SetupRelease_PHR_Config_PR_NOTHING\n");
-
- if (phr_Config->present == NR_SetupRelease_PHR_Config_PR_setup) {
- LOG_I(NR_MAC,"Adding PHR config\n");
- }
- else {
- LOG_I(NR_MAC,"Removing PHR config\n");
- }
+ AssertFatal(false, "%s() not implemented\n", __func__);
}
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl)
{
+ /* we assume that this function is mutex-protected from outside */
+ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock);
+
AssertFatal(CellGroup, "CellGroup is null\n");
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = CellGroup->mac_CellGroupConfig;
if (mac_CellGroupConfig) {
- process_drx_Config(sched_ctrl,mac_CellGroupConfig->drx_Config);
- process_schedulingRequestConfig(sched_ctrl,mac_CellGroupConfig->schedulingRequestConfig);
- process_bsrConfig(sched_ctrl,mac_CellGroupConfig->bsr_Config);
- process_tag_Config(sched_ctrl,mac_CellGroupConfig->tag_Config);
- process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config);
- }
- else {
- // apply defaults
-
+ //process_drx_Config(sched_ctrl,mac_CellGroupConfig->drx_Config);
+ //process_schedulingRequestConfig(sched_ctrl,mac_CellGroupConfig->schedulingRequestConfig);
+ //process_bsrConfig(sched_ctrl,mac_CellGroupConfig->bsr_Config);
+ //process_tag_Config(sched_ctrl,mac_CellGroupConfig->tag_Config);
+ //process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config);
}
process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList,CellGroup->rlc_BearerToReleaseList,sched_ctrl);
}
-void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
-
+static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc)
+{
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
nrmac->common_channels[0].ServingCellConfigCommon = scc;
@@ -460,19 +439,23 @@ void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_Antenn
}
}
-int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_SubcarrierSpacing_t subcarrierSpacing, uint32_t rrc_reconfiguration_delay) {
-
+int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_SubcarrierSpacing_t subcarrierSpacing, uint32_t rrc_reconfiguration_delay)
+{
if (rrc_reconfiguration_delay == 0) {
return -1;
}
- NR_UE_info_t *UE_info = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti);
+ gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+ NR_SCHED_LOCK(&nrmac->sched_lock);
+
+ NR_UE_info_t *UE_info = find_nr_UE(&nrmac->UE_info,rnti);
if (!UE_info) {
LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return -1;
}
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
- const uint16_t sl_ahead = RC.nrmac[Mod_idP]->if_inst->sl_ahead;
+ const uint16_t sl_ahead = nrmac->if_inst->sl_ahead;
sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<rnti, rrc_reconfiguration_delay);
@@ -480,8 +463,9 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S
// processing timer. To prevent this, set a variable as if we would have just
// sent it. This way, another TA command will for sure be sent in some
// frames, after RRC processing timer.
- sched_ctrl->ta_frame = (RC.nrmac[Mod_idP]->frame - 1 + 1024) % 1024;
+ sched_ctrl->ta_frame = (nrmac->frame - 1 + 1024) % 1024;
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return 0;
}
@@ -494,6 +478,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac,
{
DevAssert(nrmac != NULL);
AssertFatal(nrmac->common_channels[0].ServingCellConfigCommon == NULL, "logic error: multiple configurations of SCC\n");
+ NR_SCHED_LOCK(&nrmac->sched_lock);
DevAssert(scc != NULL);
AssertFatal(scc->ssb_PositionsInBurst->present > 0 && scc->ssb_PositionsInBurst->present < 4,
@@ -573,26 +558,31 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac,
ra->preambles.preamble_list[i] = i;
}
}
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
void nr_mac_config_mib(gNB_MAC_INST *nrmac, NR_BCCH_BCH_Message_t *mib)
{
DevAssert(nrmac != NULL);
DevAssert(mib != NULL);
+ NR_SCHED_LOCK(&nrmac->sched_lock);
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
AssertFatal(cc->mib == NULL, "logic bug: updated MIB multiple times\n");
cc->mib = mib;
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
void nr_mac_config_sib1(gNB_MAC_INST *nrmac, NR_BCCH_DL_SCH_Message_t *sib1)
{
DevAssert(nrmac != NULL);
DevAssert(sib1 != NULL);
+ NR_SCHED_LOCK(&nrmac->sched_lock);
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
AssertFatal(cc->sib1 == NULL, "logic bug: updated SIB1 multiple times\n");
cc->sib1 = sib1;
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
@@ -600,16 +590,17 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t
DevAssert(nrmac != NULL);
DevAssert(CellGroup != NULL);
DevAssert(get_softmodem_params()->phy_test);
+ NR_SCHED_LOCK(&nrmac->sched_lock);
NR_UE_info_t* UE = add_new_nr_ue(nrmac, rnti, CellGroup);
if (UE) {
LOG_I(NR_MAC,"Force-added new UE %x with initial CellGroup\n", rnti);
+ process_CellGroup(CellGroup,&UE->UE_sched_ctrl);
} else {
LOG_E(NR_MAC,"Error adding UE %04x\n", rnti);
- return false;
}
- process_CellGroup(CellGroup,&UE->UE_sched_ctrl);
- return true;
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
+ return UE != NULL;
}
bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
@@ -617,6 +608,7 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo
DevAssert(nrmac != NULL);
DevAssert(CellGroup != NULL);
DevAssert(!get_softmodem_params()->phy_test);
+ NR_SCHED_LOCK(&nrmac->sched_lock);
// NSA case: need to pre-configure CFRA
const int CC_id = 0;
@@ -628,6 +620,7 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo
}
if (ra_index == NR_NB_RA_PROC_MAX) {
LOG_E(NR_MAC, "RA processes are not available for CFRA RNTI %04x\n", rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return false;
}
NR_RA_t *ra = &cc->ra[ra_index];
@@ -656,12 +649,16 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo
}
}
LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return true;
}
bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
{
DevAssert(nrmac != NULL);
+ /* we assume that this function is mutex-protected from outside */
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
+
DevAssert(CellGroup != NULL);
NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, rnti);
@@ -677,58 +674,7 @@ bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCon
exit(1);
}
- nr_mac_update_RA(nrmac, rnti, CellGroup);
process_CellGroup(CellGroup, &UE->UE_sched_ctrl);
return true;
}
-
-bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
-{
- // Checking for free RA process
- NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
- uint8_t ra_index = 0;
- for (; ra_index < NR_NB_RA_PROC_MAX; ra_index++) {
- if ((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra))
- break;
- }
- if (ra_index == NR_NB_RA_PROC_MAX) {
- LOG_E(NR_MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
- return -1;
- }
-
- NR_RA_t *ra = &cc->ra[ra_index];
- if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
- && CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated != NULL) {
- if (CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
- ra->cfra = true;
- ra->rnti = rnti;
- ra->CellGroup = CellGroup;
- struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
- uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
- ra->preambles.num_preambles = num_preamble;
- ra->preambles.preamble_list = (uint8_t *)malloc(num_preamble * sizeof(uint8_t));
- for (int i = 0; i < cc->num_active_ssb; i++) {
- for (int j = 0; j < num_preamble; j++) {
- if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
- // One dedicated preamble for each beam
- ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
- break;
- }
- }
- }
- }
- } else {
- ra->cfra = false;
- ra->rnti = 0;
- if (ra->preambles.preamble_list == NULL) {
- ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
- ra->preambles.preamble_list = (uint8_t *)malloc(MAX_NUM_NR_PRACH_PREAMBLES * sizeof(uint8_t));
- for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
- ra->preambles.preamble_list[i] = i;
- }
- }
- LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", rnti);
-
- return true;
-}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index e831f6d4a8..2d4cd16eb4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -63,6 +63,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
nfapi_nr_tx_data_request_t *TX_req,
nfapi_nr_ul_dci_request_t *UL_dci_req)
{
+ /* called below and in simulators, so we assume a lock but don't require it */
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
@@ -149,6 +150,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ NR_SCHED_LOCK(&gNB->sched_lock);
+
if (slot==0 && (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]>=257)) {
//FR2
const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
@@ -254,6 +257,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]);
stop_meas(&gNB->eNB_scheduler);
-
+ NR_SCHED_UNLOCK(&gNB->sched_lock);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 2461d9618d..fb78ff0d13 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -49,17 +49,32 @@ extern RAN_CONTEXT_t RC;
extern const uint8_t nr_slots_per_frame[5];
extern uint16_t sl_ahead;
+// forward declaration of functions used in this file
+static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
+ NR_ServingCellConfigCommon_t *scc,
+ int round,
+ int startSymbolAndLength,
+ rnti_t rnti,
+ int scs,
+ int bwp_size,
+ int bwp_start,
+ int mappingtype,
+ int fh,
+ int msg3_first_rb,
+ int msg3_nb_rb);
+static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu);
+
static const uint8_t DELTA[4] = {2, 3, 4, 6};
static const float ssb_per_rach_occasion[8] = {0.125, 0.25, 0.5, 1, 2, 4, 8};
-int16_t ssb_index_from_prach(module_id_t module_idP,
- frame_t frameP,
- sub_frame_t slotP,
- uint16_t preamble_index,
- uint8_t freq_index,
- uint8_t symbol) {
-
+static int16_t ssb_index_from_prach(module_id_t module_idP,
+ frame_t frameP,
+ sub_frame_t slotP,
+ uint16_t preamble_index,
+ uint8_t freq_index,
+ uint8_t symbol)
+{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &gNB->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -139,10 +154,12 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
return index;
}
-
//Compute Total active SSBs and RO available
void find_SSB_and_RO_available(gNB_MAC_INST *nrmac)
{
+ /* already mutex protected through nr_mac_config_scc() */
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
+
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
@@ -242,6 +259,9 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac)
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock);
+
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int mu;
@@ -399,15 +419,20 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
}
}
-void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
- uint16_t *msg2_frame, uint16_t *msg2_slot,
- int mu, NR_ServingCellConfigCommon_t *scc,
- frame_type_t frame_type,
- uint16_t monitoring_slot_period,
- uint16_t monitoring_offset,uint8_t beam_index,
- uint8_t num_active_ssb,
- int16_t *tdd_beam_association, int sl_ahead){
-
+static void nr_schedule_msg2(uint16_t rach_frame,
+ uint16_t rach_slot,
+ uint16_t *msg2_frame,
+ uint16_t *msg2_slot,
+ int mu,
+ NR_ServingCellConfigCommon_t *scc,
+ frame_type_t frame_type,
+ uint16_t monitoring_slot_period,
+ uint16_t monitoring_offset,
+ uint8_t beam_index,
+ uint8_t num_active_ssb,
+ int16_t *tdd_beam_association,
+ int sl_ahead)
+{
// preferentially we schedule the msg2 in the mixed slot or in the last dl slot
// if they are allowed by search space configuration
uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
@@ -516,12 +541,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
uint16_t preamble_index,
uint8_t freq_index,
uint8_t symbol,
- int16_t timing_offset){
+ int16_t timing_offset)
+{
+ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+ NR_SCHED_LOCK(&nr_mac->sched_lock);
uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
-
uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset;
- gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
frame_type_t frame_type = cc->frame_type;
@@ -655,57 +681,22 @@ void nr_initiate_ra_proc(module_id_t module_idP,
cc->ssb_index[beam_index],
i);
+ NR_SCHED_UNLOCK(&nr_mac->sched_lock);
return;
}
+
+ NR_SCHED_UNLOCK(&nr_mac->sched_lock);
LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
-void nr_schedule_RA(module_id_t module_idP,
- frame_t frameP,
- sub_frame_t slotP,
- nfapi_nr_ul_dci_request_t *ul_dci_req,
- nfapi_nr_dl_tti_request_t *DL_req,
- nfapi_nr_tx_data_request_t *TX_req)
-{
- gNB_MAC_INST *mac = RC.nrmac[module_idP];
-
- start_meas(&mac->schedule_ra);
- for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
- NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
- for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
- NR_RA_t *ra = &cc->ra[i];
- LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
- switch (ra->state) {
- case Msg2:
- nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
- break;
- case Msg3_retransmission:
- nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
- break;
- case Msg3_dcch_dtch:
- nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
- case Msg4:
- nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
- break;
- case WAIT_Msg4_ACK:
- nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
- break;
- default:
- break;
- }
- }
- }
- stop_meas(&mac->schedule_ra);
-}
-
-void nr_generate_Msg3_retransmission(module_id_t module_idP,
- int CC_id,
- frame_t frame,
- sub_frame_t slot,
- NR_RA_t *ra,
- nfapi_nr_ul_dci_request_t *ul_dci_req)
+static void nr_generate_Msg3_retransmission(module_id_t module_idP,
+ int CC_id,
+ frame_t frame,
+ sub_frame_t slot,
+ NR_RA_t *ra,
+ nfapi_nr_ul_dci_request_t *ul_dci_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
@@ -877,15 +868,14 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP,
}
}
-void nr_get_Msg3alloc(module_id_t module_id,
- int CC_id,
- NR_ServingCellConfigCommon_t *scc,
- sub_frame_t current_slot,
- frame_t current_frame,
- NR_RA_t *ra,
- int16_t *tdd_beam_association)
+static void nr_get_Msg3alloc(module_id_t module_id,
+ int CC_id,
+ NR_ServingCellConfigCommon_t *scc,
+ sub_frame_t current_slot,
+ frame_t current_frame,
+ NR_RA_t *ra,
+ int16_t *tdd_beam_association)
{
-
// msg3 is scheduled in mixed slot in the following TDD period
uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes
@@ -999,16 +989,19 @@ void nr_get_Msg3alloc(module_id_t module_id,
ra->msg3_bwp_start = bwpStart;
}
-
-void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
- NR_ServingCellConfigCommon_t *scc,
- int round,
- int startSymbolAndLength,
- rnti_t rnti, int scs,
- int bwp_size, int bwp_start,
- int mappingtype, int fh,
- int msg3_first_rb, int msg3_nb_rb) {
-
+static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
+ NR_ServingCellConfigCommon_t *scc,
+ int round,
+ int startSymbolAndLength,
+ rnti_t rnti,
+ int scs,
+ int bwp_size,
+ int bwp_start,
+ int mappingtype,
+ int fh,
+ int msg3_first_rb,
+ int msg3_nb_rb)
+{
int start_symbol_index,nr_of_symbols;
SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
@@ -1087,7 +1080,7 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
}
}
-void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu)
+static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu)
{
gNB_MAC_INST *mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
@@ -1155,13 +1148,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
}
-void nr_generate_Msg2(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_dl_tti_request_t *DL_req,
- nfapi_nr_tx_data_request_t *TX_req)
+
+static void nr_generate_Msg2(module_id_t module_idP,
+ int CC_id,
+ frame_t frameP,
+ sub_frame_t slotP,
+ NR_RA_t *ra,
+ nfapi_nr_dl_tti_request_t *DL_req,
+ nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
@@ -1427,22 +1421,29 @@ void nr_generate_Msg2(module_id_t module_idP,
}
}
-void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
- NR_RA_t *ra,
- NR_UE_DL_BWP_t *dl_bwp,
- nfapi_nr_dl_tti_request_body_t *dl_req,
- NR_sched_pucch_t *pucch,
- NR_pdsch_dmrs_t dmrs_info,
- NR_tda_info_t tda,
- int aggregation_level,
- int CCEIndex,
- int tb_size, int ndi,
- int tpc, int delta_PRI,
- int current_harq_pid,
- int time_domain_assignment,
- int CC_id, int rnti, int round,
- int mcsIndex, int tb_scaling,
- int pduindex, int rbStart, int rbSize)
+static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
+ NR_RA_t *ra,
+ NR_UE_DL_BWP_t *dl_bwp,
+ nfapi_nr_dl_tti_request_body_t *dl_req,
+ NR_sched_pucch_t *pucch,
+ NR_pdsch_dmrs_t dmrs_info,
+ NR_tda_info_t tda,
+ int aggregation_level,
+ int CCEIndex,
+ int tb_size,
+ int ndi,
+ int tpc,
+ int delta_PRI,
+ int current_harq_pid,
+ int time_domain_assignment,
+ int CC_id,
+ int rnti,
+ int round,
+ int mcsIndex,
+ int tb_scaling,
+ int pduindex,
+ int rbStart,
+ int rbSize)
{
// look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
// important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
@@ -1613,13 +1614,13 @@ void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
}
-void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_dl_tti_request_t *DL_req,
- nfapi_nr_tx_data_request_t *TX_req)
+static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
+ int CC_id,
+ frame_t frameP,
+ sub_frame_t slotP,
+ NR_RA_t *ra,
+ nfapi_nr_dl_tti_request_t *DL_req,
+ nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
@@ -1799,13 +1800,13 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
sched_ctrl->ul_failure = 0;
}
-void nr_generate_Msg4(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_dl_tti_request_t *DL_req,
- nfapi_nr_tx_data_request_t *TX_req)
+static void nr_generate_Msg4(module_id_t module_idP,
+ int CC_id,
+ frame_t frameP,
+ sub_frame_t slotP,
+ NR_RA_t *ra,
+ nfapi_nr_dl_tti_request_t *DL_req,
+ nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
@@ -2056,8 +2057,8 @@ void nr_generate_Msg4(module_id_t module_idP,
}
}
-void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
-
+static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra)
+{
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti);
const int current_harq_pid = ra->harq_pid;
@@ -2098,7 +2099,10 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
}
}
-void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra){
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra)
+{
+ /* we assume that this function is mutex-protected from outside */
+ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_idP]->sched_lock);
LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
ra->state = RA_IDLE;
ra->timing_offset = 0;
@@ -2141,11 +2145,8 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t
// - sending only 1 RAR subPDU
// - UL Grant: hardcoded CSI, TPC, time alloc
// - padding
-void nr_fill_rar(uint8_t Mod_idP,
- NR_RA_t * ra,
- uint8_t * dlsch_buffer,
- nfapi_nr_pusch_pdu_t *pusch_pdu){
-
+static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu)
+{
LOG_D(NR_MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset);
NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer;
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1);
@@ -2239,3 +2240,43 @@ void nr_fill_rar(uint8_t Mod_idP,
csi_req,
t_crnti);
}
+
+void nr_schedule_RA(module_id_t module_idP,
+ frame_t frameP,
+ sub_frame_t slotP,
+ nfapi_nr_ul_dci_request_t *ul_dci_req,
+ nfapi_nr_dl_tti_request_t *DL_req,
+ nfapi_nr_tx_data_request_t *TX_req)
+{
+ gNB_MAC_INST *mac = RC.nrmac[module_idP];
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
+
+ start_meas(&mac->schedule_ra);
+ for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ NR_RA_t *ra = &cc->ra[i];
+ LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
+ switch (ra->state) {
+ case Msg2:
+ nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
+ break;
+ case Msg3_retransmission:
+ nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
+ break;
+ case Msg3_dcch_dtch:
+ nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
+ case Msg4:
+ nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
+ break;
+ case WAIT_Msg4_ACK:
+ nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ stop_meas(&mac->schedule_ra);
+}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index f6d1f83e35..0d66ec0842 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -51,11 +51,15 @@
extern RAN_CONTEXT_t RC;
-void schedule_ssb(frame_t frame, sub_frame_t slot,
- NR_ServingCellConfigCommon_t *scc,
- nfapi_nr_dl_tti_request_body_t *dl_req,
- int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) {
-
+static void schedule_ssb(frame_t frame,
+ sub_frame_t slot,
+ NR_ServingCellConfigCommon_t *scc,
+ nfapi_nr_dl_tti_request_body_t *dl_req,
+ int i_ssb,
+ uint8_t scoffset,
+ uint16_t offset_pointa,
+ uint32_t payload)
+{
uint8_t beam_index = 0;
nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -86,12 +90,25 @@ void schedule_ssb(frame_t frame, sub_frame_t slot,
dl_req->nPDUs++;
LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot);
+}
+static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id)
+{
+ AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
+ NR_SubcarrierSpacing_kHz240,
+ "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");
+
+ uint16_t *vrb_map = cc[CC_id].vrb_map;
+
+ const int extra_prb = ssb_subcarrier_offset > 0;
+ for (int rb = 0; rb < 20+extra_prb; rb++)
+ vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4);
}
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req)
{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
NR_COMMON_channels_t *cc;
nfapi_nr_dl_tti_request_body_t *dl_req;
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib->message.choice.mib;
@@ -254,33 +271,15 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
}
}
-void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
-//----------------------------------------
-}
-
-void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id) {
-
- AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
- NR_SubcarrierSpacing_kHz240,
- "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");
-
- uint16_t *vrb_map = cc[CC_id].vrb_map;
-
- const int extra_prb = ssb_subcarrier_offset > 0;
- for (int rb = 0; rb < 20+extra_prb; rb++)
- vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4);
-
-}
-
-uint32_t schedule_control_sib1(module_id_t module_id,
- int CC_id,
- NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
- int time_domain_allocation,
- NR_pdsch_dmrs_t *dmrs_parms,
- NR_tda_info_t *tda_info,
- uint8_t candidate_idx,
- uint16_t num_total_bytes) {
-
+static uint32_t schedule_control_sib1(module_id_t module_id,
+ int CC_id,
+ NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+ int time_domain_allocation,
+ NR_pdsch_dmrs_t *dmrs_parms,
+ NR_tda_info_t *tda_info,
+ uint8_t candidate_idx,
+ uint16_t num_total_bytes)
+{
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -377,14 +376,14 @@ uint32_t schedule_control_sib1(module_id_t module_id,
return TBS;
}
-void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
- nfapi_nr_dl_tti_request_body_t *dl_req,
- int pdu_index,
- NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
- uint32_t TBS,
- int StartSymbolIndex,
- int NrOfSymbols) {
-
+static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
+ nfapi_nr_dl_tti_request_body_t *dl_req,
+ int pdu_index,
+ NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+ uint32_t TBS,
+ int StartSymbolIndex,
+ int NrOfSymbols)
+{
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = gNB_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -515,7 +514,6 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
LOG_D(MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex);
LOG_D(MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity);
LOG_D(MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
-
}
void schedule_nr_sib1(module_id_t module_idP,
@@ -524,6 +522,7 @@ void schedule_nr_sib1(module_id_t module_idP,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
// TODO: Get these values from RRC
const int CC_id = 0;
uint8_t candidate_idx = 0;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 71b4499c55..4d3d59c12e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -55,6 +55,7 @@
const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) {
+ /* we assume that this function is mutex-protected from outside */
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
@@ -76,8 +77,12 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
const NR_UE_sched_ctrl_t *ue_sched_ctl,
unsigned char *mac_pdu,
unsigned char drx_cmd,
- unsigned char *ue_cont_res_id) {
+ unsigned char *ue_cont_res_id)
+{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
+ /* already mutex protected: called below and in _RA.c */
+ NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock);
+
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
uint8_t last_size = 0;
int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0;
@@ -311,10 +316,8 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
return offset;
}
-void nr_store_dlsch_buffer(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot) {
-
+static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
UE_iterator(RC.nrmac[module_id]->UE_info.list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
sched_ctrl->num_total_bytes = 0;
@@ -363,8 +366,9 @@ void nr_store_dlsch_buffer(module_id_t module_id,
}
}
-void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) {
-
+void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid)
+{
+ /* already mutex protected through handle_dl_harq() */
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid];
@@ -375,13 +379,13 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) {
}
-bool allocate_dl_retransmission(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- uint16_t *rballoc_mask,
- int *n_rb_sched,
- NR_UE_info_t *UE,
- int current_harq_pid)
+static bool allocate_dl_retransmission(module_id_t module_id,
+ frame_t frame,
+ sub_frame_t slot,
+ uint16_t *rballoc_mask,
+ int *n_rb_sched,
+ NR_UE_info_t *UE,
+ int current_harq_pid)
{
int CC_id = 0;
@@ -549,15 +553,14 @@ static int comparator(const void *p, const void *q) {
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
}
-void pf_dl(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- NR_UE_info_t **UE_list,
- int max_num_ue,
- int n_rb_sched,
- uint16_t *rballoc_mask)
+static void pf_dl(module_id_t module_id,
+ frame_t frame,
+ sub_frame_t slot,
+ NR_UE_info_t **UE_list,
+ int max_num_ue,
+ int n_rb_sched,
+ uint16_t *rballoc_mask)
{
-
gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
// UEs that could be scheduled
@@ -784,7 +787,7 @@ void pf_dl(module_id_t module_id,
}
}
-void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
+static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
{
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
@@ -843,6 +846,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
}
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) {
+ /* during initialization: no mutex needed */
/* in the PF algorithm, we have to use the TBsize to compute the coefficient.
* This would include the number of DMRS symbols, which in turn depends on
* the time domain allocation. In case we are in a mixed slot, we do not want
@@ -876,6 +880,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY,
+ "this function should be called with the scheduler mutex locked\n");
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
return;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 96756d41cd..d59efafdc2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -50,6 +50,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot)
{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
return;
NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0];
@@ -192,6 +193,7 @@ uint64_t ulsch_slot_bitmap = (1 << 8);
bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_UE_info_t *UE = nr_mac->UE_info.list[0];
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 0deb86a5db..2a8457356a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -509,7 +509,7 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac,
}
}
-bool multiple_2_3_5(int rb)
+static bool multiple_2_3_5(int rb)
{
while (rb % 2 == 0)
rb /= 2;
@@ -2369,7 +2369,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
reset_srs_stats(UE);
- pthread_mutex_lock(&UE_info->mutex);
+ NR_SCHED_LOCK(&UE_info->mutex);
int i;
for(i=0; ilist[i] == NULL) {
@@ -2380,10 +2380,10 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
if (i == MAX_MOBILES_PER_GNB) {
LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", rntiP);
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
- pthread_mutex_unlock(&UE_info->mutex);
+ NR_SCHED_UNLOCK(&UE_info->mutex);
return NULL;
}
- pthread_mutex_unlock(&UE_info->mutex);
+ NR_SCHED_UNLOCK(&UE_info->mutex);
LOG_D(NR_MAC, "Add NR rnti %x\n", rntiP);
dump_nr_list(UE_info->list);
@@ -2487,8 +2487,11 @@ void reset_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl) {
void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
{
+ /* already mutex protected */
+ NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
+
NR_UEs_t *UE_info = &nr_mac->UE_info;
- pthread_mutex_lock(&UE_info->mutex);
+ NR_SCHED_LOCK(&UE_info->mutex);
UE_iterator(UE_info->list, UE) {
if (UE->rnti==rnti)
break;
@@ -2496,7 +2499,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
if (!UE) {
LOG_W(NR_MAC,"Call to del rnti %04x, but not existing\n", rnti);
- pthread_mutex_unlock(&UE_info->mutex);
+ NR_SCHED_UNLOCK(&UE_info->mutex);
return;
}
@@ -2506,7 +2509,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
if(UE_info->list[i] && UE_info->list[i]->rnti != rnti)
newUEs[newListIdx++]=UE_info->list[i];
memcpy(UE_info->list, newUEs, sizeof(UE_info->list));
- pthread_mutex_unlock(&UE_info->mutex);
+ NR_SCHED_UNLOCK(&UE_info->mutex);
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
}
@@ -2525,6 +2528,7 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
nr_dci_format_t dci_format,
uint8_t *pdsch_to_harq_feedback) {
+ /* already mutex protected: held in nr_acknack_scheduling() */
if (dci_format == NR_DL_DCI_FORMAT_1_0) {
for (int i = 0; i < 8; i++)
@@ -2545,6 +2549,9 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
int CC_id = 0;
NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
+
+ NR_SCHED_ENSURE_LOCKED(&gNB_mac->sched_lock);
+
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map;
UE_info->sched_csirs = false;
@@ -2770,7 +2777,10 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
void nr_mac_update_timers(module_id_t module_id,
frame_t frame,
- sub_frame_t slot) {
+ sub_frame_t slot)
+{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_id]->sched_lock);
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
UE_iterator(UE_info->list, UE) {
@@ -2824,7 +2834,10 @@ void nr_mac_update_timers(module_id_t module_id,
void schedule_nr_bwp_switch(module_id_t module_id,
frame_t frame,
- sub_frame_t slot) {
+ sub_frame_t slot)
+{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_id]->sched_lock);
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
@@ -2887,6 +2900,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu
LOG_W(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", sdu_len, rnti);
NR_UE_info_t *UE = (NR_UE_info_t *)rawUE;
+ NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
uint8_t du2cu[1024];
int encoded = encode_cellGroupConfig(UE->CellGroup, du2cu, sizeof(du2cu));
@@ -2904,6 +2918,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu
void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
{
+ NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
/* create this UE's initial CellGroup */
/* Note: relying on the RRC is a hack, as we are in the DU; there should be
* no RRC, remove in the future */
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
index 8a85448c7f..3309e1af34 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
@@ -42,7 +42,8 @@ const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 4
160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256,
256, 264, 272, 272, 272 };
-uint32_t max4(uint32_t a, uint32_t b,uint32_t c,uint32_t d) {
+static uint32_t max4(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
+{
int x = max(a, b);
x = max(x, c);
x = max(x, d);
@@ -53,6 +54,9 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr
const NR_UE_UL_BWP_t *current_BWP,
uint8_t *ul_ri)
{
+ /* already mutex protected: held in handle_nr_srs_measurements() */
+ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock);
+
// If the gNB or UE has 1 antenna, the rank is always 1, i.e., *ul_ri = 0.
// For 2x2 scenario, we compute the rank of channel.
// The computation for 2x4, 4x2, 4x4, ... scenarios are not implemented yet. In these cases, the function sets *ul_ri = 0, which is always a valid value.
@@ -137,7 +141,14 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr
}
-void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int slot, int module_id, int CC_id, NR_UE_info_t *UE, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource, int buffer_index)
+static void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu,
+ int slot,
+ int module_id,
+ int CC_id,
+ NR_UE_info_t *UE,
+ NR_SRS_ResourceSet_t *srs_resource_set,
+ NR_SRS_Resource_t *srs_resource,
+ int buffer_index)
{
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
@@ -196,7 +207,13 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int slot, int module_id, int
vrb_map_UL[i + srs_pdu->bwp_start] |= mask;
}
-void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, int frame, int slot, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource)
+static void nr_fill_nfapi_srs(int module_id,
+ int CC_id,
+ NR_UE_info_t *UE,
+ int frame,
+ int slot,
+ NR_SRS_ResourceSet_t *srs_resource_set,
+ NR_SRS_Resource_t *srs_resource)
{
int index = ul_buffer_index(frame, slot, UE->current_UL_BWP.scs, RC.nrmac[module_id]->UL_tti_req_ahead_size);
@@ -226,8 +243,10 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, int frame, in
*********************************************************************/
void nr_schedule_srs(int module_id, frame_t frame, int slot)
{
-
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
+
NR_UEs_t *UE_info = &nrmac->UE_info;
UE_iterator(UE_info->list, UE) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index bc1796a6dc..e1716458d2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -144,7 +144,7 @@ static const int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
-30 // 10 - 15
};
-int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size)
+static int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size)
{
// PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots
// this functions return the index to the structure for slot passed to the function
@@ -167,6 +167,9 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac,
frame_t frameP,
sub_frame_t slotP)
{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
+
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
return;
@@ -198,7 +201,10 @@ void nr_csi_meas_reporting(int Mod_idP,
frame_t frame,
sub_frame_t slot)
{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
+
UE_iterator(nrmac->UE_info.list, UE ) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
@@ -324,8 +330,8 @@ static void handle_dl_harq(NR_UE_info_t * UE,
}
}
-int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * UE) {
-
+static int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t *UE)
+{
const NR_PDSCH_Config_t *pdsch_Config = UE->current_DL_BWP.pdsch_Config;
int nb_tci_states = pdsch_Config ? pdsch_Config->tci_StatesToAddModList->list.count : 0;
NR_TCI_State_t *tci =NULL;
@@ -350,8 +356,8 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t *
return -1;
}
-int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) {
-
+static int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE)
+{
NR_TCI_State_t *tci =NULL;
NR_TCI_StateId_t *tci_id = NULL;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
@@ -390,7 +396,8 @@ int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) {
}
//returns the measured RSRP value (upper limit)
-int get_measured_rsrp(uint8_t index) {
+static int get_measured_rsrp(uint8_t index)
+{
//if index is invalid returning minimum rsrp -140
if(index <= 15 || index >= 114)
return MIN_RSRP_VALUE;
@@ -399,7 +406,7 @@ int get_measured_rsrp(uint8_t index) {
}
//returns the differential RSRP value (upper limit)
-int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
+static int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
if(strongest_rsrp != -1) {
return strongest_rsrp + diff_rsrp_ssb_csi_meas_10_1_6_1_2[index];
} else
@@ -409,8 +416,8 @@ int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
//identifies the target SSB Beam index
//keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally
//handles triggering of PDCCH and PDSCH MAC CEs
-void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) {
-
+static void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot)
+{
int strongest_ssb_rsrp = 0;
int cqi_idx = 0;
int curr_ssb_beam_index = 0; //ToDo: yet to know how to identify the serving ssb beam index
@@ -583,24 +590,23 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) {
}
}//tci_presentInDCI
}//is-triggering_beam_switch
-}//tci handling
+} // tci handling
-
-uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit) {
+static uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit)
+{
uint8_t rev_bits = 0;
for (int i=0; i>((start_bit+i)%8))&0x01)<<(bitlen-i-1);
return rev_bits;
}
-
-void evaluate_rsrp_report(NR_UE_info_t *UE,
- NR_UE_sched_ctrl_t *sched_ctrl,
- uint8_t csi_report_id,
- uint8_t *payload,
- int *cumul_bits,
- NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){
-
+static void evaluate_rsrp_report(NR_UE_info_t *UE,
+ NR_UE_sched_ctrl_t *sched_ctrl,
+ uint8_t csi_report_id,
+ uint8_t *payload,
+ int *cumul_bits,
+ NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type)
+{
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
uint8_t cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
uint16_t curr_payload;
@@ -659,21 +665,18 @@ void evaluate_rsrp_report(NR_UE_info_t *UE,
stats->num_rsrp_meas++;
}
-void evaluate_cri_report(uint8_t *payload,
- uint8_t cri_bitlen,
- int cumul_bits,
- NR_UE_sched_ctrl_t *sched_ctrl){
-
+static void evaluate_cri_report(uint8_t *payload, uint8_t cri_bitlen, int cumul_bits, NR_UE_sched_ctrl_t *sched_ctrl)
+{
uint8_t temp_cri = pickandreverse_bits(payload, cri_bitlen, cumul_bits);
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cri = temp_cri;
}
-int evaluate_ri_report(uint8_t *payload,
- uint8_t ri_bitlen,
- uint8_t ri_restriction,
- int cumul_bits,
- NR_UE_sched_ctrl_t *sched_ctrl){
-
+static int evaluate_ri_report(uint8_t *payload,
+ uint8_t ri_bitlen,
+ uint8_t ri_restriction,
+ int cumul_bits,
+ NR_UE_sched_ctrl_t *sched_ctrl)
+{
uint8_t ri_index = pickandreverse_bits(payload, ri_bitlen, cumul_bits);
int count=0;
for (int i=0; i<8; i++) {
@@ -689,13 +692,12 @@ int evaluate_ri_report(uint8_t *payload,
AssertFatal(1==0, "Decoded ri %d does not correspond to any valid value in ri_restriction %d\n",ri_index,ri_restriction);
}
-
-void evaluate_cqi_report(uint8_t *payload,
- nr_csi_report_t *csi_report,
- int cumul_bits,
- uint8_t ri,
- NR_UE_info_t *UE,
- uint8_t cqi_Table)
+static void evaluate_cqi_report(uint8_t *payload,
+ nr_csi_report_t *csi_report,
+ int cumul_bits,
+ uint8_t ri,
+ NR_UE_info_t *UE,
+ uint8_t cqi_Table)
{
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
@@ -723,13 +725,12 @@ void evaluate_cqi_report(uint8_t *payload,
sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_Table, cqi_idx);
}
-
-uint8_t evaluate_pmi_report(uint8_t *payload,
- nr_csi_report_t *csi_report,
- int cumul_bits,
- uint8_t ri,
- NR_UE_sched_ctrl_t *sched_ctrl){
-
+static uint8_t evaluate_pmi_report(uint8_t *payload,
+ nr_csi_report_t *csi_report,
+ int cumul_bits,
+ uint8_t ri,
+ NR_UE_sched_ctrl_t *sched_ctrl)
+{
int x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[ri];
int x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[ri];
int tot_bitlen = x1_bitlen + x2_bitlen;
@@ -744,16 +745,14 @@ uint8_t evaluate_pmi_report(uint8_t *payload,
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
return tot_bitlen;
-
}
-
-int evaluate_li_report(uint8_t *payload,
- nr_csi_report_t *csi_report,
- int cumul_bits,
- uint8_t ri,
- NR_UE_sched_ctrl_t *sched_ctrl){
-
+static int evaluate_li_report(uint8_t *payload,
+ nr_csi_report_t *csi_report,
+ int cumul_bits,
+ uint8_t ri,
+ NR_UE_sched_ctrl_t *sched_ctrl)
+{
int li_bitlen = csi_report->csi_meas_bitlen.li_bitlen[ri];
if (li_bitlen>0) {
@@ -762,14 +761,10 @@ int evaluate_li_report(uint8_t *payload,
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.li = temp_li;
}
return li_bitlen;
-
}
-void skip_zero_padding(int *cumul_bits,
- nr_csi_report_t *csi_report,
- uint8_t ri,
- uint16_t max_bitlen) {
-
+static void skip_zero_padding(int *cumul_bits, nr_csi_report_t *csi_report, uint8_t ri, uint16_t max_bitlen)
+{
// actual number of reported bits depends on the reported rank
// zero padding bits are added to have a predetermined max bit length to decode
@@ -783,13 +778,12 @@ void skip_zero_padding(int *cumul_bits,
*cumul_bits+=(max_bitlen-reported_bitlen);
}
-
-void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
- const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
- frame_t frame,
- slot_t slot,
- NR_UE_info_t *UE,
- NR_ServingCellConfigCommon_t *scc)
+static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
+ const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
+ frame_t frame,
+ slot_t slot,
+ NR_UE_info_t *UE,
+ NR_ServingCellConfigCommon_t *scc)
{
/** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */
uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload;
@@ -929,9 +923,12 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01)
{
- NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_01->rnti);
+ gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
+ NR_SCHED_LOCK(&nrmac->sched_lock);
+ NR_UE_info_t * UE = find_nr_UE(&nrmac->UE_info, uci_01->rnti);
if (!UE) {
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
}
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
@@ -941,7 +938,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
- NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max);
+ NR_UE_harq_t *harq = find_harq(frame, slot, UE, nrmac->dl_bler.harq_round_max);
if (!harq) {
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
break;
@@ -950,13 +947,13 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
- handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->dl_bler.harq_round_max);
+ handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max);
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
}
// tpc (power control) only if we received AckNack
if (uci_01->harq->harq_confidence_level==0)
- sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30);
+ sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, uci_01->ul_cqi, 30);
else
sched_ctrl->tpc1 = 3;
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
@@ -974,6 +971,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
}
free(uci_01->sr);
}
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
@@ -981,15 +979,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234)
{
- NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_234->rnti);
+ gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
+ NR_SCHED_LOCK(&nrmac->sched_lock);
+
+ NR_UE_info_t * UE = find_nr_UE(&nrmac->UE_info, uci_234->rnti);
if (!UE) {
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti);
return;
}
NR_CSI_MeasConfig_t *csi_MeasConfig = UE->current_UL_BWP.csi_MeasConfig;
- if (csi_MeasConfig==NULL)
+ if (csi_MeasConfig==NULL) {
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
+ }
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
// tpc (power control)
@@ -1014,13 +1018,13 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
DevAssert(harq->is_waiting);
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
- handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->dl_bler.harq_round_max);
+ handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max);
}
free(uci_234->harq.harq_payload);
}
if ((uci_234->pduBitmap >> 2) & 0x01) {
//API to parse the csi report and store it into sched_ctrl
- extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon);
+ extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, nrmac->common_channels->ServingCellConfigCommon);
//TCI handling function
tci_handling(UE,frame, slot);
free(uci_234->csi_part1.csi_part1_payload);
@@ -1029,9 +1033,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
//@TODO:Handle CSI Report 2
// nothing to free (yet)
}
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
-void set_pucch_allocation(const NR_UE_UL_BWP_t *ul_bwp, const int r_pucch, const int bwp_size, NR_sched_pucch_t *pucch)
+static void set_pucch_allocation(const NR_UE_UL_BWP_t *ul_bwp, const int r_pucch, const int bwp_size, NR_sched_pucch_t *pucch)
{
if(r_pucch<0){
const NR_PUCCH_Resource_t *resource = ul_bwp->pucch_Config->resourceToAddModList->list.array[0];
@@ -1053,11 +1058,8 @@ void set_pucch_allocation(const NR_UE_UL_BWP_t *ul_bwp, const int r_pucch, const
}
}
-bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch,
- uint16_t *vrb_map_UL,
- const int bwp_start,
- const int bwp_size) {
-
+static bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, uint16_t *vrb_map_UL, const int bwp_start, const int bwp_size)
+{
// We assume initial cyclic shift is always 0 so different pucch resources can't overlap
// verifying occupation of PRBs for ACK/NACK on dedicated pucch
@@ -1076,9 +1078,7 @@ bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch,
return true;
}
-void set_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch,
- uint16_t *vrb_map_UL,
- const int bwp_start)
+static void set_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, uint16_t *vrb_map_UL, const int bwp_start)
{
for (int l=0; lnr_of_symb; l++) {
uint16_t symb = SL_to_bitmap(pucch->start_symb+l, 1);
@@ -1100,6 +1100,8 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
int r_pucch,
int is_common)
{
+ /* we assume that this function is mutex-protected from outside. Since it is
+ * called often, don't try to lock every time */
const int CC_id = 0;
const int minfbtime = mac->minRXTXTIMEpdsch;
@@ -1204,6 +1206,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
{
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
+
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
return;
const int CC_id = 0;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index e1a4e716ef..80c1652b61 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -39,7 +39,10 @@
//#define SRS_IND_DEBUG
-const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot) {
+const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
+{
+ /* we assume that this function is mutex-protected from outside */
+ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
/* there is a mixed slot only when in TDD */
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
@@ -61,14 +64,8 @@ const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *sc
return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots)
}
-int compute_ph_factor(int mu,
- int tbs_bits,
- int rb,
- int n_layers,
- int n_symbols,
- int n_dmrs,
- long *deltaMCS) {
-
+static int compute_ph_factor(int mu, int tbs_bits, int rb, int n_layers, int n_symbols, int n_dmrs, long *deltaMCS)
+{
// 38.213 7.1.1
// if the PUSCH transmission is over more than one layer delta_tf = 0
int delta_tf = 0;
@@ -109,14 +106,14 @@ int compute_ph_factor(int mu,
// F: length of L is 0:8 or 1:16 bits wide
// R: Reserved bit, set to zero.
-int nr_process_mac_pdu(instance_t module_idP,
- NR_UE_info_t* UE,
- uint8_t CC_id,
- frame_t frameP,
- sub_frame_t slot,
- uint8_t *pduP,
- int pdu_len,
- const int8_t harq_pid)
+static int nr_process_mac_pdu(instance_t module_idP,
+ NR_UE_info_t *UE,
+ uint8_t CC_id,
+ frame_t frameP,
+ sub_frame_t slot,
+ uint8_t *pduP,
+ int pdu_len,
+ const int8_t harq_pid)
{
uint8_t done = 0;
@@ -462,7 +459,7 @@ int nr_process_mac_pdu(instance_t module_idP,
return 0;
}
-void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
+static void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
{
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
@@ -479,7 +476,7 @@ void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
sched_ctrl->sched_ul_bytes = 0;
}
-bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_id, const frame_t frame, const sub_frame_t slot)
+static bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_id, const frame_t frame, const sub_frame_t slot)
{
bool UE_waiting_CFRA_msg3 = false;
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
@@ -498,17 +495,22 @@ void handle_nr_ul_harq(const int CC_idP,
sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu)
{
- NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti);
- bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(RC.nrmac[mod_id], CC_idP, frame, slot);
+ gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
+ NR_SCHED_LOCK(&nrmac->sched_lock);
+
+ NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, crc_pdu->rnti);
+ bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(nrmac, CC_idP, frame, slot);
if (!UE || UE_waiting_CFRA_msg3 == true) {
LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
- NR_RA_t *ra = &RC.nrmac[mod_id]->common_channels[CC_idP].ra[i];
- if (ra->state >= WAIT_Msg3 &&
- ra->rnti == crc_pdu->rnti)
+ NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i];
+ if (ra->state >= WAIT_Msg3 && ra->rnti == crc_pdu->rnti) {
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
+ }
}
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
LOG_E(NR_MAC, "%s(): unknown RNTI 0x%04x in PUSCH\n", __func__, crc_pdu->rnti);
return;
}
@@ -521,8 +523,10 @@ void handle_nr_ul_harq(const int CC_idP,
crc_pdu->harq_id,
harq_pid,
crc_pdu->rnti);
- if (harq_pid < 0)
+ if (harq_pid < 0) {
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
+ }
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
@@ -562,22 +566,23 @@ void handle_nr_ul_harq(const int CC_idP,
crc_pdu->rnti);
add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
}
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
/*
* When data are received on PHY and transmitted to MAC
*/
-void nr_rx_sdu(const module_id_t gnb_mod_idP,
- const int CC_idP,
- const frame_t frameP,
- const sub_frame_t slotP,
- const rnti_t rntiP,
- uint8_t *sduP,
- const uint16_t sdu_lenP,
- const uint16_t timing_advance,
- const uint8_t ul_cqi,
- const uint16_t rssi){
-
+static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
+ const int CC_idP,
+ const frame_t frameP,
+ const sub_frame_t slotP,
+ const rnti_t rntiP,
+ uint8_t *sduP,
+ const uint16_t sdu_lenP,
+ const uint16_t timing_advance,
+ const uint8_t ul_cqi,
+ const uint16_t rssi)
+{
gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP];
const int current_rnti = rntiP;
@@ -841,8 +846,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
}
-uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t size) {
+void nr_rx_sdu(const module_id_t gnb_mod_idP,
+ const int CC_idP,
+ const frame_t frameP,
+ const sub_frame_t slotP,
+ const rnti_t rntiP,
+ uint8_t *sduP,
+ const uint16_t sdu_lenP,
+ const uint16_t timing_advance,
+ const uint8_t ul_cqi,
+ const uint16_t rssi)
+{
+ gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP];
+ NR_SCHED_LOCK(&gNB_mac->sched_lock);
+ _nr_rx_sdu(gnb_mod_idP, CC_idP, frameP, slotP, rntiP, sduP, sdu_lenP, timing_advance, ul_cqi, rssi);
+ NR_SCHED_UNLOCK(&gNB_mac->sched_lock);
+}
+static uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t size)
+{
// Real part value
int64_t sum_x = 0;
int64_t sum_x2 = 0;
@@ -864,7 +886,8 @@ uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t s
return power_re+power_im;
}
-c16_t nr_h_times_w(c16_t h, char w) {
+static c16_t nr_h_times_w(c16_t h, char w)
+{
c16_t output;
switch (w) {
case '0': // 0
@@ -893,11 +916,11 @@ c16_t nr_h_times_w(c16_t h, char w) {
return output;
}
-uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config,
- const uint16_t num_ue_srs_ports,
- const uint8_t *nrOfLayers,
- int *additional_max_tpmi) {
-
+static uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config,
+ const uint16_t num_ue_srs_ports,
+ const uint8_t *nrOfLayers,
+ int *additional_max_tpmi)
+{
uint8_t max_tpmi = 0;
if ((pusch_Config && pusch_Config->txConfig != NULL && *pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook) ||
@@ -1056,13 +1079,13 @@ uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config,
return max_tpmi;
}
-void get_precoder_matrix_coef(char *w,
- const uint8_t ul_ri,
- const uint16_t num_ue_srs_ports,
- const long transform_precoding,
- const uint8_t tpmi,
- const uint8_t uI,
- int layer_idx)
+static void get_precoder_matrix_coef(char *w,
+ const uint8_t ul_ri,
+ const uint16_t num_ue_srs_ports,
+ const long transform_precoding,
+ const uint8_t tpmi,
+ const uint8_t uI,
+ int layer_idx)
{
if (ul_ri == 0) {
if (num_ue_srs_ports == 2) {
@@ -1085,15 +1108,16 @@ void get_precoder_matrix_coef(char *w,
}
}
-int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config,
- const long transform_precoding,
- const uint8_t *channel_matrix,
- const uint8_t normalized_iq_representation,
- const uint16_t num_gnb_antenna_elements,
- const uint16_t num_ue_srs_ports,
- const uint16_t prg_size,
- const uint16_t num_prgs,
- const uint8_t ul_ri) {
+static int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config,
+ const long transform_precoding,
+ const uint8_t *channel_matrix,
+ const uint8_t normalized_iq_representation,
+ const uint16_t num_gnb_antenna_elements,
+ const uint16_t num_ue_srs_ports,
+ const uint16_t prg_size,
+ const uint16_t num_prgs,
+ const uint8_t ul_ri)
+{
if (ul_ri > 1) {
LOG_D(NR_MAC, "TPMI computation for ul_ri %i is not implemented yet!\n", ul_ri);
return 0;
@@ -1173,6 +1197,8 @@ void handle_nr_srs_measurements(const module_id_t module_id,
const sub_frame_t slot,
nfapi_nr_srs_indication_pdu_t *srs_ind)
{
+ gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+ NR_SCHED_LOCK(&nrmac->sched_lock);
LOG_D(NR_MAC, "(%d.%d) Received SRS indication for UE %04x\n", frame, slot, srs_ind->rnti);
#ifdef SRS_IND_DEBUG
@@ -1188,11 +1214,13 @@ void handle_nr_srs_measurements(const module_id_t module_id,
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti);
if (!UE) {
LOG_W(NR_MAC, "Could not find UE for RNTI %04x\n", srs_ind->rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
}
if (srs_ind->timing_advance_offset == 0xFFFF) {
LOG_W(NR_MAC, "Invalid timing advance offset for RNTI %04x\n", srs_ind->rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
}
@@ -1210,6 +1238,7 @@ void handle_nr_srs_measurements(const module_id_t module_id,
if (nr_srs_bf_report.wide_band_snr == 0xFF) {
LOG_W(NR_MAC, "Invalid wide_band_snr for RNTI %04x\n", srs_ind->rnti);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
return;
}
@@ -1308,12 +1337,14 @@ void handle_nr_srs_measurements(const module_id_t module_id,
default:
AssertFatal(1 == 0, "Invalid SRS usage\n");
}
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
int time_domain_assignment,
int mu) {
+ /* we assume that this function is mutex-protected from outside */
NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdaList->list.array[time_domain_assignment];
if (tda->k2)
@@ -1363,7 +1394,7 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, in
return has_data || sched_ctrl->SR || high_inactivity;
}
-void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Config, uint16_t *R, uint8_t *Qm)
+static void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Config, uint16_t *R, uint8_t *Qm)
{
*R = nr_get_code_rate_ul(mcs, mcs_table);
*Qm = nr_get_Qm_ul(mcs, mcs_table);
@@ -1374,7 +1405,14 @@ void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Co
}
}
-void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_sched_pusch_t *sched_pusch, NR_UE_UL_BWP_t *ul_bwp, uint16_t minRb, uint32_t tbs, uint16_t *Rb, uint8_t *mcs)
+static void nr_ue_max_mcs_min_rb(int mu,
+ int ph_limit,
+ NR_sched_pusch_t *sched_pusch,
+ NR_UE_UL_BWP_t *ul_bwp,
+ uint16_t minRb,
+ uint32_t tbs,
+ uint16_t *Rb,
+ uint8_t *mcs)
{
AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb);
AssertFatal(*mcs >= 0 && *mcs <= 28, "illegal MCS %d\n", *mcs);
@@ -1577,13 +1615,13 @@ static int comparator(const void *p, const void *q) {
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
}
-void pf_ul(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- NR_UE_info_t *UE_list[],
- int max_num_ue,
- int n_rb_sched,
- uint16_t *rballoc_mask)
+static void pf_ul(module_id_t module_id,
+ frame_t frame,
+ sub_frame_t slot,
+ NR_UE_info_t *UE_list[],
+ int max_num_ue,
+ int n_rb_sched,
+ uint16_t *rballoc_mask)
{
const int CC_id = 0;
@@ -1870,7 +1908,7 @@ void pf_ul(module_id_t module_id,
}
}
-bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
+static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
@@ -1971,6 +2009,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id)
{
+ /* during initialization: no mutex needed */
/* in the PF algorithm, we have to use the TBsize to compute the coefficient.
* This would include the number of DMRS symbols, which in turn depends on
* the time domain allocation. In case we are in a mixed slot, we do not want
@@ -2002,6 +2041,9 @@ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id)
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
+ /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+ NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
+
/* Uplink data ONLY can be scheduled when the current slot is downlink slot,
* because we have to schedule the DCI0 first before schedule uplink data */
if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index a700c5c652..c2cbe8799d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -40,8 +40,6 @@ void set_cset_offset(uint16_t);
void mac_top_init_gNB(ngran_node_t node_type);
-void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc);
-
int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP,
rnti_t rnti,
NR_SubcarrierSpacing_t subcarrierSpacing,
@@ -58,7 +56,6 @@ void nr_mac_config_sib1(gNB_MAC_INST *nrmac, NR_BCCH_DL_SCH_Message_t *sib1);
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
-bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
int CC_idP,
@@ -87,15 +84,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req);
-uint32_t schedule_control_sib1(module_id_t module_id,
- int CC_id,
- NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
- int time_domain_allocation,
- NR_pdsch_dmrs_t *dmrs_parms,
- NR_tda_info_t *tda_info,
- uint8_t candidate_idx,
- uint16_t num_total_bytes);
-
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id);
@@ -139,41 +127,6 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
-void nr_get_Msg3alloc(module_id_t module_id,
- int CC_id,
- NR_ServingCellConfigCommon_t *scc,
- sub_frame_t current_subframe,
- frame_t current_frame,
- NR_RA_t *ra,
- int16_t *tdd_beam_association);
-
-void nr_generate_Msg3_retransmission(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_ul_dci_request_t *ul_dci_req);
-
-/* \brief Function in gNB to fill RAR pdu when requested by PHY.
-@param ra Instance of RA resources of gNB
-@param dlsch_buffer Pointer to RAR input buffer
-@param N_RB_UL Number of UL resource blocks
-*/
-void nr_fill_rar(uint8_t Mod_idP,
- NR_RA_t * ra,
- uint8_t * dlsch_buffer,
- nfapi_nr_pusch_pdu_t *pusch_pdu);
-
-void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
- NR_ServingCellConfigCommon_t *scc,
- int round,
- int startSymbolAndLength,
- rnti_t rnti, int scs,
- int bwp_size, int bwp_start,
- int mappingtype, int fh,
- int msg3_first_rb, int msg3_nb_rb);
-
-
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
@@ -380,39 +333,10 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
unsigned char drx_cmd,
unsigned char *ue_cont_res_id);
-void nr_generate_Msg2(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_dl_tti_request_t *dl_req,
- nfapi_nr_tx_data_request_t *TX_req);
-
-void nr_generate_Msg4(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_dl_tti_request_t *DL_req,
- nfapi_nr_tx_data_request_t *TX_req);
-
-void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra);
-
-void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP,
- NR_RA_t *ra,
- nfapi_nr_dl_tti_request_t *DL_req,
- nfapi_nr_tx_data_request_t *TX_req);
-
int binomial(int n, int k);
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
-void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id);
-
-
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of gNB
@param CC_id Component carrier index
@@ -451,13 +375,6 @@ void handle_nr_srs_measurements(const module_id_t module_id,
const sub_frame_t slot,
nfapi_nr_srs_indication_pdu_t *srs_ind);
-int16_t ssb_index_from_prach(module_id_t module_idP,
- frame_t frameP,
- sub_frame_t slotP,
- uint16_t preamble_index,
- uint8_t freq_index,
- uint8_t symbol);
-
void find_SSB_and_RO_available(gNB_MAC_INST *nrmac);
NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
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 0a47699591..4fdad6fb81 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
@@ -22,12 +22,130 @@
#include "mac_rrc_dl_handler.h"
#include "mac_proto.h"
-#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
+#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
-#include "NR_RRCSetup.h"
-#include "NR_DL-CCCH-Message.h"
-#include "NR_CellGroupConfig.h"
+static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb)
+{
+ long priority = srb->srb_id; // high priority for SRB
+ e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket =
+ NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5;
+ return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket);
+}
+
+static void handle_ue_context_srbs_setup(const f1ap_ue_context_setup_t *req,
+ f1ap_ue_context_setup_t *resp,
+ NR_CellGroupConfig_t *cellGroupConfig)
+{
+ DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL);
+
+ resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length;
+ resp->srbs_to_be_setup = calloc(req->srbs_to_be_setup_length, sizeof(*resp->srbs_to_be_setup));
+ AssertFatal(resp->srbs_to_be_setup != NULL, "out of memory\n");
+ for (int i = 0; i < req->srbs_to_be_setup_length; i++) {
+ f1ap_srb_to_be_setup_t *srb = &req->srbs_to_be_setup[i];
+ NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb);
+ nr_rlc_add_srb(req->rnti, srb->srb_id, rlc_BearerConfig);
+
+ resp->srbs_to_be_setup[i] = *srb;
+
+ int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
+ DevAssert(ret == 0);
+ }
+}
+
+static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb)
+{
+ const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am;
+ long priority = 13; // hardcoded for the moment
+ return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority);
+}
+
+static void handle_ue_context_drbs_setup(const f1ap_ue_context_setup_t *req,
+ f1ap_ue_context_setup_t *resp,
+ NR_CellGroupConfig_t *cellGroupConfig)
+{
+ DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL);
+
+ /* Note: the actual GTP tunnels are created in the F1AP breanch of
+ * ue_context_*_response() */
+ resp->drbs_to_be_setup_length = req->drbs_to_be_setup_length;
+ resp->drbs_to_be_setup = calloc(req->drbs_to_be_setup_length, sizeof(*resp->drbs_to_be_setup));
+ AssertFatal(resp->drbs_to_be_setup != NULL, "out of memory\n");
+ for (int i = 0; i < req->drbs_to_be_setup_length; i++) {
+ f1ap_drb_to_be_setup_t *drb = &req->drbs_to_be_setup[i];
+ NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
+ nr_rlc_add_drb(req->rnti, drb->drb_id, rlc_BearerConfig);
+
+ resp->drbs_to_be_setup[i] = *drb;
+
+ int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
+ DevAssert(ret == 0);
+ }
+}
+
+void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
+{
+ gNB_MAC_INST *mac = RC.nrmac[0];
+ /* response has same type as request... */
+ 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) {
+ AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL, "CG-ConfigInfo not handled\n");
+ AssertFatal(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList == NULL, "UE capabilities not handled yet\n");
+ AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL, "MeasConfig not handled\n");
+ }
+
+ 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", UE->rnti);
+
+ if (req->srbs_to_be_setup_length > 0)
+ handle_ue_context_srbs_setup(req, &resp, UE->CellGroup);
+
+ if (req->drbs_to_be_setup_length > 0) {
+ handle_ue_context_drbs_setup(req, &resp, NULL);
+ }
+
+ if (req->rrc_container != NULL)
+ nr_rlc_srb_recv_sdu(req->rnti, 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));
+ AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n");
+ resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024);
+ AssertFatal(resp.du_to_cu_rrc_information->cellGroupConfig != NULL, "out of memory\n");
+ asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
+ NULL,
+ UE->CellGroup,
+ resp.du_to_cu_rrc_information->cellGroupConfig,
+ 1024);
+ AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name);
+ resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
+
+ /* TODO: need to apply after UE context reconfiguration confirmed? */
+ process_CellGroup(UE->CellGroup, &UE->UE_sched_ctrl);
+
+ NR_SCHED_UNLOCK(&mac->sched_lock);
+
+ /* some sanity checks, since we use the same type for request and response */
+ DevAssert(resp.cu_to_du_rrc_information == NULL);
+ DevAssert(resp.du_to_cu_rrc_information != NULL);
+ DevAssert(resp.rrc_container == NULL && resp.rrc_container_length == 0);
+
+ mac->mac_rrc.ue_context_setup_response(req, &resp);
+
+ /* free the memory we allocated above */
+ free(resp.srbs_to_be_setup);
+ free(resp.drbs_to_be_setup);
+ free(resp.du_to_cu_rrc_information->cellGroupConfig);
+ free(resp.du_to_cu_rrc_information);
+}
int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc)
{
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 ecbc95eef0..25b51c2d84 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
@@ -25,6 +25,8 @@
#include "platform_types.h"
#include "f1ap_messages_types.h"
+void ue_context_setup_request(const f1ap_ue_context_setup_t *req);
+
int dl_rrc_message(module_id_t module_id, 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.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h
index cb80ba4fa5..53736a1695 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h
@@ -25,6 +25,8 @@
#include "platform_types.h"
#include "f1ap_messages_types.h"
+typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp);
+
typedef void (*initial_ul_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc);
struct nr_mac_rrc_ul_if_s;
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 ace8b17f49..eafa544185 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
@@ -24,6 +24,37 @@
#include "mac_rrc_ul.h"
+static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
+{
+ DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
+ AssertFatal(req->drbs_to_be_setup_length == 0, "not implemented\n");
+
+ (void) req; /* we don't need the request -- it is to set up GTP in F1 case */
+ MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
+ f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg);
+ /* copy all fields, but reallocate memory buffers! */
+ *f1ap_msg = *resp;
+
+ if (resp->srbs_to_be_setup_length > 0) {
+ DevAssert(resp->srbs_to_be_setup != NULL);
+ f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length;
+ f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup));
+ for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
+ f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
+ }
+
+ f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
+ AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
+ f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length;
+ du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information;
+ du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length;
+ du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig));
+ AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n");
+ memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length);
+
+ itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
+}
+
static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc)
{
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
@@ -46,5 +77,6 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
{
+ mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct;
}
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 13547c5291..c5bcb8814a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
@@ -19,11 +19,47 @@
* conmnc_digit_lengtht@openairinterface.org
*/
+#include
+#include
+#include
+
#include "nr_mac_gNB.h"
#include "intertask_interface.h"
+#include "openair3/ocp-gtpu/gtp_itf.h"
#include "mac_rrc_ul.h"
+static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
+{
+ DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
+ AssertFatal(req->drbs_to_be_setup_length == 0, "not implmented\n");
+
+ DevAssert(req->srbs_to_be_setup_length == resp->srbs_to_be_setup_length);
+ MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
+ f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg);
+ /* copy all fields, but reallocate rrc_containers! */
+ *f1ap_msg = *resp;
+
+ if (resp->srbs_to_be_setup_length > 0) {
+ DevAssert(resp->srbs_to_be_setup != NULL);
+ f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length;
+ f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup));
+ for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
+ f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
+ }
+
+ f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
+ AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
+ f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length;
+ du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information;
+ du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length;
+ du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig));
+ AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n");
+ memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length);
+
+ itti_send_msg_to_task(TASK_DU_F1, 0, msg);
+}
+
static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc)
{
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
@@ -46,6 +82,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
{
+ mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap;
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index cd8e16c48b..d7cd8e1b4b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -60,7 +60,9 @@ void *nrmac_stats_thread(void *arg) {
while (oai_exit == 0) {
char *p = output;
+ NR_SCHED_LOCK(&gNB->sched_lock);
p += dump_mac_stats(gNB, p, end - p, false);
+ NR_SCHED_UNLOCK(&gNB->sched_lock);
p += snprintf(p, end - p, "\n");
p += print_meas_log(&gNB->eNB_scheduler, "DL & UL scheduling timing", NULL, NULL, p, end - p);
p += print_meas_log(&gNB->schedule_dlsch, "dlsch scheduler", NULL, NULL, p, end - p);
@@ -87,7 +89,11 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
const char *begin = output;
const char *end = output + strlen;
- pthread_mutex_lock(&gNB->UE_info.mutex);
+ /* this function is called from gNB_dlsch_ulsch_scheduler(), so assumes the
+ * scheduler to be locked*/
+ NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock);
+
+ NR_SCHED_LOCK(&gNB->UE_info.mutex);
UE_iterator(gNB->UE_info.list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_mac_stats_t *stats = &UE->mac_stats;
@@ -175,7 +181,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
stats->ul.lc_bytes[lc_id]);
}
}
- pthread_mutex_unlock(&gNB->UE_info.mutex);
+ NR_SCHED_UNLOCK(&gNB->UE_info.mutex);
return output - begin;
}
@@ -233,6 +239,8 @@ void mac_top_init_gNB(ngran_node_t node_type)
RC.nrmac[i]->first_MIB = true;
+ pthread_mutex_init(&RC.nrmac[i]->sched_lock, NULL);
+
pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL);
uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator);
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index b8517da55e..5f25713650 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -41,6 +41,25 @@
#include
#include
#include
+#include
+
+#define NR_SCHED_LOCK(lock) \
+ do { \
+ int rc = pthread_mutex_lock(lock); \
+ AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \
+ } while (0)
+
+#define NR_SCHED_UNLOCK(lock) \
+ do { \
+ int rc = pthread_mutex_unlock(lock); \
+ AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \
+ } 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");\
+ } while (0)
/* Commmon */
#include "radio/COMMON/common_lib.h"
@@ -641,6 +660,7 @@ typedef struct NR_bler_options {
typedef struct nr_mac_rrc_ul_if_s {
/* TODO add other message types as necessary */
+ ue_context_setup_response_func_t ue_context_setup_response;
initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer;
} nr_mac_rrc_ul_if_t;
@@ -795,6 +815,8 @@ typedef struct gNB_MAC_INST_s {
int16_t frame;
int16_t slot;
+ pthread_mutex_t sched_lock;
+
} gNB_MAC_INST;
#endif /*__LAYER2_NR_MAC_GNB_H__ */
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 2e83c69af2..4e9c077afa 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -55,12 +55,17 @@ 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)
{
- nr_mac_update_cellgroup(RC.nrmac[0], rntiMaybeUEid, cgc);
+ gNB_MAC_INST *nrmac = RC.nrmac[0];
+ NR_SCHED_LOCK(&nrmac->sched_lock);
+ nr_mac_update_cellgroup(nrmac, rntiMaybeUEid, cgc);
+ NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h
index 1943490cd6..49ffccd4a7 100644
--- a/openair2/RRC/NR/mac_rrc_dl.h
+++ b/openair2/RRC/NR/mac_rrc_dl.h
@@ -25,6 +25,8 @@
#include "platform_types.h"
#include "f1ap_messages_types.h"
+typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req);
+
typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
struct nr_mac_rrc_dl_if_s;
diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c
index 5c8d9d9d5b..be416d6921 100644
--- a/openair2/RRC/NR/mac_rrc_dl_direct.c
+++ b/openair2/RRC/NR/mac_rrc_dl_direct.c
@@ -33,5 +33,6 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_
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->dl_rrc_message_transfer = dl_rrc_message_transfer_direct;
}
diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c
index 40f3b4b6ea..9bbddaf476 100644
--- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c
+++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c
@@ -19,9 +19,27 @@
* conmnc_digit_lengtht@openairinterface.org
*/
+#include
+
#include "mac_rrc_dl.h"
#include "nr_rrc_defs.h"
+static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req)
+{
+ MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
+ f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg);
+ *f1ap_msg = *req;
+ AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
+ f1ap_msg->cu_to_du_rrc_information = malloc(sizeof(*f1ap_msg->cu_to_du_rrc_information));
+ if (req->rrc_container_length > 0) {
+ f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
+ AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
+ f1ap_msg->rrc_container_length = req->rrc_container_length;
+ memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length);
+ }
+ itti_send_msg_to_task(TASK_CU_F1, 0, msg);
+}
+
static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc)
{
/* TODO call F1AP function directly? no real-time constraint here */
@@ -40,5 +58,6 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
+ mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap;
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap;
}
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index c739b174b6..20ba902244 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -2323,6 +2323,8 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid,
return cellGroupConfig;
}
+#include "common/ran_context.h"
+#include "nr_rrc_defs.h"
void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
const int uid,
NR_UE_NR_Capability_t *uecap,
@@ -2338,6 +2340,13 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
return;
DevAssert(configuration->scc != NULL);
+ /* This is a hack and will be removed once the CellGroupConfig is fully
+ * handled at the DU */
+ if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+ LOG_W(RRC, "update of CellGroupConfig not yet supported in F1\n");
+ return;
+ }
+
NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig;
NR_ServingCellConfigCommon_t *scc = configuration->scc;
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 93acdeac7b..942e9ffb1f 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -481,6 +481,7 @@ typedef struct {
typedef struct nr_mac_rrc_dl_if_s {
/* TODO add other message types as necessary */
+ ue_context_setup_request_func_t ue_context_setup_request;
dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
} nr_mac_rrc_dl_if_t;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 2d3628f765..81a17afab1 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -363,7 +363,6 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance,
// remove UE after 10 frames after RRCConnectionRelease is triggered
ue_context_pP->ue_context.ue_release_timer_thres = 1000;
- /* TODO: this should go through the E1 interface */
nr_pdcp_add_srbs(true, rnti, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL);
f1ap_dl_rrc_message_t dl_rrc = {
@@ -497,6 +496,7 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
/******************** Radio Bearer Config ********************/
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
+ AssertFatal(ue_p->nb_of_pdusessions == 0, "logic bug: PDU sessions present before RRC Connection established\n");
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
@@ -2285,72 +2285,12 @@ rrc_gNB_decode_dcch(
ul_dcch_msg);
}
- if (!NODE_IS_CU(gnb_rrc_inst->node_type)) {
- if (UE->established_pdu_sessions_flag == 1) {
- rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p, NULL);
- } else {
- rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
- }
- } else {
- /*Generate a UE context setup request message towards the DU to provide the UE
- *capability info and get the updates on master cell group config from the DU*/
- MessageDef *message_p;
- message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
- f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p);
- //UE_IDs will be extracted from F1AP layer
- req->gNB_CU_ue_id = 0;
- req->gNB_DU_ue_id = 0;
- req->rnti = UE->rnti;
- req->mcc = gnb_rrc_inst->configuration.mcc[0];
- req->mnc = gnb_rrc_inst->configuration.mnc[0];
- req->mnc_digit_length = gnb_rrc_inst->configuration.mnc_digit_length[0];
- req->nr_cellid = gnb_rrc_inst->nr_cellid;
-
- if (UE->established_pdu_sessions_flag == 1) {
- /*Instruction towards the DU for SRB2 configuration*/
- req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
- req->srbs_to_be_setup_length = 1;
- f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
- SRBs[0].srb_id = 2;
- SRBs[0].lcid = 2;
-
- /*Instruction towards the DU for DRB configuration and tunnel creation*/
- req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
- req->drbs_to_be_setup_length = 1;
- f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
- LOG_I(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
- DRBs[0].drb_id = 1;
- DRBs[0].rlc_mode = RLC_MODE_AM;
- DRBs[0].up_ul_tnl[0].tl_address = inet_addr(gnb_rrc_inst->eth_params_s.my_addr);
- DRBs[0].up_ul_tnl[0].port = gnb_rrc_inst->eth_params_s.my_portd;
- DRBs[0].up_ul_tnl_length = 1;
- DRBs[0].up_dl_tnl[0].tl_address = inet_addr(gnb_rrc_inst->eth_params_s.remote_addr);
- DRBs[0].up_dl_tnl[0].port = gnb_rrc_inst->eth_params_s.remote_portd;
- DRBs[0].up_dl_tnl_length = 1;
- }
- if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present ==
- NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) {
- struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList =
- ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList;
- if(ue_CapabilityRAT_ContainerList!=NULL){
- LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is present \n");
- req->cu_to_du_rrc_information = calloc(1,sizeof(cu_to_du_rrc_information_t));
- req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = calloc(1,4096);
- asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList,
- NULL,
- ue_CapabilityRAT_ContainerList,
- req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList,
- 4096);
- AssertFatal (enc_rval.encoded > 0, "ASN1 ue_CapabilityRAT_ContainerList encoding failed (%s, %jd)!\n",
- enc_rval.failed_type->name, enc_rval.encoded);
- req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = (enc_rval.encoded+7)>>3;
- }
- else{
- LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is not present \n");
- }
- }
- itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
- }
+ // we send the UE capabilities request before RRC connection is complete,
+ // so we cannot have a PDU session yet
+ AssertFatal(UE->established_pdu_sessions_flag == 0, "logic bug: received capabilities while PDU session established\n");
+ // TODO: send UE context modification response with UE capabilities to
+ // allow DU configure CellGroupConfig
+ rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
break;
@@ -2525,233 +2465,6 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
rrc_remove_nsa_user(rrc, m->rnti);
}
-static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, instance_t instance)
-{
- f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_SETUP_REQ(msg_p);
- gNB_RRC_INST *rrc = RC.nrrrc[instance];
- gNB_MAC_INST *mac = RC.nrmac[instance];
- rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti);
- gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
- MessageDef *message_p;
- message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
- f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p);
- uint32_t incoming_teid = 0;
-
- if(req->cu_to_du_rrc_information!=NULL){
- if(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){
- LOG_I(NR_RRC, "Length of ue_CapabilityRAT_ContainerList is: %d \n", (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
- struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = NULL;
- asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
- &asn_DEF_NR_UE_CapabilityRAT_ContainerList,
- (void **)&ue_CapabilityRAT_ContainerList,
- (uint8_t *)req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList,
- (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
-
- if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- AssertFatal(1==0,"UE Capability RAT ContainerList decode error\n");
- // free the memory
- SEQUENCE_free( &asn_DEF_NR_UE_CapabilityRAT_ContainerList, ue_CapabilityRAT_ContainerList, 1 );
- return;
- }
- //To fill ue_context.UE_Capability_MRDC, ue_context.UE_Capability_nr ...
- int NR_index = -1;
- for(int i = 0;i < ue_CapabilityRAT_ContainerList->list.count; i++){
- if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
- NR_RAT_Type_nr){
- LOG_I(NR_RRC, "DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU \n");
- if (UE->UE_Capability_nr) {
- ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
- UE->UE_Capability_nr = 0;
- }
-
- dec_rval = uper_decode(NULL,
- &asn_DEF_NR_UE_NR_Capability,
- (void **)&UE->UE_Capability_nr,
- ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf,
- ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size,
- 0,
- 0);
- if(LOG_DEBUGFLAG(DEBUG_ASN1)){
- xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
- }
-
- if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){
- LOG_E(NR_RRC, "UE %04x Failed to decode nr UE capabilities (%zu bytes)\n", req->rnti, dec_rval.consumed);
- ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
- UE->UE_Capability_nr = 0;
- }
-
- UE->UE_Capability_size = ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size;
- if(NR_index != -1){
- LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n");
- exit(1);
- }
- NR_index = i;
- }
-
- if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
- NR_RAT_Type_eutra_nr){
- LOG_I(NR_RRC, "DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU \n");
- if (UE->UE_Capability_MRDC) {
- ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
- UE->UE_Capability_MRDC = 0;
- }
- dec_rval = uper_decode(NULL,
- &asn_DEF_NR_UE_MRDC_Capability,
- (void **)&UE->UE_Capability_MRDC,
- ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf,
- ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size,
- 0,
- 0);
- if(LOG_DEBUGFLAG(DEBUG_ASN1)){
- xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
- }
-
- if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){
- LOG_E(NR_RRC, "UE %04x Failed to decode nr UE capabilities (%zu bytes)\n", req->rnti, dec_rval.consumed);
- ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
- UE->UE_Capability_MRDC = 0;
- }
- UE->UE_MRDC_Capability_size = ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size;
- }
-
- if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
- NR_RAT_Type_eutra){
- //TODO
- }
- }
- }
- }
-
-
- /* Configure SRB2 */
- NR_SRB_ToAddMod_t *SRB2_config = NULL;
- NR_SRB_ToAddModList_t *SRB_configList = NULL;
- uint8_t SRBs_before_new_addition = 0;
-
- if(req->srbs_to_be_setup_length>0){
- if (UE->SRB_configList == NULL) {
- LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n");
- UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList));
- }
- SRB_configList = UE->SRB_configList;
- SRBs_before_new_addition = SRB_configList->list.count;
- for (int i=0; isrbs_to_be_setup_length; i++){
- SRB2_config = CALLOC(1, sizeof(*SRB2_config));
- SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id;
- asn1cSeqAdd(&SRB_configList->list, SRB2_config);
- }
- }
-
- /* Configure DRB */
- NR_DRB_ToAddMod_t *DRB_config = NULL;
- NR_DRB_ToAddModList_t *DRB_configList = NULL;
- uint8_t drb_id_to_setup_start = 0;
- uint8_t nb_drb_to_setup = 0;
- long drb_priority[NGAP_MAX_DRBS_PER_UE];
- if(req->drbs_to_be_setup_length>0){
- if (UE->DRB_configList == NULL) {
- UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList));
- }
- DRB_configList = UE->DRB_configList;
- nb_drb_to_setup = req->drbs_to_be_setup_length;
- for (int i=0; idrbs_to_be_setup_length; i++){
- DRB_config = CALLOC(1, sizeof(*DRB_config));
- DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id;
- if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity;
- asn1cSeqAdd(&DRB_configList->list, DRB_config);
- f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i];
- transport_layer_addr_t addr;
- memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address));
- addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8;
- extern instance_t DUuniqInstance;
- incoming_teid = newGtpuCreateTunnel(DUuniqInstance,
- req->rnti,
- drb_p.drb_id,
- drb_p.drb_id,
- drb_p.up_ul_tnl[0].teid,
- -1, // no qfi
- addr,
- drb_p.up_ul_tnl[0].port,
- DURecvCb,
- NULL);
- /* TODO: hardcoded to 13 for the time being, to be changed? */
- drb_priority[DRB_config->drb_Identity-1] = 13;
- }
- }
-
- NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
- if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length>0)
- // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or
- // bearer IDs for the DRBs
- fill_mastercellGroupConfig(cellGroupConfig, UE->masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
- protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
- apply_macrlc_config(rrc, ue_context_p, &ctxt);
-
- if(req->rrc_container_length > 0){
- mem_block_t *pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__);
- memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length);
- du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length, pdcp_pdu_p);
- LOG_I(F1AP, "Printing RRC Container of UE context setup request: \n");
- for (int j=0; jrrc_container_length; j++){
- printf("%02x ", pdcp_pdu_p->data[j]);
- }
- printf("\n");
- }
-
- /* Fill the UE context setup response ITTI message to send to F1AP */
- resp->gNB_CU_ue_id = req->gNB_CU_ue_id;
- resp->rnti = req->rnti;
- if(DRB_configList){
- if(DRB_configList->list.count > 0){
- resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t));
- resp->drbs_to_be_setup_length = DRB_configList->list.count;
- for (int i=0; ilist.count; i++){
- resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity;
- resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM;
- resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid;
- resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr);
- resp->drbs_to_be_setup[i].up_dl_tnl_length = 1;
- }
- }
- else{
- LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context setup request with a DRB to setup list\n");
- }
- }
- if(SRB_configList){
- if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){
- resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t));
- resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length;
- for (int i=SRBs_before_new_addition; ilist.count; i++){
- resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity;
- }
- }
- else{
- LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n");
- }
- }
- else{
- LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n");
- }
- /* fixme:
- * Here we should be encoding the updates on cellgroupconfig based on the content of UE capabilities
- */
- resp->du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t));
- resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024);
- asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
- NULL,
- UE->masterCellGroup, //(void *)cellGroupConfig,
- resp->du_to_cu_rrc_information->cellGroupConfig,
- 1024);
- if (enc_rval.encoded == -1) {
- LOG_E(F1AP,"Could not encode ue_context.masterCellGroup, failed element %s\n",enc_rval.failed_type->name);
- exit(-1);
- }
- resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3;
- free(cellGroupConfig);
- itti_send_msg_to_task(TASK_DU_F1, instance, message_p);
-}
-
static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance)
{
f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p);
@@ -2899,54 +2612,29 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, in
static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance)
{
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
- protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
- gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
+ 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);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
+
NR_CellGroupConfig_t *cellGroupConfig = NULL;
+ asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
+ &asn_DEF_NR_CellGroupConfig,
+ (void **)&cellGroupConfig,
+ (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig,
+ resp->du_to_cu_rrc_information->cellGroupConfig_length);
+ AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed > 0, "Cell group config decode error\n");
- asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
- &asn_DEF_NR_CellGroupConfig,
- (void **)&cellGroupConfig,
- (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig,
- (int) resp->du_to_cu_rrc_information->cellGroupConfig_length);
-
- if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- AssertFatal(1==0,"Cell group config decode error\n");
- // free the memory
- SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 );
- return;
+ if (UE->masterCellGroup) {
+ ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
+ LOG_I(RRC, "UE %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rnti);
}
- //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig);
-
- if (UE->masterCellGroup == NULL) {
- UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t));
- }
- if(cellGroupConfig->rlc_BearerToAddModList!=NULL){
- if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) {
- int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count;
- for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){
- asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]);
- }
- } else {
- LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n");
- UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
- memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
- }
- }
- if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
+ UE->masterCellGroup = cellGroupConfig;
+ if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
- }
- if (UE->established_pdu_sessions_flag == 1) {
- fill_DRB_configList(&ctxt, ue_context_p);
- rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig);
- } else {
- rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p);
- }
-
- free(cellGroupConfig->rlc_BearerToAddModList);
- free(cellGroupConfig);
+ /* at this point, we don't have to do anything: the UE context setup request
+ * includes the Security Command, whose response will trigger the following
+ * messages (UE capability, to be specific) */
}
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
@@ -3508,10 +3196,6 @@ void *rrc_gnb_task(void *args_p) {
AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST, need call by CU!\n");
rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
break;
-
- case F1AP_UE_CONTEXT_SETUP_REQ:
- rrc_DU_process_ue_context_setup_request(msg_p, instance);
- break;
case F1AP_UE_CONTEXT_SETUP_RESP:
rrc_CU_process_ue_context_setup_response(msg_p, instance);
@@ -3583,6 +3267,27 @@ void *rrc_gnb_task(void *args_p) {
}
}
+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);
+}
+
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_SecurityModeCommand(
@@ -3604,7 +3309,8 @@ rrc_gNB_generate_SecurityModeCommand(
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);
+ /* 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);
}
void
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index bf69aa703b..250402a2cf 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -401,8 +401,11 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
rrc_rlc_remove_ue(&ctxt);
- // WHAT A RACE CONDITION
+ // lock the scheduler before removing the UE. Note: mac_remove_nr_ue() checks
+ // that the scheduler is actually locked!
+ NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock);
mac_remove_nr_ue(RC.nrmac[rrc->module_id], rnti);
+ NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock);
gtpv1u_enb_delete_tunnel_req_t tmp={0};
tmp.rnti=rnti;
tmp.from_gnb=1;