From b257734c6fed9889215e75005b9ee5568294bc0a Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Oct 2023 12:48:57 +0200 Subject: [PATCH 1/5] Fix tPool calls: symmetric to pushing messages Messages are pushed using pushNotifiedFIFO(), so we pullNotifiedFIFO() --- executables/nr-gnb.c | 14 ++++++-------- nfapi/oai_integration/nfapi_pnf.c | 2 +- openair1/SCHED_NR/fapi_nr_l1.c | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index e4a9e4e5e6..675bc7c14f 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -290,7 +290,7 @@ void rx_func(void *param) pushTpool(&gNB->threadPool, res); } } else if (get_softmodem_params()->continuous_tx) { - notifiedFIFO_elt_t *res = pullTpool(&gNB->L1_tx_free, &gNB->threadPool); + notifiedFIFO_elt_t *res = pullNotifiedFIFO(&gNB->L1_tx_free); if (res == NULL) return; // Tpool has been stopped processingData_L1tx_t *syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res); @@ -420,10 +420,8 @@ void *nrL1_stats_thread(void *param) { // two parallel L1 tx threads. void *tx_reorder_thread(void* param) { PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; - notifiedFIFO_elt_t *resL1Reserve = NULL; - - resL1Reserve = pullTpool(&gNB->L1_tx_out, &gNB->threadPool); + notifiedFIFO_elt_t *resL1Reserve = pullNotifiedFIFO(&gNB->L1_tx_out); AssertFatal(resL1Reserve != NULL, "pullTpool() did not return start message in %s\n", __func__); int next_tx_slot=((processingData_L1tx_t *)NotifiedFifoData(resL1Reserve))->slot; @@ -436,15 +434,15 @@ void *tx_reorder_thread(void* param) { if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) { LOG_E(PHY,"order mistake\n"); resL1Reserve = NULL; - resL1 = pullTpool(&gNB->L1_tx_out, &gNB->threadPool); + resL1 = pullNotifiedFIFO(&gNB->L1_tx_out); } - } else { - resL1 = pullTpool(&gNB->L1_tx_out, &gNB->threadPool); + } else { + resL1 = pullNotifiedFIFO(&gNB->L1_tx_out); if (resL1 != NULL && ((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) { if (resL1Reserve) LOG_E(PHY,"error, have a stored packet, then a second one\n"); resL1Reserve = resL1; - resL1 = pullTpool(&gNB->L1_tx_out, &gNB->threadPool); + resL1 = pullNotifiedFIFO(&gNB->L1_tx_out); if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) LOG_E(PHY,"error, pull two msg, none is good\n"); } diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 3536f23a08..33f85a97ea 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -1112,7 +1112,7 @@ notifiedFIFO_elt_t *l1tx_message_extract(PHY_VARS_gNB *gNB, int frame, int slot) notifiedFIFO_elt_t *res; //TODO: This needs to be reworked for nfapi to work - res = pullTpool(&gNB->L1_tx_free, &gNB->threadPool); + res = pullNotifiedFIFO(&gNB->L1_tx_free); return res; } diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 9662780737..8d9a51d41a 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -161,7 +161,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) notifiedFIFO_elt_t *res=NULL; processingData_L1tx_t *msgTx=NULL; if (!gNB->reorder_thread_disable) { - res = pullTpool(&gNB->L1_tx_free, &gNB->threadPool); + res = pullNotifiedFIFO(&gNB->L1_tx_free); if (res == NULL) return; // Tpool has been stopped, nothing to process msgTx = (processingData_L1tx_t *)NotifiedFifoData(res); From 1fb68160b0cb49ba4ab076c6962ddeeb3313c3a5 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Oct 2023 12:49:38 +0200 Subject: [PATCH 2/5] config: harmonize number array parameters --- executables/softmodem-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index bdf942226f..1774f76f57 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -105,10 +105,10 @@ void get_common_options(uint32_t execmask) { paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC; checkedparam_t cmdline_CheckParams[] = CMDLINE_PARAMS_CHECK_DESC; - int numparams = sizeof(cmdline_params) / sizeof(paramdef_t); + int numparams = sizeofArray(cmdline_params); config_set_checkfunctions(cmdline_params, cmdline_CheckParams, numparams); - config_get(cmdline_params, sizeof(cmdline_params) / sizeof(paramdef_t), NULL); - nfapi_index = config_paramidx_fromname(cmdline_params, sizeof(cmdline_params) / sizeof(paramdef_t),"nfapi"); + config_get(cmdline_params, numparams, NULL); + nfapi_index = config_paramidx_fromname(cmdline_params, numparams, "nfapi"); AssertFatal(nfapi_index >= 0,"Index for nfapi config option not found!"); nfapi_mode = config_get_processedint(&cmdline_params[nfapi_index]); From 75cc625fe96e0b7a10ea141e7206a94b69a4db5a Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Oct 2023 12:50:28 +0200 Subject: [PATCH 3/5] Use recursive mutex in PDCP to prevent deadlocks --- openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c index 5d28872854..782ba1dbf9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c @@ -45,7 +45,13 @@ nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag) exit(1); } - if (pthread_mutex_init(&ret->lock, NULL)) abort(); + pthread_mutexattr_t Attr; + pthread_mutexattr_init(&Attr); + // We need to be recursive because pdcp locks before forwarding, and calls in same thread, + // so, if same thread wants to send something back, and there is no itti intermediate thread, we deadlock on ourselves + pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE); + if (pthread_mutex_init(&ret->lock, &Attr)) + abort(); ret->enb_flag = enb_flag; return ret; From 724c8c014caeaa409b96b1d1c035a66cebbcefac Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Oct 2023 12:47:58 +0200 Subject: [PATCH 4/5] Simplify ITTI task definition --- common/utils/ocp_itti/intertask_interface.h | 120 +++++++++----------- 1 file changed, 51 insertions(+), 69 deletions(-) diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 131606f6fe..4d761cefe1 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -275,87 +275,69 @@ typedef uint32_t itti_message_types_t; typedef unsigned long message_number_t; #define MESSAGE_NUMBER_SIZE (sizeof(unsigned long)) -typedef enum task_priorities_e { - TASK_PRIORITY_MAX = 100, - TASK_PRIORITY_MAX_LEAST = 85, - TASK_PRIORITY_MED_PLUS = 70, - TASK_PRIORITY_MED = 55, - TASK_PRIORITY_MED_LEAST = 40, - TASK_PRIORITY_MIN_PLUS = 25, - TASK_PRIORITY_MIN = 10, -} task_priorities_t; - typedef struct { - task_priorities_t priority; unsigned int queue_size; /* Printable name */ char name[256]; - void *(*func)(void *) ; - void *(*threadFunc)(void *) ; } task_info_t; -// -//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL) -//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) -//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL) -//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL) -void *rrc_enb_process_msg(void *); -#define FOREACH_TASK(TASK_DEF) \ - TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \ - TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \ - TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX, 200, NULL, NULL) \ - TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_MAC_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_PDCP_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_NGAP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_M3AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_M3AP_MME, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_M3AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_GNB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_MCE_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_MME_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_PHY_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_MAC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RLC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_PDCP_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000, NULL, NULL) \ - TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_CUCP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_CUUP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_NSA_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_RRC_NSA_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_NAS_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \ - TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL) -#define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc }, +#define FOREACH_TASK(TASK_DEF) \ + TASK_DEF(TASK_UNKNOWN, 50) \ + TASK_DEF(TASK_TIMER, 10) \ + TASK_DEF(TASK_L2L1, 200) \ + TASK_DEF(TASK_BM, 200) \ + TASK_DEF(TASK_PHY_ENB, 200) \ + TASK_DEF(TASK_MAC_GNB, 200) \ + TASK_DEF(TASK_RLC_ENB, 200) \ + TASK_DEF(TASK_RRC_ENB_NB_IoT, 200) \ + TASK_DEF(TASK_PDCP_ENB, 200) \ + TASK_DEF(TASK_PDCP_GNB, 200) \ + TASK_DEF(TASK_DATA_FORWARDING, 200) \ + TASK_DEF(TASK_END_MARKER, 200) \ + TASK_DEF(TASK_RRC_ENB, 200) \ + TASK_DEF(TASK_RRC_GNB, 200) \ + TASK_DEF(TASK_RAL_ENB, 200) \ + TASK_DEF(TASK_S1AP, 200) \ + TASK_DEF(TASK_NGAP, 200) \ + TASK_DEF(TASK_X2AP, 200) \ + TASK_DEF(TASK_M2AP_ENB, 200) \ + TASK_DEF(TASK_M2AP_MCE, 200) \ + TASK_DEF(TASK_M3AP, 200) \ + TASK_DEF(TASK_M3AP_MME, 200) \ + TASK_DEF(TASK_M3AP_MCE, 200) \ + TASK_DEF(TASK_SCTP, 200) \ + TASK_DEF(TASK_ENB_APP, 200) \ + TASK_DEF(TASK_GNB_APP, 200) \ + TASK_DEF(TASK_MCE_APP, 200) \ + TASK_DEF(TASK_MME_APP, 200) \ + TASK_DEF(TASK_PHY_UE, 200) \ + TASK_DEF(TASK_MAC_UE, 200) \ + TASK_DEF(TASK_RLC_UE, 200) \ + TASK_DEF(TASK_PDCP_UE, 200) \ + TASK_DEF(TASK_RRC_UE, 200) \ + TASK_DEF(TASK_RRC_NRUE, 200) \ + TASK_DEF(TASK_NAS_UE, 200) \ + TASK_DEF(TASK_RAL_UE, 200) \ + TASK_DEF(TASK_GTPV1_U, 1000) \ + TASK_DEF(TASK_CU_F1, 200) \ + TASK_DEF(TASK_DU_F1, 200) \ + TASK_DEF(TASK_CUCP_E1, 200) \ + TASK_DEF(TASK_CUUP_E1, 200) \ + TASK_DEF(TASK_RRC_UE_SIM, 200) \ + TASK_DEF(TASK_RRC_GNB_SIM, 200) \ + TASK_DEF(TASK_RRC_NSA_UE, 200) \ + TASK_DEF(TASK_RRC_NSA_NRUE, 200) \ + TASK_DEF(TASK_NAS_NRUE, 200) \ + TASK_DEF(TASK_MAX, 200) + +#define TASK_DEF(TaskID, qUEUEsIZE) {qUEUEsIZE, #TaskID}, /* Map task id to printable name. */ static const task_info_t tasks_info[] = { FOREACH_TASK(TASK_DEF) }; -#define TASK_ENUM(TaskID, pRIO, qUEUEsIZE, FuNc,ThreadFunc ) TaskID, +#define TASK_ENUM(TaskID, qUEUEsIZE) TaskID, //! Tasks id of each task typedef enum { FOREACH_TASK(TASK_ENUM) From a1982390848818c887f7c1a0dd92159fe3b74e78 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Oct 2023 12:52:44 +0200 Subject: [PATCH 5/5] Introduce no-thread mode in ITTI Introduce a --no-itti-threads command line option to disable threading in ITTI, and call message handlers in the current thread. This is being introduced in order to increase repeatability when testing the nrUE with the IQPlayer. Without this feature, runs with the IQPlayer will end up differently, depending on the timing of ITTI threads, mostly when sending messages to RRC and NAS. --- common/utils/ocp_itti/intertask_interface.cpp | 41 ++- common/utils/ocp_itti/intertask_interface.h | 8 +- executables/create_tasks_ue.c | 4 +- executables/nr-uesoftmodem.c | 6 +- executables/softmodem-common.h | 4 + .../SIMULATION/NR_PHY/nr_dummy_functions.c | 4 + openair2/RRC/NR_UE/rrc_UE.c | 343 ++++++++++-------- openair2/RRC/NR_UE/rrc_proto.h | 1 + openair3/NAS/NR_UE/nr_nas_msg_sim.c | 224 ++++++------ openair3/NAS/NR_UE/nr_nas_msg_sim.h | 1 + 10 files changed, 344 insertions(+), 292 deletions(-) diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 941e4de6ef..8c4da1d92c 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -30,17 +30,19 @@ extern "C" { #include #include +#include "executables/softmodem-common.h" - typedef struct timer_elm_s { - timer_type_t type; ///< Timer type - long instance; - long duration; - uint64_t timeout; - void *timer_arg; ///< Optional argument that will be passed when timer expires - } timer_elm_t ; +typedef struct timer_elm_s { + timer_type_t type; ///< Timer type + long instance; + long duration; + uint64_t timeout; + void *timer_arg; ///< Optional argument that will be passed when timer expires +} timer_elm_t; typedef struct task_list_s { task_info_t admin; + ittiTask_parms_t task_parms; pthread_t thread; pthread_mutex_t queue_cond_lock; std::vector message_queue; @@ -162,12 +164,12 @@ extern "C" { pthread_mutex_lock (&t->queue_cond_lock); int ret=itti_send_msg_to_task_locked(destination_task_id, destinationInstance, message); - while ( t->message_queue.size()>0 && t->admin.func != NULL ) { + while (t->message_queue.size() > 0 && t->task_parms.shortcut_func != NULL) { if (t->message_queue.size()>1) LOG_W(ITTI,"queue in no thread mode is %ld\n", t->message_queue.size()); pthread_mutex_unlock (&t->queue_cond_lock); - t->admin.func(NULL); + t->task_parms.shortcut_func(NULL); pthread_mutex_lock (&t->queue_cond_lock); } @@ -327,11 +329,20 @@ extern "C" { pthread_mutex_unlock (&t->queue_cond_lock); } - int itti_create_task(task_id_t task_id, - void *(*start_routine)(void *), - void *args_p) { + int itti_create_task(const task_id_t task_id, void *(*start_routine)(void *), const ittiTask_parms_t *parms) + { task_list_t *t=tasks[task_id]; - threadCreate (&t->thread, start_routine, args_p, (char *)itti_get_task_name(task_id),-1,OAI_PRIORITY_RT); + if (get_softmodem_params()->no_itti && task_id < sizeofArray(tasks_info) && parms && parms->shortcut_func) { + LOG_W(ITTI, "not starting the thread for %s, the msg processing will be done in place\n", tasks_info[task_id].name); + t->task_parms.shortcut_func = parms->shortcut_func; + return 0; + } + threadCreate(&t->thread, + start_routine, + parms ? parms->args_to_start_routine : NULL, + (char *)itti_get_task_name(task_id), + -1, + OAI_PRIORITY_RT); LOG_I(ITTI,"Created Posix thread %s\n", itti_get_task_name(task_id) ); return 0; } @@ -353,6 +364,7 @@ extern "C" { AssertFatal(new_tasks != NULL, "could not realloc() tasks list"); tasks = new_tasks; tasks[newQueue]= new task_list_t; + tasks[newQueue]->task_parms = {0}; pthread_mutex_unlock (&lock_nb_queues); LOG_I(ITTI,"Starting itti queue: %s as task %d\n", taskInfo->name, newQueue); pthread_mutex_init(&tasks[newQueue]->queue_cond_lock, NULL); @@ -361,9 +373,6 @@ extern "C" { AssertFatal( ( tasks[newQueue]->sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, ""); itti_subscribe_event_fd((task_id_t)newQueue, tasks[newQueue]->sem_fd); - if (tasks[newQueue]->admin.threadFunc != NULL) - itti_create_task((task_id_t)newQueue, tasks[newQueue]->admin.threadFunc, NULL); - return newQueue; } diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 4d761cefe1..7756499039 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -484,9 +484,11 @@ void itti_poll_msg(task_id_t task_id, MessageDef **received_msg); \param args_p Optional argument to pass to the start routine @returns -1 on failure, 0 otherwise **/ -int itti_create_task(task_id_t task_id, - void *(*start_routine) (void *), - void *args_p); +typedef struct { + void *args_to_start_routine; + void *(*shortcut_func)(void *); +} ittiTask_parms_t; +int itti_create_task(const task_id_t task_id, void *(*start_routine)(void *), const ittiTask_parms_t *args_p); int itti_create_queue(const task_info_t *task_info); diff --git a/executables/create_tasks_ue.c b/executables/create_tasks_ue.c index 2172827b03..728e4546b5 100644 --- a/executables/create_tasks_ue.c +++ b/executables/create_tasks_ue.c @@ -47,8 +47,8 @@ int create_tasks_ue(uint32_t ue_nb) { if (users == NULL) abort(); users->count = ue_nb; - - if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { + ittiTask_parms_t parms = {users, NULL}; + if (itti_create_task(TASK_NAS_UE, nas_ue_task, &parms) < 0) { LOG_E(NAS, "Create task for NAS UE failed\n"); return -1; } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index e5332e8e5e..eee4072eeb 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -197,7 +197,8 @@ int create_tasks_nrue(uint32_t ue_nb) { if (ue_nb > 0) { LOG_I(NR_RRC,"create TASK_RRC_NRUE \n"); - if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { + const ittiTask_parms_t parmsRRC = {NULL, rrc_nrue}; + if (itti_create_task(TASK_RRC_NRUE, rrc_nrue_task, &parmsRRC) < 0) { LOG_E(NR_RRC, "Create task for RRC UE failed\n"); return -1; } @@ -208,7 +209,8 @@ int create_tasks_nrue(uint32_t ue_nb) { return -1; } } - if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { + const ittiTask_parms_t parmsNAS = {NULL, nas_nrue}; + if (itti_create_task(TASK_NAS_NRUE, nas_nrue_task, &parmsNAS) < 0) { LOG_E(NR_RRC, "Create task for NAS UE failed\n"); return -1; } diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index aa26dd1afc..90915f9983 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -109,6 +109,7 @@ extern "C" #define CONFIG_HLP_SYNC_REF "Sync Reference in Sidelink\n" #define CONFIG_HLP_NID1 "Set NID1 value in Sidelink\n" #define CONFIG_HLP_NID2 "Set NID2 value in Sidelink\n" +#define CONFIG_HLP_NOITTI "Do not start itti threads, call queue processing in place, inside the caller thread" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -190,6 +191,7 @@ extern int usrp_tx_thread; {"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \ {"nid1", CONFIG_HLP_NID1, 0, .iptr=&NID1, .defintval=10, TYPE_INT, 0}, \ {"nid2", CONFIG_HLP_NID2, 0, .iptr=&NID2, .defintval=1, TYPE_INT, 0}, \ + {"no-itti-threads", CONFIG_HLP_NOITTI, PARAMFLAG_BOOL, .iptr=&softmodem_params.no_itti, .defintval=0, TYPE_INT, 0}, \ } // clang-format on @@ -238,6 +240,7 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } // clang-format on @@ -349,6 +352,7 @@ typedef struct { int sync_ref; int nid1; int nid2; + int no_itti; } softmodem_params_t; extern uint64_t get_softmodem_optmask(void); diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index bf1a60faf8..ed72823789 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -51,3 +51,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } +void *rrc_nrue(void *notUsed) +{ + return NULL; +} diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 709ffa50e4..b8a55e71e3 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1729,172 +1729,193 @@ void nr_rrc_handle_ra_indication(unsigned int mod_id, bool ra_succeeded) // reconfigurationWithSync is included in spCellConfig } } - void *rrc_nrue_task(void *args_p) { - MessageDef *msg_p; - instance_t instance; - unsigned int ue_mod_id; - int result; - protocol_ctxt_t ctxt; - itti_mark_task_ready(TASK_RRC_NRUE); + itti_mark_task_ready(TASK_RRC_NRUE); - while(1) { - // Wait for a message - itti_receive_msg (TASK_RRC_NRUE, &msg_p); - instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); - ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - LOG_W(NR_RRC, " *** Exiting RRC thread\n"); - itti_exit_task (); - break; - - case MESSAGE_TEST: - LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - - case NR_RRC_MAC_SYNC_IND: - LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", - ue_mod_id, - ITTI_MSG_NAME (msg_p), - NR_RRC_MAC_SYNC_IND (msg_p).frame); - nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND (msg_p).in_sync ? - IN_SYNC : OUT_OF_SYNC; - NR_UE_Timers_Constants_t *tac = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; - handle_rlf_sync(tac, sync_msg); - break; - - case NRRRC_FRAME_PROCESS: - LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", - ue_mod_id, ITTI_MSG_NAME (msg_p), NRRRC_FRAME_PROCESS (msg_p).frame); - // increase the timers every 10ms (every new frame) - NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; - nr_rrc_handle_timers(timers); - NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[ue_mod_id].SInfo[NRRRC_FRAME_PROCESS (msg_p).gnb_id]; - nr_rrc_SI_timers(SInfo); - break; - - case NR_RRC_MAC_MSG3_IND: - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_MSG3_IND (msg_p).rnti, 0, 0); - LOG_D(NR_RRC, "[UE %d] Received %s for RNTI %d\n", - ue_mod_id, - ITTI_MSG_NAME (msg_p), - NR_RRC_MAC_MSG3_IND (msg_p).rnti); - nr_rrc_ue_generate_ra_msg(ue_mod_id, NR_RRC_MAC_MSG3_IND (msg_p).rnti); - break; - - case NR_RRC_MAC_RA_IND: - LOG_D(NR_RRC, "[UE %d] Received %s: frame %d RA %s\n", - ue_mod_id, - ITTI_MSG_NAME (msg_p), - NR_RRC_MAC_RA_IND (msg_p).frame, - NR_RRC_MAC_RA_IND (msg_p).RA_succeeded ? "successful" : "failed"); - nr_rrc_handle_ra_indication(ue_mod_id, NR_RRC_MAC_RA_IND (msg_p).RA_succeeded); - break; - - case NR_RRC_MAC_BCCH_DATA_IND: - LOG_D(NR_RRC, "[UE %d] Received %s: gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), - NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); - NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND (msg_p); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, bcch->frame, 0, bcch->gnb_index); - if (bcch->is_bch) - nr_rrc_ue_decode_NR_BCCH_BCH_Message(ue_mod_id, - bcch->gnb_index, - bcch->sdu, - bcch->sdu_size); - else - nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(ctxt.module_id, - bcch->gnb_index, - bcch->sdu, - bcch->sdu_size, - bcch->rsrq, - bcch->rsrp); - break; - - case NR_RRC_MAC_CCCH_DATA_IND: - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, 0, 0); - nr_rrc_ue_decode_ccch(&ctxt, - NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu, - NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size, - /* gNB_index = */ 0); - break; - - /* PDCP messages */ - case NR_RRC_DCCH_DATA_IND: - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, - NR_RRC_DCCH_DATA_IND (msg_p).module_id, - GNB_FLAG_NO, - NR_RRC_DCCH_DATA_IND (msg_p).rnti, - NR_RRC_DCCH_DATA_IND (msg_p).frame, - 0, - NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); - LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n", - NR_RRC_DCCH_DATA_IND (msg_p).module_id, - ITTI_MSG_NAME (msg_p), - NR_RRC_DCCH_DATA_IND (msg_p).frame, - NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); - LOG_D(NR_RRC, PROTOCOL_RRC_CTXT_UE_FMT"Received %s DCCH %d, gNB %d\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), - ITTI_MSG_NAME (msg_p), - NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); - nr_rrc_ue_decode_dcch ( - &ctxt, - NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND (msg_p).sdu_p, - NR_RRC_DCCH_DATA_IND (msg_p).sdu_size, - NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); - break; - - case NAS_KENB_REFRESH_REQ: - memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb)); - LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KgNB = " - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x\n", - ue_mod_id, ITTI_MSG_NAME (msg_p), - NR_UE_rrc_inst[ue_mod_id].kgnb[0], NR_UE_rrc_inst[ue_mod_id].kgnb[1], NR_UE_rrc_inst[ue_mod_id].kgnb[2], NR_UE_rrc_inst[ue_mod_id].kgnb[3], - NR_UE_rrc_inst[ue_mod_id].kgnb[4], NR_UE_rrc_inst[ue_mod_id].kgnb[5], NR_UE_rrc_inst[ue_mod_id].kgnb[6], NR_UE_rrc_inst[ue_mod_id].kgnb[7], - NR_UE_rrc_inst[ue_mod_id].kgnb[8], NR_UE_rrc_inst[ue_mod_id].kgnb[9], NR_UE_rrc_inst[ue_mod_id].kgnb[10], NR_UE_rrc_inst[ue_mod_id].kgnb[11], - NR_UE_rrc_inst[ue_mod_id].kgnb[12], NR_UE_rrc_inst[ue_mod_id].kgnb[13], NR_UE_rrc_inst[ue_mod_id].kgnb[14], NR_UE_rrc_inst[ue_mod_id].kgnb[15], - NR_UE_rrc_inst[ue_mod_id].kgnb[16], NR_UE_rrc_inst[ue_mod_id].kgnb[17], NR_UE_rrc_inst[ue_mod_id].kgnb[18], NR_UE_rrc_inst[ue_mod_id].kgnb[19], - NR_UE_rrc_inst[ue_mod_id].kgnb[20], NR_UE_rrc_inst[ue_mod_id].kgnb[21], NR_UE_rrc_inst[ue_mod_id].kgnb[22], NR_UE_rrc_inst[ue_mod_id].kgnb[23], - NR_UE_rrc_inst[ue_mod_id].kgnb[24], NR_UE_rrc_inst[ue_mod_id].kgnb[25], NR_UE_rrc_inst[ue_mod_id].kgnb[26], NR_UE_rrc_inst[ue_mod_id].kgnb[27], - NR_UE_rrc_inst[ue_mod_id].kgnb[28], NR_UE_rrc_inst[ue_mod_id].kgnb[29], NR_UE_rrc_inst[ue_mod_id].kgnb[30], NR_UE_rrc_inst[ue_mod_id].kgnb[31]); - break; - - case NAS_UPLINK_DATA_REQ: { - uint32_t length; - uint8_t *buffer; - LOG_I(NR_RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NAS_UPLINK_DATA_REQ (msg_p).UEid); - /* Create message for PDCP (ULInformationTransfer_t) */ - length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); - /* Transfer data to PDCP */ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0,0); - // check if SRB2 is created, if yes request data_req on SRB2 - rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].Srb[0][2].status == RB_ESTABLISHED ? 2 : 1; - nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL); - break; - } - - default: - LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - } - LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, NR_UE_rrc_inst[ue_mod_id].nrRrcState); - result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - msg_p = NULL; + while (1) { + rrc_nrue(NULL); } } + +void *rrc_nrue(void *notUsed) +{ + protocol_ctxt_t ctxt; + + MessageDef *msg_p = NULL; + itti_receive_msg(TASK_RRC_NRUE, &msg_p); + instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); + unsigned int ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting RRC thread\n"); + itti_exit_task(); + break; + + case MESSAGE_TEST: + LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME(msg_p)); + break; + + case NR_RRC_MAC_SYNC_IND: + LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_SYNC_IND(msg_p).frame); + nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND(msg_p).in_sync ? IN_SYNC : OUT_OF_SYNC; + NR_UE_Timers_Constants_t *tac = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; + handle_rlf_sync(tac, sync_msg); + break; + + case NRRRC_FRAME_PROCESS: + LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NRRRC_FRAME_PROCESS(msg_p).frame); + // increase the timers every 10ms (every new frame) + NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; + nr_rrc_handle_timers(timers); + NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[ue_mod_id].SInfo[NRRRC_FRAME_PROCESS(msg_p).gnb_id]; + nr_rrc_SI_timers(SInfo); + break; + + case NR_RRC_MAC_MSG3_IND: + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_MSG3_IND(msg_p).rnti, 0, 0); + LOG_D(NR_RRC, "[UE %d] Received %s for RNTI %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_MSG3_IND(msg_p).rnti); + nr_rrc_ue_generate_ra_msg(ue_mod_id, NR_RRC_MAC_MSG3_IND(msg_p).rnti); + break; + + case NR_RRC_MAC_RA_IND: + LOG_D(NR_RRC, + "[UE %d] Received %s: frame %d RA %s\n", + ue_mod_id, + ITTI_MSG_NAME(msg_p), + NR_RRC_MAC_RA_IND(msg_p).frame, + NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed"); + nr_rrc_handle_ra_indication(ue_mod_id, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded); + break; + + case NR_RRC_MAC_BCCH_DATA_IND: + LOG_D(NR_RRC, "[UE %d] Received %s: gNB %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_BCCH_DATA_IND(msg_p).gnb_index); + NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND(msg_p); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, bcch->frame, 0, bcch->gnb_index); + if (bcch->is_bch) + nr_rrc_ue_decode_NR_BCCH_BCH_Message(ue_mod_id, bcch->gnb_index, bcch->sdu, bcch->sdu_size); + else + nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(ctxt.module_id, + bcch->gnb_index, + bcch->sdu, + bcch->sdu_size, + bcch->rsrq, + bcch->rsrp); + break; + + case NR_RRC_MAC_CCCH_DATA_IND: + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti, 0, 0); + nr_rrc_ue_decode_ccch(&ctxt, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, + /* gNB_index = */ 0); + break; + + /* PDCP messages */ + case NR_RRC_DCCH_DATA_IND: + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, + NR_RRC_DCCH_DATA_IND(msg_p).module_id, + GNB_FLAG_NO, + NR_RRC_DCCH_DATA_IND(msg_p).rnti, + NR_RRC_DCCH_DATA_IND(msg_p).frame, + 0, + NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); + LOG_D(NR_RRC, + "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n", + NR_RRC_DCCH_DATA_IND(msg_p).module_id, + ITTI_MSG_NAME(msg_p), + NR_RRC_DCCH_DATA_IND(msg_p).frame, + NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); + LOG_D(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT "Received %s DCCH %d, gNB %d\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), + ITTI_MSG_NAME(msg_p), + NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); + nr_rrc_ue_decode_dcch(&ctxt, + NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, + NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, + NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); + break; + + case NAS_KENB_REFRESH_REQ: + memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, + (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, + sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb)); + LOG_D(RRC, + "[UE %d] Received %s: refreshed RRC::KgNB = " + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x\n", + ue_mod_id, + ITTI_MSG_NAME(msg_p), + NR_UE_rrc_inst[ue_mod_id].kgnb[0], + NR_UE_rrc_inst[ue_mod_id].kgnb[1], + NR_UE_rrc_inst[ue_mod_id].kgnb[2], + NR_UE_rrc_inst[ue_mod_id].kgnb[3], + NR_UE_rrc_inst[ue_mod_id].kgnb[4], + NR_UE_rrc_inst[ue_mod_id].kgnb[5], + NR_UE_rrc_inst[ue_mod_id].kgnb[6], + NR_UE_rrc_inst[ue_mod_id].kgnb[7], + NR_UE_rrc_inst[ue_mod_id].kgnb[8], + NR_UE_rrc_inst[ue_mod_id].kgnb[9], + NR_UE_rrc_inst[ue_mod_id].kgnb[10], + NR_UE_rrc_inst[ue_mod_id].kgnb[11], + NR_UE_rrc_inst[ue_mod_id].kgnb[12], + NR_UE_rrc_inst[ue_mod_id].kgnb[13], + NR_UE_rrc_inst[ue_mod_id].kgnb[14], + NR_UE_rrc_inst[ue_mod_id].kgnb[15], + NR_UE_rrc_inst[ue_mod_id].kgnb[16], + NR_UE_rrc_inst[ue_mod_id].kgnb[17], + NR_UE_rrc_inst[ue_mod_id].kgnb[18], + NR_UE_rrc_inst[ue_mod_id].kgnb[19], + NR_UE_rrc_inst[ue_mod_id].kgnb[20], + NR_UE_rrc_inst[ue_mod_id].kgnb[21], + NR_UE_rrc_inst[ue_mod_id].kgnb[22], + NR_UE_rrc_inst[ue_mod_id].kgnb[23], + NR_UE_rrc_inst[ue_mod_id].kgnb[24], + NR_UE_rrc_inst[ue_mod_id].kgnb[25], + NR_UE_rrc_inst[ue_mod_id].kgnb[26], + NR_UE_rrc_inst[ue_mod_id].kgnb[27], + NR_UE_rrc_inst[ue_mod_id].kgnb[28], + NR_UE_rrc_inst[ue_mod_id].kgnb[29], + NR_UE_rrc_inst[ue_mod_id].kgnb[30], + NR_UE_rrc_inst[ue_mod_id].kgnb[31]); + break; + + case NAS_UPLINK_DATA_REQ: { + uint32_t length; + uint8_t *buffer; + LOG_I(NR_RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NAS_UPLINK_DATA_REQ(msg_p).UEid); + /* Create message for PDCP (ULInformationTransfer_t) */ + length = + do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ(msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ(msg_p).nasMsg.data); + /* Transfer data to PDCP */ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0, 0); + // check if SRB2 is created, if yes request data_req on SRB2 + rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].Srb[0][2].status == RB_ESTABLISHED ? 2 : 1; + nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL); + break; + } + + default: + LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME(msg_p)); + break; + } + LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, NR_UE_rrc_inst[ue_mod_id].nrRrcState); + int result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + return NULL; +} + void nr_rrc_ue_process_sidelink_radioResourceConfig( module_id_t Mod_idP, uint8_t gNB_index, diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 335b9ba84d..69c2d1af82 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -114,6 +114,7 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index); /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_nrue_task(void *args_p); +void *rrc_nrue(void *args_p); void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 59ff269edd..015b2a8f9e 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -57,7 +57,7 @@ uint8_t *registration_request_buf; uint32_t registration_request_len; extern char *baseNetAddress; extern uint16_t NB_UE_INST; -static nr_ue_nas_t nr_ue_nas; +static nr_ue_nas_t nr_ue_nas = {0}; static int nas_protected_security_header_encode( char *buffer, @@ -416,6 +416,8 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) { nr_ue_nas_t *get_ue_nas_info(module_id_t module_id) { DevAssert(module_id == 0); + if (!nr_ue_nas.uicc) + nr_ue_nas.uicc = checkUicc(0); return &nr_ue_nas; } @@ -912,97 +914,105 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i void *nas_nrue_task(void *args_p) { - MessageDef *msg_p; - instance_t instance; - int result; - uint8_t msg_type = 0; - uint8_t *pdu_buffer = NULL; - - nr_ue_nas.uicc = checkUicc(0); - nr_ue_nas_t *nas = get_ue_nas_info(0); - itti_mark_task_ready (TASK_NAS_NRUE); - - while(1) { - // Wait for a message or an event - itti_receive_msg (TASK_NAS_NRUE, &msg_p); + while (1) { + nas_nrue(NULL); + } +} - if (msg_p != NULL) { - instance = msg_p->ittiMsgHeader.originInstance; - AssertFatal(instance == 0, "cannot handle more than one UE!\n"); +void *nas_nrue(void *args_p) +{ + // Wait for a message or an event + nr_ue_nas.uicc = checkUicc(0); + MessageDef *msg_p; + itti_receive_msg(TASK_NAS_NRUE, &msg_p); - switch (ITTI_MSG_ID(msg_p)) { - case INITIALIZE_MESSAGE: + if (msg_p != NULL) { + instance_t instance = msg_p->ittiMsgHeader.originInstance; + AssertFatal(instance == 0, "cannot handle more than one UE!\n"); - break; + switch (ITTI_MSG_ID(msg_p)) { + case INITIALIZE_MESSAGE: - case TERMINATE_MESSAGE: - itti_exit_task(); - break; + break; - case MESSAGE_TEST: - break; + case TERMINATE_MESSAGE: + itti_exit_task(); + break; - case NAS_CELL_SELECTION_CNF: - LOG_I(NAS, - "[UE %ld] Received %s: errCode %u, cellID %u, tac %u\n", - instance, - ITTI_MSG_NAME(msg_p), - NAS_CELL_SELECTION_CNF(msg_p).errCode, - NAS_CELL_SELECTION_CNF(msg_p).cellID, - NAS_CELL_SELECTION_CNF(msg_p).tac); - // as_stmsi_t s_tmsi={0, 0}; - // as_nas_info_t nas_info; - // plmn_t plmnID={0, 0, 0, 0}; - // generateRegistrationRequest(&nas_info); - // nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0); - break; + case MESSAGE_TEST: + break; - case NAS_CELL_SELECTION_IND: - LOG_I(NAS, "[UE %ld] Received %s: cellID %u, tac %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_CELL_SELECTION_IND(msg_p).cellID, NAS_CELL_SELECTION_IND(msg_p).tac); + case NAS_CELL_SELECTION_CNF: + LOG_I(NAS, + "[UE %ld] Received %s: errCode %u, cellID %u, tac %u\n", + instance, + ITTI_MSG_NAME(msg_p), + NAS_CELL_SELECTION_CNF(msg_p).errCode, + NAS_CELL_SELECTION_CNF(msg_p).cellID, + NAS_CELL_SELECTION_CNF(msg_p).tac); + // as_stmsi_t s_tmsi={0, 0}; + // as_nas_info_t nas_info; + // plmn_t plmnID={0, 0, 0, 0}; + // generateRegistrationRequest(&nas_info); + // nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0); + break; - /* TODO not processed by NAS currently */ - break; + case NAS_CELL_SELECTION_IND: + LOG_I(NAS, + "[UE %ld] Received %s: cellID %u, tac %u\n", + instance, + ITTI_MSG_NAME(msg_p), + NAS_CELL_SELECTION_IND(msg_p).cellID, + NAS_CELL_SELECTION_IND(msg_p).tac); - case NAS_PAGING_IND: - LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause); + /* TODO not processed by NAS currently */ + break; - /* TODO not processed by NAS currently */ - break; + case NAS_PAGING_IND: + LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause); - case NAS_CONN_ESTABLI_CNF: { - LOG_I(NAS, "[UE %ld] Received %s: errCode %u, length %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).errCode, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); + /* TODO not processed by NAS currently */ + break; - pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data; - msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); + case NAS_CONN_ESTABLI_CNF: { + LOG_I(NAS, + "[UE %ld] Received %s: errCode %u, length %u\n", + instance, + ITTI_MSG_NAME(msg_p), + NAS_CONN_ESTABLI_CNF(msg_p).errCode, + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); - if (msg_type == REGISTRATION_ACCEPT) { - LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); - decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas); + uint8_t *pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data; + int msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); - as_nas_info_t initialNasMsg = {0}; - generateRegistrationComplete(nas, &initialNasMsg, NULL); - if (initialNasMsg.length > 0) { - send_nas_uplink_data_req(instance, &initialNasMsg); - LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); - } + if (msg_type == REGISTRATION_ACCEPT) { + LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); + nr_ue_nas_t *nas = get_ue_nas_info(0); + decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas); - as_nas_info_t pduEstablishMsg = {0}; - generatePduSessionEstablishRequest(nas, &pduEstablishMsg); - if (pduEstablishMsg.length > 0) { - send_nas_uplink_data_req(instance, &pduEstablishMsg); - LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); - } - } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { - capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); + as_nas_info_t initialNasMsg = {0}; + generateRegistrationComplete(nas, &initialNasMsg, NULL); + if (initialNasMsg.length > 0) { + send_nas_uplink_data_req(instance, &initialNasMsg); + LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } - break; + as_nas_info_t pduEstablishMsg = {0}; + generatePduSessionEstablishRequest(nas, &pduEstablishMsg); + if (pduEstablishMsg.length > 0) { + send_nas_uplink_data_req(instance, &pduEstablishMsg); + LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); + } + } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { + capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); + } + + break; } case NAS_CONN_RELEASE_IND: - LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME (msg_p), - NAS_CONN_RELEASE_IND (msg_p).cause); + LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_CONN_RELEASE_IND(msg_p).cause); /* the following is not clean, but probably necessary: we need to give * time to RLC to Ack the SRB1 PDU which contained the RRC release * message. Hence, we just below wait some time, before finally @@ -1012,45 +1022,48 @@ void *nas_nrue_task(void *args_p) break; case NAS_UPLINK_DATA_CNF: - LOG_I(NAS, "[UE %ld] Received %s: UEid %u, errCode %u\n", instance, ITTI_MSG_NAME (msg_p), - NAS_UPLINK_DATA_CNF (msg_p).UEid, NAS_UPLINK_DATA_CNF (msg_p).errCode); + LOG_I(NAS, + "[UE %ld] Received %s: UEid %u, errCode %u\n", + instance, + ITTI_MSG_NAME(msg_p), + NAS_UPLINK_DATA_CNF(msg_p).UEid, + NAS_UPLINK_DATA_CNF(msg_p).errCode); break; case NAS_DEREGISTRATION_REQ: { - LOG_I(NAS, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); - if (nas->guti) { - nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); - as_nas_info_t initialNasMsg = {0}; - generateDeregistrationRequest(nas, &initialNasMsg, req); - send_nas_uplink_data_req(instance, &initialNasMsg); - } else { - LOG_E(NAS, "no GUTI, cannot trigger deregistration request\n"); - } + LOG_I(NAS, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); + nr_ue_nas_t *nas = get_ue_nas_info(0); + if (nas->guti) { + nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); + as_nas_info_t initialNasMsg = {0}; + generateDeregistrationRequest(nas, &initialNasMsg, req); + send_nas_uplink_data_req(instance, &initialNasMsg); + } else { + LOG_E(NAS, "no GUTI, cannot trigger deregistration request\n"); } - break; + } break; - case NAS_DOWNLINK_DATA_IND: - { + case NAS_DOWNLINK_DATA_IND: { LOG_I(NAS, "[UE %ld] Received %s: length %u , buffer %p\n", instance, ITTI_MSG_NAME(msg_p), NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data); - as_nas_info_t initialNasMsg={0}; + as_nas_info_t initialNasMsg = {0}; - pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data; - msg_type = get_msg_type(pdu_buffer, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length); - - switch(msg_type){ + uint8_t *pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data; + int msg_type = get_msg_type(pdu_buffer, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length); + nr_ue_nas_t *nas = get_ue_nas_info(0); + switch (msg_type) { case FGS_IDENTITY_REQUEST: generateIdentityResponse(&initialNasMsg, *(pdu_buffer + 3), nas->uicc); - break; + break; case FGS_AUTHENTICATION_REQUEST: - generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer); - break; + generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer); + break; case FGS_SECURITY_MODE_COMMAND: nas_itti_kgnb_refresh_req(nas->security.kgnb); generateSecurityModeComplete(nas, &initialNasMsg); @@ -1109,28 +1122,23 @@ void *nas_nrue_task(void *args_p) } offset++; } - } - break; + } break; default: - LOG_W(NR_RRC,"unknown message type %d\n",msg_type); - break; + LOG_W(NR_RRC, "unknown message type %d\n", msg_type); + break; } - if (initialNasMsg.length > 0) - send_nas_uplink_data_req(instance, &initialNasMsg); - } - break; + if (initialNasMsg.length > 0) + send_nas_uplink_data_req(instance, &initialNasMsg); + } break; default: - LOG_E(NAS, "[UE %ld] Received unexpected message %s\n", instance, ITTI_MSG_NAME (msg_p)); + LOG_E(NAS, "[UE %ld] Received unexpected message %s\n", instance, ITTI_MSG_NAME(msg_p)); break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - msg_p = NULL; } - } + int result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } return NULL; } diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index fbf0362949..fa4911c738 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -174,6 +174,7 @@ typedef struct { nr_ue_nas_t *get_ue_nas_info(module_id_t module_id); void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas); void *nas_nrue_task(void *args_p); +void *nas_nrue(void *args_p); #endif /* __NR_NAS_MSG_SIM_H__*/