diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h
index 77ff6fd62fb4a6b09eca75a73788a9218c347cab..aab872cfe150607a06f6f19b2a23c435d57f82e3 100644
--- a/common/utils/msc/msc.h
+++ b/common/utils/msc/msc.h
@@ -48,6 +48,7 @@ typedef enum {
   MSC_MAC_ENB,
   MSC_RLC_ENB,
   MSC_PDCP_ENB,
+  MSC_PDCP_GNB,
   MSC_RRC_ENB,
   MSC_RRC_GNB,
   MSC_IP_ENB,
diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h
index 8531ce16a04503eb15460d371e71949ad0ef099a..86103dd91151b910a930814211c7119631b4e451 100644
--- a/openair2/COMMON/gtpv1_u_messages_def.h
+++ b/openair2/COMMON/gtpv1_u_messages_def.h
@@ -30,4 +30,7 @@ MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_dat
 MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ,      MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t,    Gtpv1uEndMarkerReq)
 MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND,      MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t,    Gtpv1uEndMarkerInd)
 MESSAGE_DEF(GTPV1U_ENB_S1_REQ,        MESSAGE_PRIORITY_MED, Gtpv1uS1Req,    gtpv1uS1Req)
+
+MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ,   MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t,  NRGtpv1uDeleteTunnelReq)
+MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP,  MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp)
 MESSAGE_DEF(GTPV1U_GNB_NG_REQ,        MESSAGE_PRIORITY_MED, Gtpv1uNGReq,    gtpv1uNGReq)
diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h
index c7e247f0fa83587a5b08895ff80ffb0a42597477..8fde34300060ffc4264b40e24ca30b1098a56b83 100644
--- a/openair2/COMMON/gtpv1_u_messages_types.h
+++ b/openair2/COMMON/gtpv1_u_messages_types.h
@@ -40,7 +40,10 @@
 #define GTPV1U_ENB_END_MARKER_IND(mSGpTR)     (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd
 
 #define GTPV1U_ENB_S1_REQ(mSGpTR)    (mSGpTR)->ittiMsg.gtpv1uS1Req
-#define GTPV1U_GNB_NG_REQ(mSGpTR)    (mSGpTR)->ittiMsg.gtpv1uNGReq
+
+#define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR)  (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq
+#define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp
+#define GTPV1U_GNB_NG_REQ(mSGpTR)             (mSGpTR)->ittiMsg.gtpv1uNGReq
 
 #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
 
@@ -195,4 +198,16 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s {
   transport_layer_addr_t gnb_addr;
 } gtpv1u_gnb_create_tunnel_resp_t;
 
+typedef struct gtpv1u_gnb_delete_tunnel_req_s {
+  rnti_t                 rnti;
+  uint8_t                num_pdusession;
+  pdusessionid_t         pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
+} gtpv1u_gnb_delete_tunnel_req_t;
+
+typedef struct gtpv1u_gnb_delete_tunnel_resp_s {
+  rnti_t                 rnti;
+  uint8_t                status;               ///< Status of NGU endpoint deleteion (Failed = 0xFF or Success = 0x0)
+  teid_t                 gnb_NGu_teid;         ///< local NGU Tunnel Endpoint Identifier to be deleted
+} gtpv1u_gnb_delete_tunnel_resp_t;
+
 #endif /* GTPV1_U_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h
index a2b40815d6952543f0d674392e8f673bdd06d185..af746b91933620ff657dbb752c91e48b51bf80c6 100644
--- a/openair2/COMMON/ngap_messages_types.h
+++ b/openair2/COMMON/ngap_messages_types.h
@@ -741,6 +741,10 @@ typedef struct ngap_ue_release_command_s {
 typedef struct pdusession_release_s {
   /* Unique pdusession_id for the UE. */
   uint8_t                     pdusession_id;
+  /* Octet string data */
+  uint8_t  *transfer_buffer;
+  /* Length of the octet string */
+  uint32_t  transfer_length;
 } pdusession_release_t;
 
 typedef struct ngap_ue_release_req_s {
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 27fb9a78297d49e9270ba586740a55428101d66c..09964eda7c154d5ee8f4f6425b287ecbe8abf85e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -523,6 +523,7 @@ typedef struct gNB_MAC_INST_s {
 
   /// UL handle
   uint32_t ul_handle;
+  UE_info_t UE_info;
 
   // MAC function execution peformance profiler
   /// processing time of eNB scheduler
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 5de9e96d853d5a13cad3e420d50db74f1e229322..e6e9e370cbf6bf71f5307c2e7a1d1b6955919174 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -69,6 +69,7 @@
 #include "NR_RRCReconfigurationComplete.h"
 #include "NR_RRCReconfigurationComplete-IEs.h"
 #include "NR_DLInformationTransfer.h"
+#include "NR_RRCReestablishmentRequest.h"
 #if defined(NR_Rel16)
   #include "NR_SCS-SpecificCarrier.h"
   #include "NR_TDD-UL-DL-ConfigCommon.h"
@@ -652,7 +653,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
                     int                          CC_id,
                     uint8_t                      *const buffer,
                     const uint8_t                transaction_id,
-                    NR_SRB_ToAddModList_t        *SRB_configList)
+                    NR_SRB_ToAddModList_t        **SRB_configList)
 //------------------------------------------------------------------------------
 {
     asn_enc_rval_t                                   enc_rval;;
@@ -684,19 +685,19 @@ uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
 
     /****************************** radioBearerConfig ******************************/
     /* Configure SRB1 */
-    if (SRB_configList) {
-        free(SRB_configList);
+    if (*SRB_configList) {
+        free(*SRB_configList);
     }
 
-    SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
+    *SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
     // SRB1
     /* TODO */
     SRB1_config = calloc(1, sizeof(NR_SRB_ToAddMod_t));
     SRB1_config->srb_Identity = 1;
     // pdcp_Config->t_Reordering
     SRB1_config->pdcp_Config = pdcp_Config;
-    ie->radioBearerConfig.srb_ToAddModList = SRB_configList;
-    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB1_config);
+    ie->radioBearerConfig.srb_ToAddModList = *SRB_configList;
+    ASN_SEQUENCE_ADD(&(*SRB_configList)->list, SRB1_config);
 
     ie->radioBearerConfig.srb3_ToRelease    = NULL;
     ie->radioBearerConfig.drb_ToAddModList  = NULL;
@@ -954,26 +955,25 @@ uint8_t do_NR_RRCRelease(uint8_t                            *buffer,
   return((enc_rval.encoded+7)/8);
 }
 
+//------------------------------------------------------------------------------
 uint16_t do_RRCReconfiguration(
     const protocol_ctxt_t        *const ctxt_pP,
-    rrc_gNB_ue_context_t         *const ue_context_pP,
     uint8_t                      *buffer,
-    uint8_t                      Transaction_id,
-    gNB_RRC_INST                 *gnb_rrc_inst
-)
+    uint8_t                       Transaction_id,
+    NR_SRB_ToAddModList_t        *SRB_configList,
+    NR_DRB_ToAddModList_t        *DRB_configList,
+    NR_DRB_ToReleaseList_t       *DRB_releaseList,
+    NR_SecurityConfig_t          *security_config,
+    NR_SDAP_Config_t             *sdap_config,
+    NR_MeasConfig_t              *meas_config,
+    struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
+                                 *dedicatedNAS_MessageList,
+    NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig)
+//------------------------------------------------------------------------------
 {
     NR_DL_DCCH_Message_t                             dl_dcch_msg;
     asn_enc_rval_t                                   enc_rval;
     NR_RRCReconfiguration_IEs_t                      *ie;
-    NR_SRB_ToAddModList_t                            *SRB_configList       = NULL;
-    NR_SRB_ToAddModList_t                            *SRB_configList2      = NULL;
-    NR_SRB_ToAddMod_t                                *SRB2_config          = NULL;
-    NR_DRB_ToAddModList_t                            *DRB_configList       = NULL;
-    NR_DRB_ToAddModList_t                            *DRB_configList2      = NULL;
-    NR_DRB_ToAddMod_t                                *DRB_config           = NULL;
-    NR_SDAP_Config_t                                 *sdap_config          = NULL;
-    NR_SecurityConfig_t                              *security_config      = NULL;
-    NR_DedicatedNAS_Message_t                        *dedicatedNAS_Message = NULL;
 
     memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
     dl_dcch_msg.message.present            = NR_DL_DCCH_MessageType_PR_c1;
@@ -985,73 +985,6 @@ uint16_t do_RRCReconfiguration(
     dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
 
     /******************** Radio Bearer Config ********************/
-    /* Configure SRB2 */
-    SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[Transaction_id];
-    SRB_configList = ue_context_pP->ue_context.SRB_configList;
-    SRB_configList = CALLOC(1, sizeof(*SRB_configList));
-    memset(SRB_configList, 0, sizeof(*SRB_configList));
-
-    if (SRB_configList2) {
-        free(SRB_configList2);
-    }
-
-    SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2));
-    memset(SRB_configList2, 0, sizeof(*SRB_configList2));
-    SRB2_config = CALLOC(1, sizeof(*SRB2_config));
-    SRB2_config->srb_Identity = 2;
-    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
-    ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB2_config);
-
-    /* Configure DRB */
-    DRB_configList = ue_context_pP->ue_context.DRB_configList;
-    if (DRB_configList) {
-        free(DRB_configList);
-    }
-
-    DRB_configList = CALLOC(1, sizeof(*DRB_configList));
-    memset(DRB_configList, 0, sizeof(*DRB_configList));
-
-    DRB_configList2 = ue_context_pP->ue_context.DRB_configList2[Transaction_id];
-    if (DRB_configList2) {
-        free(DRB_configList2);
-    }
-    DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
-    memset(DRB_configList2, 0, sizeof(*DRB_configList2));
-
-    DRB_config = CALLOC(1, sizeof(*DRB_config));
-    DRB_config->drb_Identity = 1;
-    DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
-    DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
-    // TODO sdap_Config
-    sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
-    memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
-    DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
-    // TODO pdcp_Config
-    DRB_config->reestablishPDCP = NULL;
-    DRB_config->recoverPDCP = NULL;
-    DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
-    DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
-    DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
-    *DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_ms30;
-    DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
-    *DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
-    DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
-    *DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
-    DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
-    DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
-
-    DRB_config->pdcp_Config->drb->integrityProtection = NULL;
-    DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
-    DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
-    DRB_config->pdcp_Config->moreThanOneRLC = NULL;
-
-    DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
-    *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
-    DRB_config->pdcp_Config->ext1 = NULL;
-
-    ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
-    ASN_SEQUENCE_ADD(&DRB_configList2->list, DRB_config);
-
     /* Configure Security */
     // security_config    =  CALLOC(1, sizeof(NR_SecurityConfig_t));
     // security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig));
@@ -1066,7 +999,7 @@ uint16_t do_RRCReconfiguration(
     ie->radioBearerConfig->drb_ToAddModList  = DRB_configList;
     ie->radioBearerConfig->securityConfig    = security_config;
     ie->radioBearerConfig->srb3_ToRelease    = NULL;
-    ie->radioBearerConfig->drb_ToReleaseList = NULL;
+    ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
 
     /******************** Secondary Cell Group ********************/
     // rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
@@ -1079,16 +1012,12 @@ uint16_t do_RRCReconfiguration(
 
     /******************** Meas Config ********************/
     // measConfig
-    ie->measConfig = NULL;
+    ie->measConfig = meas_config;
     // lateNonCriticalExtension
     ie->lateNonCriticalExtension = NULL;
     // nonCriticalExtension
     ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
-    dedicatedNAS_Message = calloc(1, sizeof(NR_DedicatedNAS_Message_t));
-    dedicatedNAS_Message->buf  = ue_context_pP->ue_context.nas_pdu.buffer;
-    dedicatedNAS_Message->size = ue_context_pP->ue_context.nas_pdu.length;
-	ie->nonCriticalExtension->dedicatedNAS_MessageList = calloc(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
-    ASN_SEQUENCE_ADD(&ie->nonCriticalExtension->dedicatedNAS_MessageList->list, dedicatedNAS_Message);
+    ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList;
 
     dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
 
@@ -1329,3 +1258,202 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8
 
     return encoded;
 }
+
+uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti) {
+  asn_enc_rval_t enc_rval;
+  NR_UL_CCCH_Message_t ul_ccch_msg;
+  NR_RRCReestablishmentRequest_t *rrcReestablishmentRequest;
+  uint8_t buf[2];
+
+  memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t));
+  ul_ccch_msg.message.present            = NR_UL_CCCH_MessageType_PR_c1;
+  ul_ccch_msg.message.choice.c1          = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1));
+  ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest;
+  ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest = CALLOC(1, sizeof(NR_RRCReestablishmentRequest_t));
+
+  rrcReestablishmentRequest = ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest;
+  // test
+  rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = NR_ReestablishmentCause_reconfigurationFailure;
+  rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.c_RNTI = c_rnti;
+  rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = 0;
+  rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = buf;
+  rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[0] = 0x08;
+  rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[1] = 0x32;
+  rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.size = 2;
+
+
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg);
+  }
+
+  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message,
+                                   NULL,
+                                   (void *)&ul_ccch_msg,
+                                   buffer,
+                                   100);
+  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
+  LOG_D(NR_RRC,"[UE] RRCReestablishmentRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
+  return((enc_rval.encoded+7)/8);
+}
+
+//------------------------------------------------------------------------------
+uint8_t
+do_RRCReestablishment(
+const protocol_ctxt_t     *const ctxt_pP,
+rrc_gNB_ue_context_t      *const ue_context_pP,
+int                              CC_id,
+uint8_t                   *const buffer,
+//const uint8_t                    transmission_mode,
+const uint8_t                    Transaction_id,
+NR_SRB_ToAddModList_t               **SRB_configList
+) {
+    asn_enc_rval_t enc_rval;
+    //long *logicalchannelgroup = NULL;
+    struct NR_SRB_ToAddMod *SRB1_config = NULL;
+    struct NR_SRB_ToAddMod *SRB2_config = NULL;
+    //gNB_RRC_INST *nrrrc               = RC.nrrrc[ctxt_pP->module_id];
+    NR_DL_DCCH_Message_t dl_dcch_msg;
+    NR_RRCReestablishment_t *rrcReestablishment = NULL;
+    int i = 0;
+    ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
+    NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
+    SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
+
+    if (*SRB_configList2) {
+      free(*SRB_configList2);
+    }
+
+    *SRB_configList2 = CALLOC(1, sizeof(NR_SRB_ToAddModList_t));
+    memset((void *)&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
+    dl_dcch_msg.message.present           = NR_DL_DCCH_MessageType_PR_c1;
+    dl_dcch_msg.message.choice.c1 = calloc(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
+    dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment;
+    dl_dcch_msg.message.choice.c1->choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_t));
+    rrcReestablishment = dl_dcch_msg.message.choice.c1->choice.rrcReestablishment;
+
+    // get old configuration of SRB2
+    if (*SRB_configList != NULL) {
+      for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) {
+        LOG_D(NR_RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n",
+              i, (*SRB_configList)->list.array[i]->srb_Identity);
+    
+        if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ) {
+          SRB2_config = (*SRB_configList)->list.array[i];
+        } else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ) {
+          SRB1_config = (*SRB_configList)->list.array[i];
+        }
+      }
+    }
+
+    if (SRB1_config == NULL) {
+      // default SRB1 configuration
+      LOG_W(NR_RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n");
+      /// SRB1
+      SRB1_config = CALLOC(1, sizeof(*SRB1_config));
+      SRB1_config->srb_Identity = 1;
+    }
+
+    if (SRB2_config == NULL) {
+      LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
+    } else {
+      ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+    }
+
+    if (*SRB_configList) {
+      free(*SRB_configList);
+    }
+
+    *SRB_configList = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t));
+    ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config);
+
+    rrcReestablishment->rrc_TransactionIdentifier = Transaction_id;
+    rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment;
+    rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_IEs_t));
+
+    uint8_t KgNB_star[32] = { 0 };
+    /** TODO
+    uint16_t pci = nrrrc->carrier[CC_id].physCellId;
+    uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
+                         nrrrc->carrier[CC_id].dl_CarrierFreq);
+    bool     is_rel8_only = true;
+    
+    if (earfcn_dl > 65535) {
+      is_rel8_only = false;
+    }
+    LOG_D(NR_RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n",
+          pci,
+          RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
+          nrrrc->carrier[CC_id].dl_CarrierFreq,
+          earfcn_dl,
+          is_rel8_only == true ? "true": "false");
+    */
+    
+    if (ue_context_pP->ue_context.nh_ncc >= 0) {
+      //TODO derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KgNB_star);
+      rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = ue_context_pP->ue_context.nh_ncc;
+    } else { // first HO
+      //TODO derive_keNB_star (ue_context_pP->ue_context.kgnb, pci, earfcn_dl, is_rel8_only, KgNB_star);
+      // LG: really 1
+      rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = 0;
+    }
+    // copy KgNB_star to ue_context_pP->ue_context.kgnb
+    memcpy (ue_context_pP->ue_context.kgnb, KgNB_star, 32);
+    ue_context_pP->ue_context.kgnb_ncc = 0;
+    rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL;
+    rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL;
+
+    if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+      xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
+    }
+
+    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
+                                     NULL,
+                                     (void *)&dl_dcch_msg,
+                                     buffer,
+                                     100);
+
+    if(enc_rval.encoded == -1) {
+      LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+            enc_rval.failed_type->name, enc_rval.encoded);
+      return -1;
+    }
+    
+    LOG_D(NR_RRC,"RRCReestablishment Encoded %u bits (%u bytes)\n",
+          (uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8);
+    return((enc_rval.encoded+7)/8);
+
+}
+
+uint8_t 
+do_RRCReestablishmentComplete(uint8_t *buffer, int64_t rrc_TransactionIdentifier) {
+  asn_enc_rval_t enc_rval;
+  NR_UL_DCCH_Message_t ul_dcch_msg;
+  NR_RRCReestablishmentComplete_t *rrcReestablishmentComplete;
+
+  memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
+  ul_dcch_msg.message.present            = NR_UL_DCCH_MessageType_PR_c1;
+  ul_dcch_msg.message.choice.c1          = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
+  ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete;
+  ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_t));
+
+  rrcReestablishmentComplete = ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete;
+  rrcReestablishmentComplete->rrc_TransactionIdentifier = rrc_TransactionIdentifier;
+  rrcReestablishmentComplete->criticalExtensions.present = NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete;
+  rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_IEs_t));
+  rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->lateNonCriticalExtension = NULL;
+  rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->nonCriticalExtension = NULL;
+
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_dcch_msg);
+  }
+
+  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
+                                   NULL,
+                                   (void *)&ul_dcch_msg,
+                                   buffer,
+                                   100);
+  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
+  LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
+  return((enc_rval.encoded+7)/8);
+}
+
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 44947c04edcb0acbc35ea4f0a4e547bda033a8b0..bfc4942138ef96e11dbaa9a114b9fa4240369543 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -91,7 +91,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
                     int                          CC_id,
                     uint8_t                      *const buffer,
                     const uint8_t                transaction_id,
-                    NR_SRB_ToAddModList_t        *SRB_configList);
+                    NR_SRB_ToAddModList_t        **SRB_configList);
 uint8_t do_NR_SecurityModeCommand(
                     const protocol_ctxt_t *const ctxt_pP,
                     uint8_t *const buffer,
@@ -106,11 +106,18 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
 uint8_t do_NR_RRCRelease(uint8_t *buffer,
                          uint8_t Transaction_id);
 uint16_t do_RRCReconfiguration(
-                    const protocol_ctxt_t        *const ctxt_pP,
-                    rrc_gNB_ue_context_t         *const ue_context_pP,
-                    uint8_t                      *buffer,
-                    uint8_t                      Transaction_id,
-                    gNB_RRC_INST                 *gnb_rrc_inst);
+    const protocol_ctxt_t        *const ctxt_pP,
+    uint8_t                      *buffer,
+    uint8_t                       Transaction_id,
+    NR_SRB_ToAddModList_t        *SRB_configList,
+    NR_DRB_ToAddModList_t        *DRB_configList,
+    NR_DRB_ToReleaseList_t       *DRB_releaseList,
+    NR_SecurityConfig_t          *security_config,
+    NR_SDAP_Config_t             *sdap_config,
+    NR_MeasConfig_t              *meas_config,
+    struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
+                                 *dedicatedNAS_MessageList,
+    NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig);
                     
 uint8_t do_RRCSetupComplete(uint8_t Mod_id, 
                             uint8_t *buffer, 
@@ -138,4 +145,23 @@ do_NR_DLInformationTransfer(
 
 uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, 
                         uint32_t pdu_length,
-                        uint8_t *pdu_buffer);
\ No newline at end of file
+                        uint8_t *pdu_buffer);
+
+uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti);
+
+uint8_t
+do_RRCReestablishment(
+  const protocol_ctxt_t     *const ctxt_pP,
+  rrc_gNB_ue_context_t      *const ue_context_pP,
+  int                              CC_id,
+  uint8_t                   *const buffer,
+  //const uint8_t                    transmission_mode,
+  const uint8_t                    Transaction_id,
+  NR_SRB_ToAddModList_t               **SRB_configList
+);
+
+uint8_t 
+do_RRCReestablishmentComplete(
+    uint8_t *buffer, 
+    int64_t rrc_TransactionIdentifier);
+
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 9345093ba7f05921d95241808be3354d665d20d5..e051ae082bc297090e0eb6430c20e06975c565a7 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -261,7 +261,10 @@ typedef enum pdu_session_satus_e {
   PDU_SESSION_STATUS_NEW,
   PDU_SESSION_STATUS_DONE,
   PDU_SESSION_STATUS_ESTABLISHED,
+  PDU_SESSION_STATUS_REESTABLISHED, // after HO
+  PDU_SESSION_STATUS_TOMODIFY,      // ENDC NSA
   PDU_SESSION_STATUS_FAILED,
+  PDU_SESSION_STATUS_TORELEASE  // to release DRB between eNB and UE
 } pdu_session_status_t;
 
 typedef struct pdu_session_param_s {
@@ -323,7 +326,7 @@ typedef struct gNB_RRC_UE_s {
   NR_EstablishmentCause_t            establishment_cause;
 
   /* Information from UE RRC ConnectionReestablishmentRequest */
-  NR_ReestablishmentCause_t             reestablishment_cause;
+  NR_ReestablishmentCause_t          reestablishment_cause;
 
   /* UE id for initial connection to S1AP */
   uint16_t                           ue_initial_id;
@@ -342,6 +345,8 @@ typedef struct gNB_RRC_UE_s {
   uint8_t                            nb_of_e_rabs;
   /* Total number of pdu session already setup in the list */
   uint8_t                           setup_pdu_sessions;
+  /* Number of e_rab to be setup in the list */
+  uint8_t                            nb_of_e_rabs;
   /* Number of pdu session to be setup in the list */
   uint8_t                            nb_of_pdusessions;
   /* Number of e_rab to be modified in the list */
@@ -349,10 +354,14 @@ typedef struct gNB_RRC_UE_s {
   uint8_t                            nb_of_failed_e_rabs;
   e_rab_param_t                      modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
   /* list of e_rab to be setup by RRC layers */
+  /* list of pdu session to be setup by RRC layers */
+  e_rab_param_t                      e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
   pdu_session_param_t                pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
   //release e_rabs
   uint8_t                            nb_release_of_e_rabs;
   e_rab_failed_t                     e_rabs_release_failed[S1AP_MAX_E_RAB];
+  uint8_t                            nb_release_of_pdusessions;
+  pdusession_failed_t                pdusessions_release_failed[NGAP_MAX_PDUSESSION];
   // LG: For GTPV1 TUNNELS
   uint32_t                           gnb_gtp_teid[S1AP_MAX_E_RAB];
   transport_layer_addr_t             gnb_gtp_addrs[S1AP_MAX_E_RAB];
@@ -371,6 +380,9 @@ typedef struct gNB_RRC_UE_s {
   uint32_t                           ue_reestablishment_timer;
   uint32_t                           ue_reestablishment_timer_thres;
   uint8_t                            e_rab_release_command_flag;
+  uint8_t                            pdu_session_release_command_flag;
+  uint32_t                           ue_rrc_inactivity_timer;
+  int8_t                             reestablishment_xid;
   //------------------------------------------------------------------------------//
   NR_CellGroupId_t                                      cellGroupId;
   struct NR_SpCellConfig                                *spCellConfig;
@@ -429,6 +441,8 @@ typedef struct {
   NR_SRB_INFO                               SI;
   NR_SRB_INFO                               Srb0;
   int                                       initial_csi_index[MAX_NR_RRC_UE_CONTEXTS];
+  int                                       physCellId;
+  int                                       p_gNB;
 
 } rrc_gNB_carrier_data_t;
 //---------------------------------------------------
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index a38134970ef55db926c42f81d4766f50c341d73c..80812a7df467cd91b22c68fba383b6ebfb9e6e7d 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -145,3 +145,11 @@ nr_rrc_data_req(
 int
 nr_rrc_mac_remove_ue(module_id_t mod_idP,
                   rnti_t rntiP);
+
+void
+rrc_gNB_generate_dedicatedRRCReconfiguration_release(
+    const protocol_ctxt_t   *const ctxt_pP,
+    rrc_gNB_ue_context_t    *const ue_context_pP,
+    uint8_t                  xid,
+    uint32_t                 nas_length,
+    uint8_t                 *nas_buffer);
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 679c9d0b3c44d4fd2dc790d137aba04150822225..fb35ede347f113519d40e5e3b211750230c1b085 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -54,6 +54,7 @@
 #include "NR_UL-CCCH-Message.h"
 #include "NR_RRCSetupRequest-IEs.h"
 #include "NR_RRCSetupComplete-IEs.h"
+#include "NR_RRCReestablishmentRequest-IEs.h"
 
 #include "rlc.h"
 #include "rrc_eNB_UE_context.h"
@@ -119,6 +120,7 @@ extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * con
 static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn);
 
 mui_t                               rrc_gNB_mui = 0;
+uint8_t first_rrcreconfiguration = 0;
 
 ///---------------------------------------------------------------------------------------------------------------///
 ///---------------------------------------------------------------------------------------------------------------///
@@ -417,6 +419,82 @@ rrc_gNB_generate_RRCSetup(
 #endif
 }
 
+//-----------------------------------------------------------------------------
+void
+rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
+    const protocol_ctxt_t    *const ctxt_pP,
+    const int                CC_id
+)
+//-----------------------------------------------------------------------------
+{
+  LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n");
+  NR_SRB_ToAddModList_t        **SRB_configList = NULL;
+  rrc_gNB_ue_context_t         *ue_context_pP   = NULL;
+  gNB_RRC_INST                 *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id];
+
+  ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0);
+
+  gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
+  SRB_configList = &ue_p->SRB_configList;
+  ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP,
+              ue_context_pP,
+              CC_id,
+              (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+              rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+              SRB_configList);
+
+  LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
+              (char *)(ue_p->Srb0.Tx_buffer.Payload),
+              ue_p->Srb0.Tx_buffer.payload_size,
+              "[MSG] RRC Setup\n");
+
+  LOG_D(NR_RRC,
+          PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_gNB\n",
+          PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+
+  rrc_mac_config_req_gNB(rrc_instance_p->module_id,
+                         rrc_instance_p->carrier.ssb_SubcarrierOffset,
+                         rrc_instance_p->carrier.pdsch_AntennaPorts,
+                         rrc_instance_p->carrier.pusch_TargetSNRx10,
+                         rrc_instance_p->carrier.pucch_TargetSNRx10,
+                         (NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon,
+                         0,
+                         ue_context_pP->ue_context.rnti,
+                         (NR_CellGroupConfig_t *)NULL
+                        );
+
+    MSC_LOG_TX_MESSAGE(
+        MSC_RRC_GNB,
+        MSC_RRC_UE,
+        ue_p->Srb0.Tx_buffer.Header, // LG WARNING
+        ue_p->Srb0.Tx_buffer.payload_size,
+        MSC_AS_TIME_FMT" RRCSetup UE %x size %u",
+        MSC_AS_TIME_ARGS(ctxt_pP),
+        ue_context_pP->ue_context.rnti,
+        ue_p->Srb0.Tx_buffer.payload_size);
+    LOG_I(NR_RRC,
+        PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
+        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+        ue_p->Srb0.Tx_buffer.payload_size);
+    // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
+    ue_context_pP->ue_context.ue_release_timer = 1;
+    // remove UE after 10 frames after RRCConnectionRelease is triggered
+    ue_context_pP->ue_context.ue_release_timer_thres = 1000;
+    /* init timers */
+    //   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
+#ifdef ITTI_SIM
+    MessageDef *message_p;
+    uint8_t *message_buffer;
+    message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
+              ue_p->Srb0.Tx_buffer.payload_size);
+    memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
+    message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_CCCH_DATA_IND);
+    GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
+    GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
+    itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+#endif
+}
+
 void
 rrc_gNB_generate_RRCReject(
     const protocol_ctxt_t    *const ctxt_pP,
@@ -486,23 +564,120 @@ rrc_gNB_process_RRCSetupComplete(
 //-----------------------------------------------------------------------------
 void 
 rrc_gNB_generate_defaultRRCReconfiguration(
-    const protocol_ctxt_t     *const ctxt_pP,
-    rrc_gNB_ue_context_t      *ue_context_pP
+  const protocol_ctxt_t     *const ctxt_pP,
+  rrc_gNB_ue_context_t      *ue_context_pP
 )
 //-----------------------------------------------------------------------------
 {
-  // gNB_RRC_UE_t           *ue_p = &ue_context_pP->ue_context;
-  uint8_t                buffer[RRC_BUF_SIZE];
-  uint16_t               size;
-  gNB_RRC_INST           *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
-
-  size = do_RRCReconfiguration(ctxt_pP, ue_context_pP, buffer,
-                               rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-                               gnb_rrc_inst);
-  LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
+  uint8_t                       buffer[RRC_BUF_SIZE];
+  uint16_t                      size;
+  NR_SRB_ToAddModList_t        **SRB_configList2 = NULL;
+  NR_SRB_ToAddModList_t        *SRB_configList  = ue_context_pP->ue_context.SRB_configList;
+  NR_DRB_ToAddModList_t        **DRB_configList  = NULL;
+  NR_DRB_ToAddModList_t        **DRB_configList2 = NULL;
+  NR_SRB_ToAddMod_t            *SRB2_config     = NULL;
+  NR_DRB_ToAddMod_t            *DRB_config      = NULL;
+  NR_SDAP_Config_t             *sdap_config     = NULL;
+  struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
+                               *dedicatedNAS_MessageList = NULL;
+  NR_DedicatedNAS_Message_t    *dedicatedNAS_Message = NULL;
+
+  uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
+
+  /******************** Radio Bearer Config ********************/
+  /* Configure SRB2 */
+  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
+  if (*SRB_configList2) {
+    free(*SRB_configList2);
+  }
+  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
+  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
+  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
+  SRB2_config->srb_Identity = 2;
+  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
+
+  /* Configure DRB */
+  DRB_configList = &ue_context_pP->ue_context.DRB_configList;
+  if (*DRB_configList) {
+      free(*DRB_configList);
+  }
+  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
+  memset(*DRB_configList, 0, sizeof(**DRB_configList));
+
+  DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid];
+  if (*DRB_configList2) {
+      free(*DRB_configList2);
+  }
+  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
+  memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
+
+  DRB_config = CALLOC(1, sizeof(*DRB_config));
+  DRB_config->drb_Identity = 1;
+  DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
+  DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
+  // TODO sdap_Config
+  sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
+  memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
+  DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
+  // TODO pdcp_Config
+  DRB_config->reestablishPDCP = NULL;
+  DRB_config->recoverPDCP = NULL;
+  DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
+  DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
+  DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
+  *DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_ms30;
+  DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
+  *DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
+  DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
+  *DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
+  DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
+  DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
+
+  DRB_config->pdcp_Config->drb->integrityProtection = NULL;
+  DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
+  DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
+  DRB_config->pdcp_Config->moreThanOneRLC = NULL;
+
+  DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
+  *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
+  DRB_config->pdcp_Config->ext1 = NULL;
+
+  ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
+  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
+
+  dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
+
+  if (ue_context_pP->ue_context.nas_pdu_flag == 1) {
+    dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
+    memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
+    OCTET_STRING_fromBuf(dedicatedNAS_Message,
+                          (char *)ue_context_pP->ue_context.nas_pdu.buffer,
+                          ue_context_pP->ue_context.nas_pdu.length);
+    ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
+  }
+
+  /* If list is empty free the list and reset the address */
+  if (dedicatedNAS_MessageList->list.count == 0) {
+    free(dedicatedNAS_MessageList);
+    dedicatedNAS_MessageList = NULL;
+  }
+
+  memset(buffer, 0, RRC_BUF_SIZE);
+  size = do_RRCReconfiguration(ctxt_pP, buffer,
+                                xid,
+                                *SRB_configList2,
+                                *DRB_configList,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                dedicatedNAS_MessageList,
+                                NULL);
 
   free(ue_context_pP->ue_context.nas_pdu.buffer);
 
+  LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
   LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n",
           ctxt_pP->module_id,
           ctxt_pP->frame,
@@ -526,15 +701,15 @@ rrc_gNB_generate_defaultRRCReconfiguration(
           rrc_gNB_mui,
           size);
 #ifdef ITTI_SIM
-  MessageDef *message_p;
-  uint8_t *message_buffer;
-  message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size);
-  memcpy (message_buffer, buffer, size);
-  message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND);
-  GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
-  GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
-  GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
-  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+    MessageDef *message_p;
+    uint8_t *message_buffer;
+    message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
+    memcpy (message_buffer, buffer, size);
+    message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
+    GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+    GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+    GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
+    itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
   nr_rrc_data_req(ctxt_pP,
               DCCH,
@@ -548,6 +723,112 @@ rrc_gNB_generate_defaultRRCReconfiguration(
   // rrc_rlc_config_asn1_req
 }
 
+//-----------------------------------------------------------------------------
+void
+rrc_gNB_generate_dedicatedRRCReconfiguration_release(
+    const protocol_ctxt_t   *const ctxt_pP,
+    rrc_gNB_ue_context_t    *const ue_context_pP,
+    uint8_t                  xid,
+    uint32_t                 nas_length,
+    uint8_t                 *nas_buffer)
+//-----------------------------------------------------------------------------
+{
+  uint8_t                             buffer[RRC_BUF_SIZE];
+  int                                 i;
+  uint16_t                            size  = 0;
+  NR_DRB_ToReleaseList_t             **DRB_Release_configList2 = NULL;
+  NR_DRB_Identity_t                  *DRB_release;
+  struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
+                                     *dedicatedNAS_MessageList = NULL;
+  NR_DedicatedNAS_Message_t          *dedicatedNAS_Message     = NULL;
+
+  DRB_Release_configList2 = &ue_context_pP->ue_context.DRB_Release_configList2[xid];
+  if (*DRB_Release_configList2) {
+    free(*DRB_Release_configList2);
+  }
+
+  *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
+  for(i = 0; i < NB_RB_MAX; i++) {
+    if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) {
+      DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
+      *DRB_release = i+1;
+      ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
+    }
+  }
+
+  /* If list is empty free the list and reset the address */
+  if (nas_length > 0) {
+    dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
+    dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
+    memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
+    OCTET_STRING_fromBuf(dedicatedNAS_Message,
+                         (char *)nas_buffer,
+                         nas_length);
+    ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
+    LOG_I(NR_RRC,"add NAS info with size %d\n", nas_length);
+  } else {
+    LOG_W(NR_RRC,"dedlicated NAS list is empty\n");
+  }
+
+  memset(buffer, 0, RRC_BUF_SIZE);
+  size = do_RRCReconfiguration(ctxt_pP, buffer, xid,
+                               NULL,
+                               NULL,
+                               *DRB_Release_configList2,
+                               NULL,
+                               NULL,
+                               NULL,
+                               dedicatedNAS_MessageList,
+                               NULL);
+
+  ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
+  LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
+              "[MSG] RRC Reconfiguration\n");
+
+  /* Free all NAS PDUs */
+  if (nas_length > 0) {
+    /* Free the NAS PDU buffer and invalidate it */
+    free(nas_buffer);
+  }
+
+  LOG_I(NR_RRC,
+        "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n",
+        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
+  LOG_D(NR_RRC,
+        "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
+        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
+  MSC_LOG_TX_MESSAGE(
+    MSC_RRC_GNB,
+    MSC_RRC_UE,
+    buffer,
+    size,
+    MSC_AS_TIME_FMT" dedicated NR_RRCReconfiguration UE %x MUI %d size %u",
+    MSC_AS_TIME_ARGS(ctxt_pP),
+    ue_context_pP->ue_context.rnti,
+    rrc_gNB_mui,
+    size);
+#ifdef ITTI_SIM
+  MessageDef *message_p;
+  uint8_t *message_buffer;
+  message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size);
+  memcpy (message_buffer, buffer, size);
+  message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND);
+  GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+  GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+  GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
+  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+#else
+  nr_rrc_data_req(
+    ctxt_pP,
+    DCCH,
+    rrc_gNB_mui++,
+    SDU_CONFIRM_NO,
+    size,
+    buffer,
+    PDCP_TRANSMISSION_MODE_CONTROL);
+#endif
+}
+
 //-----------------------------------------------------------------------------
 /*
 * Process the RRC Reconfiguration Complete from the UE
@@ -567,7 +848,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
   NR_SRB_ToAddModList_t              *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid];
   NR_DRB_ToReleaseList_t             *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
   NR_DRB_Identity_t                  *drb_id_p      = NULL;
-  uint8_t                             nr_DRB2LCHAN[8];
+//  uint8_t                             nr_DRB2LCHAN[8];
 
   ue_context_pP->ue_context.ue_reestablishment_timer = 0;
 
@@ -707,6 +988,350 @@ rrc_gNB_process_RRCReconfigurationComplete(
     ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL;
   }
 }
+
+//-----------------------------------------------------------------------------
+void
+rrc_gNB_generate_RRCReestablishment(
+  const protocol_ctxt_t *const ctxt_pP,
+  rrc_gNB_ue_context_t  *const ue_context_pP,
+  const int             CC_id)
+//-----------------------------------------------------------------------------
+{
+    // int UE_id = -1;
+    //NR_LogicalChannelConfig_t  *SRB1_logicalChannelConfig = NULL;
+    NR_SRB_ToAddModList_t      **SRB_configList;
+    // NR_SRB_ToAddMod_t          *SRB1_config = NULL;
+    //rrc_gNB_carrier_data_t     *carrier = NULL;
+    gNB_RRC_UE_t               *ue_context = NULL;
+    module_id_t                 module_id = ctxt_pP->module_id;
+    // uint16_t                    rnti = ctxt_pP->rnti;
+    
+    SRB_configList = &(ue_context_pP->ue_context.SRB_configList);
+    //carrier = &(RC.nrrrc[ctxt_pP->module_id]->carrier);
+    ue_context = &(ue_context_pP->ue_context);
+    ue_context->Srb0.Tx_buffer.payload_size = do_RRCReestablishment(ctxt_pP,
+        ue_context_pP,
+        CC_id,
+        (uint8_t *) ue_context->Srb0.Tx_buffer.Payload,
+        //(uint8_t) carrier->p_gNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2
+        rrc_gNB_get_next_transaction_identifier(module_id),
+        SRB_configList
+        //&(ue_context->physicalConfigDedicated)
+        );
+
+    /* Configure SRB1 for UE */
+    if (*SRB_configList != NULL) {
+      for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
+        if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
+          // SRB1_config = (*SRB_configList)->list.array[cnt];
+        }
+
+        LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_gNB\n",
+              PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+
+        // rrc_mac_config_req_eNB
+      }
+    }  // if (*SRB_configList != NULL)
+    
+    MSC_LOG_TX_MESSAGE(MSC_RRC_GNB,
+                       MSC_RRC_UE,
+                       ue_context->Srb0.Tx_buffer.Header,
+                       ue_context->Srb0.Tx_buffer.payload_size,
+                       MSC_AS_TIME_FMT" NR_RRCReestablishment UE %x size %u",
+                       MSC_AS_TIME_ARGS(ctxt_pP),
+                       ue_context->rnti,
+                       ue_context->Srb0.Tx_buffer.payload_size);
+    LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n",
+          PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+          ue_context->Srb0.Tx_buffer.payload_size);
+#if(0)
+    UE_id = find_nr_UE_id(module_id, rnti);
+    if (UE_id != -1) {
+      /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
+      RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+      /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */
+      RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100;
+    } else {
+      LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Generating NR_RRCReestablishment without UE_id(MAC) rnti %x\n",
+            PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+            rnti);
+    }
+#endif
+#ifdef ITTI_SIM
+        MessageDef *message_p;
+        uint8_t *message_buffer;
+        message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, ue_context->Srb0.Tx_buffer.payload_size);
+        memcpy (message_buffer, (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, ue_context->Srb0.Tx_buffer.payload_size);
+        message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
+        GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+        GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+        GNB_RRC_DCCH_DATA_IND (message_p).size  = ue_context->Srb0.Tx_buffer.payload_size;
+        itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+#endif
+
+}
+
+//-----------------------------------------------------------------------------
+void
+rrc_gNB_process_RRCConnectionReestablishmentComplete(
+  const protocol_ctxt_t *const ctxt_pP,
+  const rnti_t reestablish_rnti,
+  rrc_gNB_ue_context_t         *ue_context_pP,
+  const uint8_t xid
+)
+//-----------------------------------------------------------------------------
+{
+  LOG_I(NR_RRC,
+        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing NR_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n",
+        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+
+  NR_DRB_ToAddModList_t                 *DRB_configList = ue_context_pP->ue_context.DRB_configList;
+  NR_SRB_ToAddModList_t                 *SRB_configList = ue_context_pP->ue_context.SRB_configList;
+  NR_SRB_ToAddModList_t                **SRB_configList2 = NULL;
+  NR_DRB_ToAddModList_t                **DRB_configList2 = NULL;
+  NR_SRB_ToAddMod_t                     *SRB2_config     = NULL;
+  NR_DRB_ToAddMod_t                     *DRB_config      = NULL;
+  //NR_SDAP_Config_t                      *sdap_config     = NULL;
+  int i = 0;
+  uint8_t                             buffer[RRC_BUF_SIZE];
+  uint16_t                            size;
+
+  uint8_t next_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
+  int ret = 0;
+  ue_context_pP->ue_context.Status = NR_RRC_CONNECTED;
+  ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
+  ue_context_pP->ue_context.reestablishment_xid = next_xid;
+  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
+
+  // get old configuration of SRB2
+  if (*SRB_configList2 != NULL) {
+    if((*SRB_configList2)->list.count!=0) {
+      LOG_D(NR_RRC, "SRB_configList2(%p) count is %d\n           SRB_configList2->list.array[0] addr is %p",
+            SRB_configList2, (*SRB_configList2)->list.count,  (*SRB_configList2)->list.array[0]);
+    }
+
+    for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
+      if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
+        LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid);
+        SRB2_config = (*SRB_configList2)->list.array[i];
+        break;
+      }
+    }
+  }
+
+  // SRB2_config = CALLOC(1, sizeof(*SRB2_config));
+  // SRB2_config->srb_Identity = 2;
+
+  SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]);
+  DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]);
+
+  if (*SRB_configList2) {
+    free(*SRB_configList2);
+    LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
+  }
+
+  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
+
+  if (SRB2_config != NULL) {
+    // Add SRB2 to SRB configuration list
+    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
+    ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+    LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n",
+          SRB2_config->srb_Identity);
+    LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n",
+          SRB2_config->srb_Identity, next_xid);
+  } else {
+    // SRB configuration list only contains SRB1.
+    LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
+  }
+
+  if (*DRB_configList2) {
+    free(*DRB_configList2);
+    LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
+  }
+
+  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
+
+  if (DRB_configList != NULL) {
+    LOG_D(NR_RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n");
+
+    for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
+      DRB_config = DRB_configList->list.array[i];
+      // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete
+      ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
+    }
+  }
+
+  ue_context_pP->ue_context.Srb1.Active = 1;
+  //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
+
+  if (AMF_MODE_ENABLED) {
+    hashtable_rc_t    h_rc;
+    int               j;
+    rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL;
+    uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
+    uint32_t gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
+    gNB_RRC_INST *rrc_instance_p = RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];
+
+    if (gNB_ue_ngap_id > 0) {
+      h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p);
+
+      if  (h_rc == HASH_TABLE_OK) {
+    	  rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti;
+      }
+    }
+
+    if (ue_initial_id != 0) {
+      h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p);
+
+      if  (h_rc == HASH_TABLE_OK) {
+    	  rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti;
+      }
+    }
+
+    gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req;
+    /* Save e RAB information for later */
+    memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
+
+    for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
+      if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) {
+        create_tunnel_req.pdusession_id[j]   = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
+        create_tunnel_req.upf_NGu_teid[j]  = ue_context_pP->ue_context.pdusession[i].param.gtp_teid;
+        memcpy(create_tunnel_req.upf_addr[j].buffer,
+               ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer,
+                sizeof(uint8_t)*20);
+        create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length;
+        j++;
+      }
+    }
+
+    create_tunnel_req.rnti       = ctxt_pP->rnti; // warning put zero above
+    create_tunnel_req.num_tunnels    = j;
+    ret = gtpv1u_update_ngu_tunnel(
+            ctxt_pP->instance,
+            &create_tunnel_req,
+            reestablish_rnti);
+
+    if ( ret != 0 ) {
+      LOG_E(NR_RRC,"gtpv1u_update_ngu_tunnel failed,start to release UE %x\n",reestablish_rnti);
+
+      // update s1u tunnel failed,reset rnti?
+      if (gNB_ue_ngap_id > 0) {
+        h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p);
+
+        if (h_rc == HASH_TABLE_OK ) {
+        	rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti;
+        }
+      }
+
+      if (ue_initial_id != 0) {
+        h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p);
+
+        if (h_rc == HASH_TABLE_OK ) {
+          rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti;
+        }
+      }
+
+      ue_context_pP->ue_context.ue_release_timer_s1 = 1;
+      ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100;
+      ue_context_pP->ue_context.ue_release_timer = 0;
+      ue_context_pP->ue_context.ue_reestablishment_timer = 0;
+      ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
+      ue_context_pP->ue_context.ul_failure_timer = 0;
+      return;
+    }
+  } /* AMF_MODE_ENABLED */
+
+  /* Update RNTI in ue_context */
+  ue_context_pP->ue_id_rnti                    = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else
+  ue_context_pP->ue_context.rnti               = ctxt_pP->rnti;
+
+  if (AMF_MODE_ENABLED) {
+    uint8_t send_security_mode_command = FALSE;
+    nr_rrc_pdcp_config_security(
+      ctxt_pP,
+      ue_context_pP,
+      send_security_mode_command);
+    LOG_D(NR_RRC, "set security successfully \n");
+  }
+
+  /* Add all NAS PDUs to the list */
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
+
+    /* TODO parameters yet to process ... */
+    /* TODO should test if pdu session are Ok before! */
+    ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
+    ue_context_pP->ue_context.pdusession[i].xid    = xid;
+    LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
+          i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE");
+  }
+
+  memset(buffer, 0, RRC_BUF_SIZE);
+
+  size = do_RRCReconfiguration(ctxt_pP, buffer,
+                                xid,
+                               *SRB_configList2,
+                                DRB_configList,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL, // MeasObj_list,
+                                NULL,
+                                NULL);
+  LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
+              "[MSG] RRC Reconfiguration\n");
+
+  /* Free all NAS PDUs */
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
+    if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
+      /* Free the NAS PDU buffer and invalidate it */
+      free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
+    }
+  }
+
+  if(size==65535) {
+    LOG_E(NR_RRC,"RRC decode err!!! do_RRCReconfiguration\n");
+    return;
+  } else {
+    LOG_I(NR_RRC,
+          "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
+          ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
+    LOG_D(NR_RRC,
+          "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
+          ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
+    MSC_LOG_TX_MESSAGE(
+      MSC_RRC_GNB,
+      MSC_RRC_UE,
+      buffer,
+      size,
+      MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
+      MSC_AS_TIME_ARGS(ctxt_pP),
+      ue_context_pP->ue_context.rnti,
+      rrc_gNB_mui,
+      size);
+#ifdef ITTI_SIM
+    MessageDef *message_p;
+    uint8_t *message_buffer;
+    message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
+    memcpy (message_buffer, buffer, size);
+    message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
+    GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+    GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+    GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
+    itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+#else
+    nr_rrc_data_req(
+      ctxt_pP,
+      DCCH,
+      rrc_gNB_mui++,
+      SDU_CONFIRM_NO,
+      size,
+      buffer,
+      PDCP_TRANSMISSION_MODE_CONTROL);
+#endif
+  }
+}
 //-----------------------------------------------------------------------------
 
 /*------------------------------------------------------------------------------*/
@@ -715,31 +1340,25 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                            int                buffer_length,
                            const int          CC_id)
 {
+  module_id_t                                       Idx;
   asn_dec_rval_t                                    dec_rval;
   NR_UL_CCCH_Message_t                             *ul_ccch_msg = NULL;
   struct rrc_gNB_ue_context_s                      *ue_context_p = NULL;
   gNB_RRC_INST                                     *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
   NR_RRCSetupRequest_IEs_t                         *rrcSetupRequest = NULL;
-  uint64_t                                         random_value = 0;
-
-  dec_rval = uper_decode( NULL,
-                          &asn_DEF_NR_UL_CCCH_Message,
-                          (void **)&ul_ccch_msg,
-                          (uint8_t *) buffer,
-                          100,
-                          0,
-                          0);
-
-  if (dec_rval.consumed == 0) {
-    /* TODO */
-    LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n",
-               PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
-    return -1;
-  }
+  NR_RRCReestablishmentRequest_IEs_t                rrcReestablishmentRequest;
+  uint64_t                                          random_value = 0;
+  int i;
+
+    dec_rval = uper_decode( NULL,
+                            &asn_DEF_NR_UL_CCCH_Message,
+                            (void **)&ul_ccch_msg,
+                            (uint8_t *) buffer,
+                            100,
+                            0,
+                            0);
 
-  if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) {
-    switch (ul_ccch_msg->message.choice.c1->present) {
-      case NR_UL_CCCH_MessageType__c1_PR_NOTHING:
+    if (dec_rval.consumed == 0) {
         /* TODO */
         LOG_I(NR_RRC,
             PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n",
@@ -833,7 +1452,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                   LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__);
               }
 
-              if (ue_context_p != NULL) {
+       if (ue_context_p != NULL) {
                   ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE;
                   ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1;
               }
@@ -864,6 +1483,217 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                                   CC_id);
         break;
 
+            case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest:
+              LOG_I(NR_RRC, "receive rrcReestablishmentRequest message \n");
+              LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)(buffer), buffer_length,
+                    "[MSG] RRC Reestablishment Request\n");
+              LOG_D(NR_RRC,
+                    PROTOCOL_NR_RRC_CTXT_UE_FMT"MAC_gNB--- MAC_DATA_IND (rrcReestablishmentRequest on SRB0) --> RRC_gNB\n",
+                    PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+
+              rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest;
+              LOG_I(NR_RRC,
+                PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest cause %s\n",
+                PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+                ((rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_otherFailure) ?   "Other Failure" :
+                (rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" :
+                "reconfigurationFailure"));
+              {
+                uint16_t                          c_rnti = 0;
+                if (rrcReestablishmentRequest.ue_Identity.physCellId != RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId) {
+                  /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was recieved in this cell */
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+                        rrcReestablishmentRequest.ue_Identity.physCellId,
+                        RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId);
+                  rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
+                  break;
+                }
+
+                LOG_D(NR_RRC, "physCellId is %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId);
+
+                for (i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) {
+                  LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n",
+                        i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]);
+                }
+
+                if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0 ||
+                    rrcReestablishmentRequest.ue_Identity.c_RNTI > 65535) {
+                  /* c_RNTI range error should not happen */
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+                  rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
+                  break;
+                }
+
+                c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI;
+                LOG_I(NR_RRC, "c_rnti is %x\n", c_rnti);
+                ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, c_rnti);
+
+                if (ue_context_p == NULL) {
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+                  rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
+                  break;
+                }
+#if(0)
+                int UE_id = find_nr_UE_id(ctxt_pP->module_id, c_rnti);
+
+                if(UE_id == -1) {
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE_id(MAC) rnti %x, fallback to RRC establishment\n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
+                  rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
+                  break;
+                }
+
+                //previous rnti
+                rnti_t previous_rnti = 0;
+
+                for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+                  if (reestablish_rnti_map[i][1] == c_rnti) {
+                    previous_rnti = reestablish_rnti_map[i][0];
+                    break;
+                  }
+                }
+
+                if(previous_rnti != 0) {
+                  UE_id = find_nr_UE_id(ctxt_pP->module_id, previous_rnti);
+
+                  if(UE_id == -1) {
+                    LOG_E(NR_RRC,
+                          PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCReestablishmentRequest without UE_id(MAC) previous rnti %x, fallback to RRC establishment\n",
+                          PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti);
+                    rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
+                    break;
+                  }
+                }
+#endif
+                //c-plane not end
+                if((ue_context_p->ue_context.Status != NR_RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == NR_ReestablishmentCause_spare1)) {
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed \n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
+                  /* TODO RRC Release ? */
+                  break;
+                }
+
+                if(ue_context_p->ue_context.ue_reestablishment_timer > 0) {
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+                        ue_context_p->ue_context.Status
+                        );
+                  ue_context_p->ue_context.Status = NR_RRC_RECONFIGURED;
+                  protocol_ctxt_t  ctxt_old_p;
+                  PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p,
+                                                ctxt_pP->instance,
+                                                GNB_FLAG_YES,
+                                                c_rnti,
+                                                ctxt_pP->frame,
+                                                ctxt_pP->subframe);
+                  rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p,
+                      ue_context_p,
+                      ue_context_p->ue_context.reestablishment_xid);
+
+                  for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) {
+                    if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
+                      ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
+                    } else {
+                      ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
+                    }
+                  }
+                }
+
+                LOG_D(NR_RRC,
+                      PROTOCOL_NR_RRC_CTXT_UE_FMT" UE context: %p\n",
+                      PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+                      ue_context_p);
+                /* reset timers */
+                ue_context_p->ue_context.ul_failure_timer = 0;
+                ue_context_p->ue_context.ue_release_timer = 0;
+                ue_context_p->ue_context.ue_reestablishment_timer = 0;
+                // ue_context_p->ue_context.ue_release_timer_s1 = 0;
+                ue_context_p->ue_context.ue_release_timer_rrc = 0;
+                ue_context_p->ue_context.reestablishment_xid = -1;
+
+                // insert C-RNTI to map
+                for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+                  if (reestablish_rnti_map[i][0] == 0) {
+                    reestablish_rnti_map[i][0] = ctxt_pP->rnti;
+                    reestablish_rnti_map[i][1] = c_rnti;
+                    LOG_D(NR_RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
+                          i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
+                    break;
+                  }
+                }
+
+                ue_context_p->ue_context.reestablishment_cause = rrcReestablishmentRequest.reestablishmentCause;
+                LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Accept reestablishment request from UE physCellId %ld cause %ld\n",
+                      PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+                      rrcReestablishmentRequest.ue_Identity.physCellId,
+                      ue_context_p->ue_context.reestablishment_cause);
+
+                ue_context_p->ue_context.primaryCC_id = CC_id;
+                //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH;
+                Idx = DCCH;
+                // SRB1
+                ue_context_p->ue_context.Srb1.Active = 1;
+                ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
+                memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0],
+                      &DCCH_LCHAN_DESC,
+                      LCHAN_DESC_SIZE);
+                memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1],
+                      &DCCH_LCHAN_DESC,
+                      LCHAN_DESC_SIZE);
+                // SRB2: set  it to go through SRB1 with id 1 (DCCH)
+                ue_context_p->ue_context.Srb2.Active = 1;
+                ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
+                memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0],
+                      &DCCH_LCHAN_DESC,
+                      LCHAN_DESC_SIZE);
+                memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1],
+                      &DCCH_LCHAN_DESC,
+                      LCHAN_DESC_SIZE);
+
+                rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, CC_id);
+
+                LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n",
+                      PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+                      Idx);
+                MSC_LOG_TX_MESSAGE(MSC_RRC_GNB,
+                                  MSC_PDCP_GNB,
+                                  NULL,
+                                  0,
+                                  MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB",
+                                  MSC_AS_TIME_ARGS(ctxt_pP),
+                                  ue_context_p->ue_context.rnti);
+                // nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+                //                         ue_context_p->ue_context.SRB_configList,
+                //                         NULL,
+                //                         NULL,
+                //                         0xff,
+                //                         NULL,
+                //                         NULL,
+                //                         NULL,
+                //                         NULL,
+                //                         NULL,
+                //                         NULL);
+
+                // if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
+                  // nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                  //                         ue_context_p->ue_context.SRB_configList,
+                  //                         NULL,
+                  //                         NULL,
+                  //                         NULL,
+                  //                         NULL);
+                // }
+              }
+              break;
+
       case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest:
         LOG_I(NR_RRC, "receive rrcResumeRequest message \n");
         /* TODO */
@@ -924,7 +1754,8 @@ rrc_gNB_decode_dcch(
   asn_dec_rval_t                      dec_rval;
   NR_UL_DCCH_Message_t                *ul_dcch_msg  = NULL;
   struct rrc_gNB_ue_context_s         *ue_context_p = NULL;
-  // NR_RRCSetupComplete_t               *rrcSetupComplete = NULL;
+  MessageDef                         *msg_delete_tunnels_p = NULL;
+  uint8_t                             xid;
 
   int i;
 
@@ -1289,6 +2120,78 @@ rrc_gNB_decode_dcch(
       rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
       break;
 
+            case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
+              LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
+                          "[MSG] NR_RRC Connection Reestablishment Complete\n");
+              MSC_LOG_RX_MESSAGE(
+                MSC_RRC_GNB,
+                MSC_RRC_UE,
+                Rx_sdu,
+                sdu_sizeP,
+                MSC_AS_TIME_FMT" NR_RRCConnectionReestablishmentComplete UE %x size %u",
+                MSC_AS_TIME_ARGS(ctxt_pP),
+                ue_context_p->ue_context.rnti,
+                sdu_sizeP);
+              LOG_I(NR_RRC,
+                    PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
+                    "(rrcConnectionReestablishmentComplete) ---> RRC_gNB\n",
+                    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+                    DCCH,
+                    sdu_sizeP);
+              {
+                rnti_t reestablish_rnti = 0;
+
+                // select C-RNTI from map
+                for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+                  if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) {
+                    reestablish_rnti = reestablish_rnti_map[i][1];
+                    ue_context_p = rrc_gNB_get_ue_context(
+                                     RC.nrrrc[ctxt_pP->module_id],
+                                     reestablish_rnti);
+                    // clear currentC-RNTI from map
+                    reestablish_rnti_map[i][0] = 0;
+                    reestablish_rnti_map[i][1] = 0;
+                    LOG_D(NR_RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
+                          i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
+                    break;
+                  }
+                }
+
+                if (!ue_context_p) {
+                  LOG_E(NR_RRC,
+                        PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCConnectionReestablishmentComplete without UE context, falt\n",
+                        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+                  break;
+                }
+
+#if(0)
+                //clear
+                int UE_id = find_nr_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
+
+                if(UE_id == -1) {
+                  LOG_E(NR_RRC,
+                        PROTOCOL_RRC_CTXT_UE_FMT" NR_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n",
+                        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+                  break;
+                }
+
+                RC.nrmac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
+#endif
+                ue_context_p->ue_context.reestablishment_xid = -1;
+
+                if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present ==
+                    NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) {
+                  rrc_gNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p,
+                      ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->rrc_TransactionIdentifier);
+
+                }
+
+                //ue_context_p->ue_context.ue_release_timer = 0;
+                ue_context_p->ue_context.ue_reestablishment_timer = 1;
+                // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered
+                ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000;
+              }
+              break;
       default:
         break;
     }
@@ -1357,12 +2260,12 @@ void *rrc_gnb_task(void *args_p) {
 
       /* Messages from MAC */
       case NR_RRC_MAC_CCCH_DATA_IND:
-      // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
-      //                               NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index,
-      //                               GNB_FLAG_YES,
-      //                               NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
-      //                               msg_p->ittiMsgHeader.lte_time.frame,
-      //                               msg_p->ittiMsgHeader.lte_time.slot);
+      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
+                                    NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index,
+                                    GNB_FLAG_YES,
+                                    NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
+                                    msg_p->ittiMsgHeader.lte_time.frame,
+                                    msg_p->ittiMsgHeader.lte_time.slot);
         LOG_I(NR_RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
                 instance,
                 NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id,
@@ -1383,12 +2286,12 @@ void *rrc_gnb_task(void *args_p) {
 
       /* Messages from PDCP */
       case NR_RRC_DCCH_DATA_IND:
-        // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
-        //                               instance,
-        //                               ENB_FLAG_YES,
-        //                               RRC_DCCH_DATA_IND(msg_p).rnti,
-        //                               msg_p->ittiMsgHeader.lte_time.frame,
-        //                               msg_p->ittiMsgHeader.lte_time.slot);
+        PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
+                                      instance,
+                                      GNB_FLAG_YES,
+                                      NR_RRC_DCCH_DATA_IND(msg_p).rnti,
+                                      msg_p->ittiMsgHeader.lte_time.frame,
+                                      msg_p->ittiMsgHeader.lte_time.slot);
         LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n",
                 PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),
                 NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
@@ -1407,6 +2310,13 @@ void *rrc_gnb_task(void *args_p) {
         rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(msg_p, msg_name_p, instance);
         break;
 
+      case NGAP_PDUSESSION_RELEASE_COMMAND:
+        rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(msg_p, msg_name_p, instance);
+        break;
+
+      case GTPV1U_GNB_DELETE_TUNNEL_RESP:
+        break;
+
       /*
       #if defined(ENABLE_USE_MME)
 
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 97f23cffe362e255385f2da9ad3398c7ddcf9a51..1136fcb19a4aa7adb03c851dfcc2f223a9f36d1b 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -1230,3 +1230,165 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
     LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
 }
 
+//------------------------------------------------------------------------------
+void
+rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
+  const protocol_ctxt_t    *const ctxt_pP,
+  rrc_gNB_ue_context_t     *const ue_context_pP,
+  uint8_t                   xid
+)
+//------------------------------------------------------------------------------
+{
+  int pdu_sessions_released = 0;
+  MessageDef   *msg_p;
+  msg_p = itti_alloc_new_message (TASK_RRC_GNB, NGAP_PDUSESSION_RELEASE_RESPONSE);
+  NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
+
+  for (int i = 0;  i < NB_RB_MAX; i++) {
+    if (xid == ue_context_pP->ue_context.pdusession[i].xid) {
+      NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id =
+          ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
+      pdu_sessions_released++;
+      //clear
+      memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t));
+    }
+  }
+
+  NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_released = pdu_sessions_released;
+  NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_failed = ue_context_pP->ue_context.nb_release_of_pdusessions;
+  memcpy(&(NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusessions_failed[0]), &ue_context_pP->ue_context.pdusessions_release_failed[0],
+      sizeof(pdusession_failed_t)*ue_context_pP->ue_context.nb_release_of_pdusessions);
+  ue_context_pP->ue_context.setup_pdu_sessions -= pdu_sessions_released;
+  LOG_I(NR_RRC,"NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %d release_pdu_sessions %d setup_pdu_sessions %d \n",
+        NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id,
+        pdu_sessions_released, ue_context_pP->ue_context.setup_pdu_sessions);
+  itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
+
+  //clear xid
+  for(int i = 0; i < NB_RB_MAX; i++) {
+    ue_context_pP->ue_context.pdusession[i].xid = -1;
+  }
+
+  //clear release pdusessions
+  ue_context_pP->ue_context.nb_release_of_pdusessions = 0;
+  memset(&ue_context_pP->ue_context.pdusessions_release_failed[0], 0, sizeof(pdusession_failed_t)*NGAP_MAX_PDUSESSION);
+}
+
+//------------------------------------------------------------------------------
+int
+rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
+  MessageDef *msg_p,
+  const char *msg_name,
+  instance_t instance
+)
+//------------------------------------------------------------------------------
+{
+  uint32_t                        gNB_ue_ngap_id;
+  rrc_gNB_ue_context_t           *ue_context_p = NULL;
+  protocol_ctxt_t                 ctxt;
+  pdusession_release_t            pdusession_release_params[NGAP_MAX_PDUSESSION];
+  uint8_t                         nb_pdusessions_torelease;
+  MessageDef                     *msg_delete_tunnels_p = NULL;
+  uint8_t xid;
+  int i, pdusession;
+  uint8_t b_existed,is_existed;
+  uint8_t pdusession_release_drb = 0;
+
+  memcpy(&pdusession_release_params[0], &(NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).pdusession_release_params[0]),
+    sizeof(pdusession_release_t)*NGAP_MAX_PDUSESSION);
+  gNB_ue_ngap_id = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
+  nb_pdusessions_torelease = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).nb_pdusessions_torelease;
+  if (nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) {
+    return -1;
+  }
+  ue_context_p   = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id);
+  LOG_I(NR_RRC, "[gNB %d] Received %s: gNB_ue_ngap_id %d \n", instance, msg_name, gNB_ue_ngap_id);
+
+  if (ue_context_p != NULL) {
+    PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
+    xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
+    LOG_I(NR_RRC,"PDU Session Release Command: AMF_UE_NGAP_ID %lu  GNB_UE_NGAP_ID %d release_pdusessions %d \n",
+          NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, gNB_ue_ngap_id, nb_pdusessions_torelease);
+
+    for (pdusession = 0; pdusession < nb_pdusessions_torelease; pdusession++) {
+      b_existed = 0;
+      is_existed = 0;
+
+      for (i = pdusession-1; i >= 0; i--) {
+        if (pdusession_release_params[pdusession].pdusession_id == pdusession_release_params[i].pdusession_id) {
+          is_existed = 1;
+          break;
+        }
+      }
+
+      if(is_existed == 1) {
+        // pdusession_id is existed
+        continue;
+      }
+
+      for (i = 0;  i < NR_NB_RB_MAX; i++) {
+        if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) {
+          b_existed = 1;
+          break;
+        }
+      }
+
+      if(b_existed == 0) {
+        // no pdusession_id
+        LOG_I(NR_RRC, "no pdusession_id \n");
+        ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id;
+        ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
+        ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30;
+        ue_context_p->ue_context.nb_release_of_pdusessions++;
+      } else {
+        if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
+          ue_context_p->ue_context.pdusession[i].xid = xid;
+          continue;
+        } else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
+          LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id);
+          ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE;
+          ue_context_p->ue_context.pdusession[i].xid = xid;
+          pdusession_release_drb++;
+        } else {
+          // pdusession_id status NG
+          ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id;
+          ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
+          ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 0;
+          ue_context_p->ue_context.nb_release_of_pdusessions++;
+        }
+      }
+    }
+
+    if(pdusession_release_drb > 0) {
+      //TODO RRCReconfiguration To UE
+      LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
+      rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.length, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.buffer);
+    } else {
+      //gtp tunnel delete
+      LOG_I(NR_RRC, "gtp tunnel delete \n");
+      msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_GNB_DELETE_TUNNEL_REQ);
+      memset(&GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
+      GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+
+      for(i = 0; i < NB_RB_MAX; i++) {
+        if(xid == ue_context_p->ue_context.pdusession[i].xid) {
+          GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i];
+          ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
+          memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
+          ue_context_p->ue_context.gnb_gtp_psi[i]  = 0;
+        }
+      }
+
+      itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
+      //NGAP_PDUSESSION_RELEASE_RESPONSE
+      rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
+      LOG_I(NR_RRC, "Send PDU Session Release Response \n");
+    }
+  } else {
+    LOG_E(NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu  GNB_UE_NGAP_ID %d  Error ue_context_p NULL \n",
+          NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id);
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h
index 85f4f183e641488e28a18d35dd9fd3ccc29e6b64..f13c468f94f7141b28866725f9b2ae9aa67b4c80 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.h
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.h
@@ -142,4 +142,25 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
   NR_UL_DCCH_Message_t     *const ul_dcch_msg
 );
 
+int
+rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
+  MessageDef *msg_p,
+  const char *msg_name,
+  instance_t instance
+);
+
+void
+rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
+  const protocol_ctxt_t    *const ctxt_pP,
+  rrc_gNB_ue_context_t     *const ue_context_pP,
+  uint8_t                   xid
+);
+
+void
+nr_rrc_pdcp_config_security(
+    const protocol_ctxt_t  *const ctxt_pP,
+    rrc_gNB_ue_context_t   *const ue_context_pP,
+    const uint8_t          send_security_mode_command
+);
+
 #endif
diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c
index 757c35d7bc255ba8106a0dc84655147a59f117e4..988db09cc1e2573cd14c3b8cec6a436ab837cf7d 100644
--- a/openair2/RRC/NR/rrc_gNB_UE_context.c
+++ b/openair2/RRC/NR/rrc_gNB_UE_context.c
@@ -134,6 +134,7 @@ rrc_gNB_allocate_new_UE_context(
   new_p->local_uid = nr_uid_linear_allocator_new(rrc_instance_pP);
 
   for(int i = 0; i < NB_RB_MAX; i++) {
+    new_p->ue_context.e_rab[i].xid = -1;
     new_p->ue_context.pdusession[i].xid = -1;
     new_p->ue_context.modify_e_rab[i].xid = -1;
   }
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 4085e41aac41c33fdf2b8f90742d1577cb1c328a..28646384cf17826329978a9e238903c2146351ef 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -183,15 +183,15 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
 
     if (m->nb_e_rabs_tobeadded>0) {
       for (int i=0; i<m->nb_e_rabs_tobeadded; i++) {
-        // Add the new E-RABs at the corresponding rrc ue context of the gNB
-        ue_context_p->ue_context.pdusession[i].param.pdusession_id = m->e_rabs_tobeadded[i].e_rab_id;
-        ue_context_p->ue_context.pdusession[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
-        memcpy(&ue_context_p->ue_context.pdusession[i].param.upf_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
-        ue_context_p->ue_context.nb_of_pdusessions++;
+        // Add the new E-RABs at the corresponding rrc ue context of the gNB 
+        ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
+        ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
+        memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
+        ue_context_p->ue_context.nb_of_e_rabs++;
         //Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW
-        create_tunnel_req.eps_bearer_id[i]       = ue_context_p->ue_context.pdusession[i].param.pdusession_id;
-        create_tunnel_req.sgw_S1u_teid[i]        = ue_context_p->ue_context.pdusession[i].param.gtp_teid;
-        memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.pdusession[i].param.upf_addr, sizeof(transport_layer_addr_t));
+        create_tunnel_req.eps_bearer_id[i]       = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
+        create_tunnel_req.sgw_S1u_teid[i]        = ue_context_p->ue_context.e_rab[i].param.gtp_teid;
+        memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
         inde_list[i] = i;
         LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
               i,
@@ -218,8 +218,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
       X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
       X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id;
 
-      for(int i=0; i<ue_context_p->ue_context.nb_of_pdusessions; i++) {
-        X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.pdusession[i].param.pdusession_id;
+      for(int i=0; i<ue_context_p->ue_context.nb_of_e_rabs; i++) {
+        X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
         X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i];
         memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t));
         //The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index c031d1c5afd5e3f528706e87605e87298de462fb..2f5919e3d15c4c7d2a4b3feb457b360b022222dc 100755
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -117,7 +117,17 @@ uint8_t do_NR_RRCReconfigurationComplete(
                         const uint8_t Transaction_id
                       );
 
+void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );
+
+void
+nr_rrc_ue_generate_rrcReestablishmentComplete(
+  const protocol_ctxt_t *const ctxt_pP,
+  NR_RRCReestablishment_t *rrcReestablishment,
+  uint8_t gNB_index
+);
+
 mui_t nr_rrc_mui=0;
+uint8_t first_rrcreconfigurationcomplete = 0;
 
 static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) {
   return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
@@ -1394,81 +1404,83 @@ static void rrc_ue_generate_RRCSetupComplete(
 }
 
 int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){
-  NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
-  asn_dec_rval_t dec_rval;
-  int rval=0;
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
-  //    LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size,
-  //    NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State);
-  dec_rval = uper_decode(NULL,
-                         &asn_DEF_NR_DL_CCCH_Message,
-                         (void **)&dl_ccch_msg,
-                         (uint8_t *)Srb_info->Rx_buffer.Payload,
-                         100,0,0);
-  
-  // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-    xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
-  // }
-  
-  if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
-    LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
-    return -1;
-  }
-  
-  if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
-    if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) {
-      switch (dl_ccch_msg->message.choice.c1->present) {
-        case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
-          LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
-                ctxt_pP->module_id,
-                ctxt_pP->frame);
-          rval = 0;
-          break;
-  
-        case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
-          LOG_I(NR_RRC,
-                "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
-                ctxt_pP->module_id,
-                ctxt_pP->frame);
-          rval = 0;
-          break;
-  
-        case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
-          LOG_I(NR_RRC,
-                "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
-                ctxt_pP->module_id,
-                ctxt_pP->frame,
-                ctxt_pP->rnti);
-          // Get configuration
-          // Release T300 timer
-          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
-          
-          nr_rrc_ue_process_masterCellGroup(
-            ctxt_pP,
-            gNB_index,
-            &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
-          nr_sa_rrc_ue_process_radioBearerConfig(
-            ctxt_pP,
-            gNB_index,
-            &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
-          nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
-          nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
-          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
-          rrc_ue_generate_RRCSetupComplete(
-            ctxt_pP,
-            gNB_index,
-            dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
-            NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
-          rval = 0;
-          break;
-  
-        default:
-          LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
-                ctxt_pP->module_id,
-                ctxt_pP->frame);
-          rval = -1;
-          break;
+    NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    int rval=0;
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
+    //    LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size,
+    //    NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State);
+    dec_rval = uper_decode(NULL,
+                           &asn_DEF_NR_DL_CCCH_Message,
+                           (void **)&dl_ccch_msg,
+                           (uint8_t *)Srb_info->Rx_buffer.Payload,
+                           100,0,0);
+    
+    // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+      xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
+    // }
+    
+    if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
+      LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
+      return -1;
+    }
+    
+    if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
+      if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) {
+        switch (dl_ccch_msg->message.choice.c1->present) {
+          case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
+            LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
+                  ctxt_pP->module_id,
+                  ctxt_pP->frame);
+            rval = 0;
+            break;
+    
+          case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
+            LOG_I(NR_RRC,
+                  "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
+                  ctxt_pP->module_id,
+                  ctxt_pP->frame);
+            rval = 0;
+            break;
+    
+          case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
+            LOG_I(NR_RRC,
+                  "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
+                  ctxt_pP->module_id,
+                  ctxt_pP->frame,
+                  ctxt_pP->rnti);
+
+            // Get configuration
+            // Release T300 timer
+            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
+            
+            nr_rrc_ue_process_masterCellGroup(
+              ctxt_pP,
+              gNB_index,
+              &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
+            nr_sa_rrc_ue_process_radioBearerConfig(
+              ctxt_pP,
+              gNB_index,
+              &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
+            nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
+            nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
+            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
+            rrc_ue_generate_RRCSetupComplete(
+              ctxt_pP,
+              gNB_index,
+              dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
+              NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
+            rval = 0;
+            break;
+    
+          default:
+            LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
+                  ctxt_pP->module_id,
+                  ctxt_pP->frame);
+            rval = -1;
+            break;
+        }
       }
     }
   }
@@ -2252,6 +2264,7 @@ void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const
   UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
   UE_RRC_DCCH_DATA_IND (message_p).size  = size;
   itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+
 #else
   rrc_data_req_ue (
     ctxt_pP,
@@ -2320,32 +2333,38 @@ nr_rrc_ue_decode_dcch(
                 nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
                                             gNB_indexP,
                                             dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
+
+                if (first_rrcreconfigurationcomplete == 0) {
+                    first_rrcreconfigurationcomplete = 1;
 #ifdef ITTI_SIM
-                as_nas_info_t initialNasMsg;
-                memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
-                generateRegistrationComplete(&initialNasMsg, NULL);
-                if(initialNasMsg.length > 0){
-                    MessageDef *message_p;
-                    message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
-                    NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
-                    NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)initialNasMsg.data;
-                    NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
-                    itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
-                    LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
-                }
-                as_nas_info_t pduEstablishMsg;
-                memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
-                generatePduSessionEstablishRequest(&pduEstablishMsg);
-                if(initialNasMsg.length > 0){
-                    MessageDef *message_p;
-                    message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
-                    NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
-                    NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)pduEstablishMsg.data;
-                    NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
-                    itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
-                    LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
-                }
+                  if (AMF_MODE_ENABLED) {
+                    as_nas_info_t initialNasMsg;
+                    memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
+                    generateRegistrationComplete(&initialNasMsg, NULL);
+                    if(initialNasMsg.length > 0){
+                        MessageDef *message_p;
+                        message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
+                        NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
+                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)initialNasMsg.data;
+                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
+                        itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
+                        LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
+                    }
+                    as_nas_info_t pduEstablishMsg;
+                    memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
+                    generatePduSessionEstablishRequest(&pduEstablishMsg);
+                    if(initialNasMsg.length > 0){
+                        MessageDef *message_p;
+                        message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
+                        NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
+                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)pduEstablishMsg.data;
+                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
+                        itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
+                        LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
+                    }
+                  }
 #endif
+                }
             }
                 break;
 
@@ -2375,6 +2394,14 @@ nr_rrc_ue_decode_dcch(
             	  gNB_indexP);
             	 break;
             case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
+                LOG_I(NR_RRC,
+                    "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
+                    ctxt_pP->module_id,
+                    ctxt_pP->frame);
+                nr_rrc_ue_generate_rrcReestablishmentComplete(
+                  ctxt_pP,
+                  dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
+                  gNB_indexP);
                 break;
             case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
             {
@@ -2515,8 +2542,8 @@ void *rrc_nrue_task( void *args_p ) {
         memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
                 NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
         srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
-        //      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
-        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
+        PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
+        // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
         nr_rrc_ue_decode_ccch (&ctxt,
                             srb_info_p,
                             NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
@@ -2728,3 +2755,59 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
     }
   }
 }
+
+//-----------------------------------------------------------------------------
+void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) 
+{
+  NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
+    do_RRCReestablishmentRequest(
+      ctxt_pP->module_id,
+      (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, 1);
+  LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCReestablishmentRequest (bytes %d, gNB %d)\n",
+        ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
+
+  for (int i=0; i<NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
+    LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
+  }
+
+  LOG_T(NR_RRC,"\n");
+
+#ifdef ITTI_SIM
+  MessageDef *message_p;
+  uint8_t *message_buffer;
+  message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
+        NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
+  memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
+        NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
+  message_p = itti_alloc_new_message (TASK_RRC_NRUE, UE_RRC_CCCH_DATA_IND);
+  UE_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
+  UE_RRC_CCCH_DATA_IND (message_p).size  = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size;
+  itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+#endif
+}
+
+void
+nr_rrc_ue_generate_rrcReestablishmentComplete(
+  const protocol_ctxt_t *const ctxt_pP,
+  NR_RRCReestablishment_t *rrcReestablishment,
+  uint8_t gNB_index
+)
+//-----------------------------------------------------------------------------
+{
+    uint32_t length;
+    uint8_t buffer[100];
+    length = do_RRCReestablishmentComplete(buffer, rrcReestablishment->rrc_TransactionIdentifier);
+#ifdef ITTI_SIM
+    MessageDef *message_p;
+    uint8_t *message_buffer;
+    message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length);
+    memcpy (message_buffer, buffer, length);
+
+    message_p = itti_alloc_new_message (TASK_RRC_NRUE, UE_RRC_DCCH_DATA_IND);
+    UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+    UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+    UE_RRC_DCCH_DATA_IND (message_p).size  = length;
+    itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+
+#endif
+}
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index d9a291f5a3de8e3a7827f60393fcd2d47e4b0de0..8be356a90b7fd12a5407c3c605cb919ea1d5ce44 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -126,7 +126,6 @@ typedef struct NR_UE_RRC_INST_s {
 
     /* KeNB as computed from parameters within USIM card */
     uint8_t kgnb[32];
-
     /* Used integrity/ciphering algorithms */
     //RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list;
     NR_CipheringAlgorithm_t  cipheringAlgorithm;
diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c
index 4fb784f84dbce5701f51746342a9a75bf5921f4b..de72b764f2a5f1e8e6942466f4fa7592ed56b0ab 100644
--- a/openair2/SIMULATION/NR_RRC/itti_sim.c
+++ b/openair2/SIMULATION/NR_RRC/itti_sim.c
@@ -104,7 +104,7 @@ int config_sync_var=-1;
 
 openair0_config_t openair0_cfg[MAX_CARDS];
 
-volatile int             start_gNB = 0;
+//volatile int             start_gNB = 0;
 volatile int             oai_exit = 0;
 
 //static int wait_for_sync = 0;
@@ -543,7 +543,7 @@ int main( int argc, char **argv )
   }
 
   AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
- // AMF_MODE_ENABLED = 0;
+//  AMF_MODE_ENABLED = 0;
   NGAP_CONF_MODE   = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
 
 #if T_TRACER
diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c
index 8d8a01243744826ce734759ae4bff2966f057fe1..4fde588e9f12ffa82aaf938cad7843f880c15d32 100644
--- a/openair3/GTPV1-U/gtpv1u_gNB.c
+++ b/openair3/GTPV1-U/gtpv1u_gNB.c
@@ -551,6 +551,173 @@ gtpv1u_create_ngu_tunnel(
   return ret;
 }
 
+int gtpv1u_update_ngu_tunnel(
+  const instance_t                              instanceP,
+  const gtpv1u_gnb_create_tunnel_req_t *const  create_tunnel_req_pP,
+  const rnti_t                                  prior_rnti
+) {
+  /* Local tunnel end-point identifier */
+  teid_t                      ngu_teid             = 0;
+  nr_gtpv1u_teid_data_t      *gtpv1u_teid_data_p   = NULL;
+  nr_gtpv1u_ue_data_t        *gtpv1u_ue_data_p     = NULL;
+  nr_gtpv1u_ue_data_t        *gtpv1u_ue_data_new_p     = NULL;
+  //MessageDef              *message_p            = NULL;
+  hashtable_rc_t           hash_rc              = HASH_TABLE_KEY_NOT_EXISTS;
+  int                      i,j;
+  uint8_t                  bearers_num = 0,bearers_total = 0;
+  //-----------------------
+  // PDCP->GTPV1U mapping
+  //-----------------------
+  hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti, (void **)&gtpv1u_ue_data_p);
+
+  if(hash_rc != HASH_TABLE_OK) {
+    LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
+    return -1;
+  }
+
+  gtpv1u_ue_data_new_p = calloc (1, sizeof(nr_gtpv1u_ue_data_t));
+  memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(nr_gtpv1u_ue_data_t));
+  gtpv1u_ue_data_new_p->ue_id       = create_tunnel_req_pP->rnti;
+  hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p);
+
+  //AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
+  if ( hash_rc != HASH_TABLE_OK ) {
+    LOG_E(GTPU,"Failed to insert ue_mapping(rnti=%x) in GTPV1U hashtable\n",create_tunnel_req_pP->rnti);
+    return -1;
+  } else {
+    LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
+          create_tunnel_req_pP->rnti);
+  }
+
+  hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti);
+  LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n",
+        prior_rnti);
+  //-----------------------
+  // GTPV1U->PDCP mapping
+  //-----------------------
+  bearers_total =gtpv1u_ue_data_new_p->num_bearers;
+
+  for(j = 0; j<GTPV1U_MAX_BEARERS_ID; j++) {
+    if(gtpv1u_ue_data_new_p->bearers[j].state != BEARER_IN_CONFIG)
+      continue;
+
+    bearers_num++;
+
+    for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
+      if(j == (create_tunnel_req_pP->pdusession_id[i]-GTPV1U_BEARER_OFFSET))
+        break;
+    }
+
+    if(i < create_tunnel_req_pP->num_tunnels) {
+      ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB;
+      hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, (void **)&gtpv1u_teid_data_p);
+
+      if (hash_rc == HASH_TABLE_OK) {
+        gtpv1u_teid_data_p->ue_id         = create_tunnel_req_pP->rnti;
+        gtpv1u_teid_data_p->pdu_session_id = create_tunnel_req_pP->pdusession_id[i];
+        LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n",
+                    ngu_teid,prior_rnti,create_tunnel_req_pP->rnti);
+      } else {
+        LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", ngu_teid);
+      }
+    } else {
+      ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB;
+      hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid);
+
+      if (hash_rc != HASH_TABLE_OK) {
+        LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, ngu_teid);
+      }
+
+      gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN;
+      gtpv1u_ue_data_new_p->num_bearers--;
+      LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n",
+            ngu_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);;
+    }
+
+    if(bearers_num > bearers_total)
+      break;
+  }
+
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+int gtpv1u_delete_ngu_tunnel(
+  const instance_t                             instanceP,
+  const gtpv1u_gnb_delete_tunnel_req_t *const req_pP) {
+  NwGtpv1uUlpApiT          stack_req;
+  NwGtpv1uRcT              rc                   = NW_GTPV1U_FAILURE;
+  MessageDef              *message_p = NULL;
+  nr_gtpv1u_ue_data_t     *gtpv1u_ue_data_p     = NULL;
+  hashtable_rc_t           hash_rc              = HASH_TABLE_KEY_NOT_EXISTS;
+  teid_t                   teid_gNB             = 0;
+  int                      pdusession_index     = 0;
+  message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_GNB_DELETE_TUNNEL_RESP);
+  GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti     = req_pP->rnti;
+  GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status       = 0;
+  hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)&gtpv1u_ue_data_p);
+
+  if (hash_rc == HASH_TABLE_OK) {
+    for (pdusession_index = 0; pdusession_index < req_pP->num_pdusession; pdusession_index++) {
+      teid_gNB = gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB;
+      LOG_D(GTPU, "Rx GTPV1U_ENB_DELETE_TUNNEL user rnti %x eNB S1U teid %u eps bearer id %u\n",
+            req_pP->rnti, teid_gNB, req_pP->pdusession_id[pdusession_index]);
+      {
+        memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
+        stack_req.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT;
+        LOG_D(GTPU, "gtpv1u_delete_ngu_tunnel pdusession %u  %u\n",
+              req_pP->pdusession_id[pdusession_index],
+              teid_gNB);
+        stack_req.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle =
+            gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session;
+        rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req);
+        LOG_D(GTPU, ".\n");
+      }
+
+      if (rc != NW_GTPV1U_OK) {
+        GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status       |= 0xFF;
+        LOG_E(GTPU, "NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT failed");
+      }
+
+      //-----------------------
+      // PDCP->GTPV1U mapping
+      //-----------------------
+      gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].state       = BEARER_DOWN;
+      gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB    = 0;
+      gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_upf    = 0;
+      gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].upf_ip_addr = 0;
+      gtpv1u_ue_data_p->num_bearers -= 1;
+
+      if (gtpv1u_ue_data_p->num_bearers == 0) {
+        hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti);
+        LOG_D(GTPU, "Removed user rnti %x,no more bearers configured\n", req_pP->rnti);
+      }
+
+      //-----------------------
+      // GTPV1U->PDCP mapping
+      //-----------------------
+      hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, teid_gNB);
+
+      if (hash_rc != HASH_TABLE_OK) {
+        LOG_D(GTPU, "Removed user rnti %x , gNB NGU teid %u not found\n", req_pP->rnti, teid_gNB);
+      }
+    }
+  }// else silently do nothing
+
+  LOG_D(GTPU, "Tx GTPV1U_GNB_DELETE_TUNNEL_RESP user rnti %x gNB NGU teid %u status %u\n",
+        GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
+        GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).gnb_NGu_teid,
+        GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status);
+  MSC_LOG_TX_MESSAGE(
+    MSC_GTPU_GNB,
+    MSC_RRC_GNB,
+    NULL,0,
+    "0 GTPV1U_GNB_DELETE_TUNNEL_RESP rnti %x teid %x",
+    GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
+    teid_gNB);
+  return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p);
+}
+
 //-----------------------------------------------------------------------------
 static int gtpv1u_gNB_send_init_udp(const Gtpv1uNGReq *req) {
   // Create and alloc new message
@@ -603,6 +770,10 @@ void *gtpv1u_gNB_process_itti_msg(void *notUsed) {
       gtpv1u_ng_req(instance, &received_message_p->ittiMsg.gtpv1uNGReq);
       break;
 
+    case GTPV1U_GNB_DELETE_TUNNEL_REQ:
+      gtpv1u_delete_ngu_tunnel(instance, &received_message_p->ittiMsg.NRGtpv1uDeleteTunnelReq);
+      break;
+
     case TERMINATE_MESSAGE: {
       if (RC.nr_gtpv1u_data_g->ue_mapping != NULL) {
         hashtable_destroy (&(RC.nr_gtpv1u_data_g->ue_mapping));
diff --git a/openair3/GTPV1-U/gtpv1u_gNB_task.h b/openair3/GTPV1-U/gtpv1u_gNB_task.h
index 5e16b0ed0cbc328e17846264e8d5c89f466b418a..fcfaa90304fae93b8094f15af132d81033d86c41 100644
--- a/openair3/GTPV1-U/gtpv1u_gNB_task.h
+++ b/openair3/GTPV1-U/gtpv1u_gNB_task.h
@@ -40,5 +40,12 @@ gtpv1u_create_ngu_tunnel(
   const gtpv1u_gnb_create_tunnel_req_t *  const create_tunnel_req_pP,
         gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP);
 
+int
+gtpv1u_update_ngu_tunnel(
+  const instance_t                              instanceP,
+  const gtpv1u_gnb_create_tunnel_req_t *const  create_tunnel_req_pP,
+  const rnti_t                                  prior_rnti
+);
+
 #endif /* GTPV1U_GNB_TASK_H_ */
 
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
index e0c207ce9350f527eb9be86a0392e3e5910004c6..2c07de8dd5abfea1d460c0f0b09d5d672a724f80 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
@@ -525,6 +525,8 @@ void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
 }
 
 void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer               *sortransparentcontainer) {
+  //wait send RRCReconfigurationComplete and InitialContextSetupResponse
+  sleep(1);
   int length = 0;
   int size = 0;
   fgs_nas_message_t nas_msg;
@@ -603,6 +605,8 @@ void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentCo
 }
 
 void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
+  //wait send RegistrationComplete
+  usleep(100*150);
   int size = 0;
   fgs_nas_message_t nas_msg;
   memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c
index 6051e917b45db58f5a7e715486f3beb72072b8d2..fe500d896b357819a3c256edfa20103988ea98bb 100644
--- a/openair3/NGAP/ngap_gNB_handlers.c
+++ b/openair3/NGAP/ngap_gNB_handlers.c
@@ -1754,7 +1754,7 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t               assoc_id,
 
   return 0;
 }
-// handle e-rab release command and send it to rrc_end
+// handle pdu session release command and send it to rrc_end
 static
 int ngap_gNB_handle_pdusession_release_command(uint32_t               assoc_id,
     uint32_t               stream,
@@ -1772,7 +1772,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t               assoc_id,
   container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
 
   if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
-    NGAP_ERROR("[SCTP %d] Received E-RAB release command for non existing AMF context\n", assoc_id);
+    NGAP_ERROR("[SCTP %d] Received pdu session release command for non existing AMF context\n", assoc_id);
     return -1;
   }
 
@@ -1805,11 +1805,11 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t               assoc_id,
   }
 
   /* Initial context request = UE-related procedure -> stream != 0 */
-  if (stream == 0) {
-    NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
-               assoc_id, stream);
-    return -1;
-  }
+  // if (stream == 0) {
+  //   NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
+  //              assoc_id, stream);
+  //   return -1;
+  // }
 
   ue_desc_p->rx_stream = stream;
 
@@ -1818,7 +1818,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t               assoc_id,
               (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
   }
 
-  NGAP_DEBUG("[SCTP %d] Received E-RAB release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
+  NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
              assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id);
   message_p = itti_alloc_new_message(TASK_NGAP, NGAP_PDUSESSION_RELEASE_COMMAND);
   NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
@@ -1850,7 +1850,18 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t               assoc_id,
       item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i];
     
       NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID;
-      NGAP_DEBUG("[SCTP] Received E-RAB release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
+      if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) {
+        NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size;
+        NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size);
+        memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer,
+               item_p->pDUSessionResourceReleaseCommandTransfer.buf,
+               item_p->pDUSessionResourceReleaseCommandTransfer.size);
+      }else {
+        NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = 0;
+        NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = NULL;
+        NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n");
+      }
+      NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
     }
   } else {
     return -1;
diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c
index 27afd1e397edb144c04c32eaf97edaf644732bf1..039b5fc7f8122e141dd7c9c6b2aedf8ffb467a0a 100644
--- a/openair3/NGAP/ngap_gNB_nas_procedures.c
+++ b/openair3/NGAP/ngap_gNB_nas_procedures.c
@@ -852,21 +852,22 @@ int ngap_gNB_initial_ctxt_resp(
     return -1;
   }
 
-  MSC_LOG_TX_MESSAGE(
-      MSC_NGAP_GNB,
-      MSC_NGAP_AMF,
-      (const char *)buffer,
-      length,
-      MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u",
-      0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
-      initial_ctxt_resp_p->gNB_ue_ngap_id,
-      ue_context_p->amf_ue_ngap_id);
-  /* UE associated signalling -> use the allocated stream */
-  ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
-                                   ue_context_p->amf_ref->assoc_id, buffer,
-                                   length, ue_context_p->tx_stream);
-
-  return 0;
+    MSC_LOG_TX_MESSAGE(
+        MSC_NGAP_GNB,
+        MSC_NGAP_AMF,
+        (const char *)buffer,
+        length,
+        MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u",
+        0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+        initial_ctxt_resp_p->gNB_ue_ngap_id,
+        ue_context_p->amf_ue_ngap_id);
+    /* UE associated signalling -> use the allocated stream */
+    LOG_I(NR_RRC,"Send message to sctp: NGAP_InitialContextSetupResponse\n");
+    ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
+                                     ue_context_p->amf_ref->assoc_id, buffer,
+                                     length, ue_context_p->tx_stream);
+
+    return 0;
 }
 
 //------------------------------------------------------------------------------
@@ -1421,7 +1422,52 @@ int ngap_gNB_pdusession_release_resp(instance_t instance,
     ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
     ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
     ie->criticality = NGAP_Criticality_ignore;
-    ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
+    ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID;
+    asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+    /* mandatory */
+    ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
+    ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
+    ie->criticality = NGAP_Criticality_ignore;
+    ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID;
+    ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+    /* optional */
+    if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) {
+        ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
+        ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
+        ie->criticality = NGAP_Criticality_ignore;
+        ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
+
+        for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) {
+            NGAP_PDUSessionResourceReleasedItemRelRes_t *item;
+            item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t));
+        
+            item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id;
+            if(pdusession_release_resp_p->pdusession_release[i].transfer_length > 0){
+                item->pDUSessionResourceReleaseResponseTransfer.size = pdusession_release_resp_p->pdusession_release[i].transfer_length;
+                item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * pdusession_release_resp_p->pdusession_release[i].transfer_length);
+                memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf,
+                       pdusession_release_resp_p->pdusession_release[i].transfer_buffer,
+                       pdusession_release_resp_p->pdusession_release[i].transfer_length);
+            }else {
+                item->pDUSessionResourceReleaseResponseTransfer.size = 0;
+                item->pDUSessionResourceReleaseResponseTransfer.buf = NULL;
+                NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n");
+#ifdef ITTI_SIM
+                //For testing only
+                item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * 1);
+                item->pDUSessionResourceReleaseResponseTransfer.size = 1;
+                uint8_t temp = 0;
+                memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf,
+                       &temp,
+                       item->pDUSessionResourceReleaseResponseTransfer.size);    
+#endif
+            }
+            NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID);
+            ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item);
+        }
 
     for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) {
         NGAP_PDUSessionResourceReleasedItemRelRes_t *item;