From d42ddeac5602afb3a1d36363829611dba657afac Mon Sep 17 00:00:00 2001
From: Xu Bo <xubo1@cn.fujitsu.com>
Date: Thu, 1 Feb 2018 01:57:54 +0000
Subject: [PATCH] fix CRNTI process

---
 openair2/LAYER2/MAC/defs.h                    |  9 ++-
 openair2/LAYER2/MAC/eNB_scheduler_dlsch.c     | 10 ++++
 .../LAYER2/MAC/eNB_scheduler_primitives.c     | 16 +++++
 openair2/LAYER2/MAC/eNB_scheduler_ulsch.c     | 60 +++++++++++++------
 openair2/RRC/LITE/L2_interface.c              | 13 +++-
 openair2/RRC/LITE/rrc_eNB.c                   | 15 +++++
 6 files changed, 103 insertions(+), 20 deletions(-)

diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 2af8cb622d..f6c598976e 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -408,7 +408,9 @@ typedef enum {
     MSG2,
     WAITMSG3,
     MSG4,
-    WAITMSG4ACK
+    WAITMSG4ACK,
+    MSGCRNTI,
+    MSGCRNTI_ACK
 } RA_state;
 
 /*!\brief  UE ULSCH scheduling states*/
@@ -868,7 +870,8 @@ typedef struct {
     uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
     uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
     uint8_t dl_cqi[NFAPI_CC_MAX];
-    int32_t       uplane_inactivity_timer;
+    int32_t uplane_inactivity_timer;
+    uint8_t crnti_reconfigurationcomplete_flag;
 } UE_sched_ctrl;
 /*! \brief eNB template for the Random access information */
 typedef struct {
@@ -927,6 +930,8 @@ typedef struct {
     uint8_t msg2_narrowband;
     uint8_t msg34_narrowband;
 #endif
+    int32_t  crnti_rrc_mui;
+    int8_t   crnti_harq_pid;
 } RA_t;
 
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 58b6a13f6a..13c63124eb 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -1000,6 +1000,16 @@ schedule_ue_spec(module_id_t module_idP,
               }
             }
             pthread_mutex_unlock(&rrc_release_freelist);
+
+            RA_t *ra = &eNB->common_channels[CC_id].ra[0];
+            for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) {
+              if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI) &&
+                 (ra[ra_ii].crnti_rrc_mui == rlc_status.rrc_mui)){
+                ra[ra_ii].crnti_harq_pid = harq_pid;
+                ra[ra_ii].state = MSGCRNTI_ACK;
+                break;
+              }
+            }
 			T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
 			  T_INT(CC_id), T_INT(rnti), T_INT(frameP),
 			  T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH),
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 15bee20f11..fa462561af 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -3701,6 +3701,22 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0],
 		      harq_pid);
 
+        RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0];
+        for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) {
+          if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) &&
+              (ra[ra_i].crnti_harq_pid == harq_pid)) {
+            LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",pdu[0],rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP);
+            if(pdu[0] == 1){
+              cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti);
+            }else{
+              if(sched_ctl->round[CC_idP][harq_pid] == 7){
+                cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti);
+              }
+            }
+            break;
+          }
+        }
+
 		if (pdu[0] == 1) {	// ACK
 		    sched_ctl->round[CC_idP][harq_pid] = 8;	// release HARQ process
 		    sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 2a05d7ea95..281e9a298c 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -67,6 +67,7 @@ uint8_t rb_table[34] =
     { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32,
     36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100
 };
+extern mui_t    rrc_eNB_mui;
 
 void
 rx_sdu(const module_id_t enb_mod_idP,
@@ -273,8 +274,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 		      enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i,
 		      num_ce, old_rnti, old_UE_id);
 		/* receiving CRNTI means that the current rnti has to go away */
-		cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
-			       current_rnti);
+		//cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
+		//	       current_rnti);
 		if (old_UE_id != -1) {
 		    /* TODO: if the UE did random access (followed by a MAC uplink with
 		     * CRNTI) because none of its scheduling request was granted, then
@@ -287,20 +288,45 @@ rx_sdu(const module_id_t enb_mod_idP,
 		     * We have to take care of this. As the code is, nothing is done and
 		     * the UE state in the eNB is wrong.
 		     */
-		    UE_id = old_UE_id;
-		    UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
-                    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) {
-                      LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d clear to 0\n", UE_id, old_rnti,
-                      UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
-                    }
-		    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
-		    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
-			UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
-			mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
-					       subframeP, old_rnti);
-		    }
-		    current_rnti = old_rnti;
-		}
+          for (ii = 0; ii < NB_RA_PROC_MAX; ii++) {
+            ra = &mac->common_channels[CC_idP].ra[ii];
+            if ((ra->rnti == current_rnti) && (ra->state != IDLE)) {
+                mac_rrc_data_ind(enb_mod_idP,
+                                CC_idP,
+                                frameP, subframeP,
+                                old_rnti,
+                                DCCH,
+                                (uint8_t *) payload_ptr,
+                                rx_lengths[i],
+                                ENB_FLAG_YES, enb_mod_idP, 0);
+                // prepare transmission of Msg4(RRCConnectionReconfiguration)
+                ra->state = MSGCRNTI;
+                LOG_D(MAC,
+                     "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) RRCConnectionReconfiguration(Msg4)",
+                     enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id);
+                //
+                UE_id = old_UE_id;
+                current_rnti = old_rnti;
+                ra->rnti = old_rnti;
+                ra->crnti_rrc_mui = rrc_eNB_mui-1;
+                ra->crnti_harq_pid = -1;
+                //clear timer
+                UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+                UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
+                UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
+                if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
+                  UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
+                  mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
+                                         subframeP, old_rnti);
+                }
+                UE_list->UE_template[CC_idP][UE_id].ul_SR = 1;
+                UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1;
+                break;
+              }
+          }
+        }else{
+          cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti);
+        }
 		crnti_rx = 1;
 		payload_ptr += 2;
 		break;
@@ -630,7 +656,7 @@ rx_sdu(const module_id_t enb_mod_idP,
 		    // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
 		    ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0);
 		    ra->Msg4_subframe = (subframeP + 4) % 10;
-
+                    UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
 		}		// if process is active
 	    }			// loop on RA processes
 
diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c
index 620a8873d8..fb31620961 100644
--- a/openair2/RRC/LITE/L2_interface.c
+++ b/openair2/RRC/LITE/L2_interface.c
@@ -541,6 +541,7 @@ mac_rrc_data_ind(
 #endif // Rel10 || Rel14
 
   } else { // This is an eNB
+    if((srb_idP & RAB_OFFSET) == CCCH) {
     Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
     LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
     
@@ -575,7 +576,17 @@ mac_rrc_data_ind(
       Srb_info->Rx_buffer.payload_size = sdu_lenP;
       rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
     }
-
+    }
+    if((srb_idP & RAB_OFFSET) == DCCH) {
+      struct rrc_eNB_ue_context_s*    ue_context_p = NULL;
+      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP);
+      if(ue_context_p){
+        rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,
+            ue_context_p,
+            0);
+        ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+      }
+    }
 #endif
   }
 
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 9832ce39bd..e57ed85b6f 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -6179,6 +6179,21 @@ rrc_eNB_decode_dcch(
 	  LOG_I(RRC,
 		PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
 		PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+      //clear
+      int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
+      if(UE_id == -1){
+        LOG_E(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n",
+              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+        break;
+      }
+      if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1){
+        LOG_I(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n",
+              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+        dedicated_DRB = 2;
+        RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
+      }
 	}else {
 	  dedicated_DRB = 0;
 	  ue_context_p->ue_context.Status = RRC_RECONFIGURED;
-- 
GitLab