From a1982390848818c887f7c1a0dd92159fe3b74e78 Mon Sep 17 00:00:00 2001
From: Laurent THOMAS <laurent.thomas@open-cells.com>
Date: Fri, 27 Oct 2023 12:52:44 +0200
Subject: [PATCH] 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                   | 339 ++++++++++--------
 openair2/RRC/NR_UE/rrc_proto.h                |   1 +
 openair3/NAS/NR_UE/nr_nas_msg_sim.c           | 222 ++++++------
 openair3/NAS/NR_UE/nr_nas_msg_sim.h           |   1 +
 10 files changed, 341 insertions(+), 289 deletions(-)

diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index 941e4de6efe..8c4da1d92ce 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -30,17 +30,19 @@
 extern "C" {
 #include <intertask_interface.h>
 #include <common/utils/system.h>
+#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<MessageDef *> 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 4d761cefe1f..77564990399 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 2172827b03b..728e4546b56 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 e5332e8e5ef..eee4072eeb2 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 aa26dd1afce..90915f9983e 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 bf1a60faf8d..ed728237897 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 709ffa50e4b..b8a55e71e3b 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);
-
-   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;
+  itti_mark_task_ready(TASK_RRC_NRUE);
 
-       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;
-      }
+  while (1) {
+    rrc_nrue(NULL);
+  }
+}
 
-      default:
-        LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
-        break;
+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;
     }
-    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;
+
+    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 335b9ba84d9..69c2d1af822 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 59ff269edd0..015b2a8f9e5 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);
+  while (1) {
+    nas_nrue(NULL);
+  }
+}
 
+void *nas_nrue(void *args_p)
+{
+  // Wait for a message or an event
   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);
+  MessageDef *msg_p;
+  itti_receive_msg(TASK_NAS_NRUE, &msg_p);
 
-    if (msg_p != NULL) {
-      instance = msg_p->ittiMsgHeader.originInstance;
-      AssertFatal(instance == 0, "cannot handle more than one UE!\n");
+  if (msg_p != NULL) {
+    instance_t instance = msg_p->ittiMsgHeader.originInstance;
+    AssertFatal(instance == 0, "cannot handle more than one UE!\n");
 
-      switch (ITTI_MSG_ID(msg_p)) {
-        case INITIALIZE_MESSAGE:
+    switch (ITTI_MSG_ID(msg_p)) {
+      case INITIALIZE_MESSAGE:
 
-          break;
+        break;
 
-        case TERMINATE_MESSAGE:
-          itti_exit_task();
-          break;
+      case TERMINATE_MESSAGE:
+        itti_exit_task();
+        break;
 
-        case MESSAGE_TEST:
-          break;
+      case MESSAGE_TEST:
+        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 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 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_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);
 
-          /* 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_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_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);
+      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);
 
-          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);
+        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);
 
-          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);
+        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 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");
-            }
+          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");
+          }
 
-            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 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;
+        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};
-
-        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);
+        as_nas_info_t initialNasMsg = {0};
 
-        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 fbf0362949c..fa4911c7382 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__*/
 
-- 
GitLab