From b1acde2007a04995373e4bea44e6d8565cf49a9e Mon Sep 17 00:00:00 2001
From: shahab SHARIAT BAGHERI <shahab.shariat@eurecom.fr>
Date: Thu, 21 Dec 2017 13:55:37 +0100
Subject: [PATCH] Neighbouring cell RRC measurement + decrease warning

---
 .../CONTROL_MODULES/RRC/flexran_agent_rrc.c   | 110 ++++++++++---
 openair2/ENB_APP/flexran_agent_handler.c      |   2 +-
 openair2/ENB_APP/flexran_agent_ran_api.c      | 149 ++++++++++++++++--
 openair2/ENB_APP/flexran_agent_ran_api.h      |  22 ++-
 openair2/RRC/LITE/rrc_eNB.c                   |   4 +-
 5 files changed, 248 insertions(+), 39 deletions(-)

diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
index 7a251be78b..6f42d1da97 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
@@ -492,7 +492,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
 
 
   // Protocol__FlexHeader *header;
-  int i;
+  int i,j;
 
   /* Allocate memory for list of UE reports */
   if (report_config->nr_ue > 0) {
@@ -501,29 +501,86 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
       
       /* Check flag for creation of buffer status report */
       if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) {
-	
-	Protocol__FlexRrcMeasurements *rrc_measurements;
-	rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements));
-	if (rrc_measurements == NULL)
-	  goto error;
-	protocol__flex_rrc_measurements__init(rrc_measurements);
-	
-	rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i);
-	rrc_measurements->has_measid = 1;
-	
-	rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140;
-	rrc_measurements->has_pcell_rsrp = 1;
-	
-	rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20;
-	rrc_measurements->has_pcell_rsrq = 1 ;
-	
-	ue_report[i]->rrc_measurements = rrc_measurements;
-	
+      	
+        /*Source Cell*/
+        Protocol__FlexRrcMeasurements *rrc_measurements;
+      	rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements));
+      	if (rrc_measurements == NULL)
+      	  goto error;
+      	protocol__flex_rrc_measurements__init(rrc_measurements);
+      	
+      	rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i);
+      	rrc_measurements->has_measid = 1;
+      	
+      	rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i);
+      	rrc_measurements->has_pcell_rsrp = 1;
+      	
+      	rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i);
+      	rrc_measurements->has_pcell_rsrq = 1 ;
+
+        
+        /* Target Cell, Neghibouring*/
+        Protocol__FlexNeighCellsMeasurements *neigh_meas;
+        neigh_meas = malloc(sizeof(Protocol__FlexNeighCellsMeasurements));
+        if (neigh_meas == NULL)
+          goto error;
+        protocol__flex_neigh_cells_measurements__init(neigh_meas);
+         
+        
+        neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, i);
+
+        Protocol__FlexEutraMeasurements **eutra_meas = NULL;
+
+        if (neigh_meas->n_eutra_meas > 0){
+          
+          eutra_meas = malloc(sizeof(Protocol__FlexEutraMeasurements) * neigh_meas->n_eutra_meas);
+          if (eutra_meas == NULL)
+            goto error;
+          
+          for (j = 0; j < neigh_meas->n_eutra_meas; j++ ){
+
+              eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements));
+              if (eutra_meas[j] == NULL)
+                goto error;
+
+              protocol__flex_eutra_measurements__init(eutra_meas[j]);
+
+              eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, i, j);
+              eutra_meas[j]->has_phys_cell_id = 1;
+
+
+              /*TODO: Extend for CGI and PLMNID*/
+
+              Protocol__FlexEutraRefSignalMeas *meas_result;
+              meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas));
+
+              protocol__flex_eutra_ref_signal_meas__init(meas_result);     
+
+              meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, i, eutra_meas[j]->phys_cell_id);
+              meas_result->has_rsrp = 1;
+
+              meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, i, eutra_meas[j]->phys_cell_id);
+              meas_result->has_rsrq = 1;
+
+              eutra_meas[j]->meas_result = meas_result;
+             
+          }    
+
+           neigh_meas->eutra_meas = eutra_meas;   
+
+           rrc_measurements->neigh_meas = neigh_meas;
+       
+        }
+
+      	 ue_report[i]->rrc_measurements = rrc_measurements;
+      	
       }
-    }       
+
+    } 
+
   }
 
-  /* To be extended for RRC layer */ 
+  /* To be considered for RRC signaling of cell*/ 
   // if (report_config->nr_cc > 0) { 
     
             
@@ -564,6 +621,17 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
 
  error:
 
+  for (i = 0; i < report_config->nr_ue; i++){
+
+      if (ue_report[i]->rrc_measurements->neigh_meas != NULL){
+          for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, i); j++){
+
+             free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
+        }
+        free(ue_report[i]->rrc_measurements->neigh_meas);
+      }
+  }
+
   if (cell_report != NULL)
         free(cell_report);
   if (ue_report != NULL)
diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c
index 2a36b3e5c8..02df1d41dc 100644
--- a/openair2/ENB_APP/flexran_agent_handler.c
+++ b/openair2/ENB_APP/flexran_agent_handler.c
@@ -756,7 +756,7 @@ err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) {
   if (stats_context[mod_id].mutex == NULL)
     goto error;
   if (pthread_mutex_init(stats_context[mod_id].mutex, NULL))
-    goto error;;
+    goto error;
 
   return 0;
 
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index 556f018f7c..16462b4d40 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -1135,19 +1135,23 @@ uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){
 }
 
 /*PDCP super frame counter flexRAN*/
-uint32_t flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){
-  if (obs_window > 0 )
+void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){
+  if (obs_window > 0 ){
     Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window;
-  else
+  }
+  else{
     Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000;
+  }
 }
 
 /*PDCP super frame counter flexRAN*/
-uint32_t flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){
-  if (obs_window > 0 )
+void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){
+  if (obs_window > 0 ){
     Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window;
-  else
+  }
+  else{
     Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000;
+  }
 }
 
 /*PDCP num tx pdu status flexRAN*/
@@ -1256,7 +1260,7 @@ int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) {
   ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
   if(ue_context_p != NULL) {
     if(ue_context_p->ue_context.measResults != NULL) {
-      return ue_context_p->ue_context.measResults->measResultPCell.rsrpResult;
+      return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
     } else {
       return -1;
     }
@@ -1273,7 +1277,7 @@ int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) {
   ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
   if(ue_context_p != NULL) {
     if(ue_context_p->ue_context.measResults != NULL) {
-      return ue_context_p->ue_context.measResults->measResultPCell.rsrqResult;
+      return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
     } else {
       return -1;
     }
@@ -1281,8 +1285,48 @@ int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) {
     return -1;
   }
 }
-/*
-void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) {
+
+/*Number of neighbouring cells for specific UE*/
+int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) {
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
+
+  if (eNB_rrc_inst_not_ready()) return 0;
+  
+  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
+  if(ue_context_p != NULL) {
+
+    if (ue_context_p->ue_context.measResults != NULL){
+
+      if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) {
+
+       if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) {
+
+        return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count;
+       }
+       else{
+
+        return 0;
+       }
+
+      } else {
+
+        return 0;
+      }
+
+    } else {
+
+      return 0;
+
+    }
+      
+  } else {
+    return 0;
+  }
+    
+}
+
+int flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) {
   struct rrc_eNB_ue_context_s* ue_context_p = NULL;
   uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
 
@@ -1290,8 +1334,88 @@ void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) {
   
   ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
   if(ue_context_p != NULL) {
-    if(ue_context_p->ue_context.measResults != NULL) {
-      return &ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA;
+    if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) {
+
+      if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) {
+
+      return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; 
+
+      }
+      else {
+
+        return -1;
+      }      
+    } else {
+      return -1;
+    }
+  } else {
+    return -1;
+  }
+}
+
+int flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) {
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
+
+  if (eNB_rrc_inst_not_ready()) return -1;
+  
+  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
+  if(ue_context_p != NULL) {
+
+    if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) {
+
+      if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) {
+
+          if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult){
+              return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; 
+
+          }
+          else {
+
+              return 0;
+          }
+
+    }
+      else {
+
+          return -1;
+      }
+
+    } 
+    else {
+      return -1;
+    }
+  
+  }
+   else {
+    return -1;
+  }
+}
+
+int flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) {
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
+
+  if (eNB_rrc_inst_not_ready()) return -1;
+  
+  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
+  if(ue_context_p != NULL) {
+    if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) {
+      if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) {
+
+         if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult){
+           return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; 
+
+         } 
+         else {
+
+           return 0;
+         }
+      }
+      else {
+
+        return -1;
+      }
     } else {
       return -1;
     }
@@ -1299,4 +1423,3 @@ void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) {
     return -1;
   }
 }
-*/
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h
index 12ca5febea..05c6817136 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.h
+++ b/openair2/ENB_APP/flexran_agent_ran_api.h
@@ -346,10 +346,10 @@ int flexran_get_rrc_status(const mid_t mod_id,  const rnti_t  rntiP);
 uint32_t flexran_get_pdcp_sfn(const mid_t mod_id);
 
 /*PDCP pdcp tx stats window*/
-uint32_t flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window);
+void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window);
 
 /*PDCP pdcp rx stats window*/
-uint32_t flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window);
+void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window);
 
 /*PDCP num tx pdu status flexRAN*/
 uint32_t flexran_get_pdcp_tx(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid);
@@ -406,3 +406,21 @@ int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id);
 
 /*Get primary cell RSRQ measurement flexRAN*/
 int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id);
+
+/* Get RRC neighbouring measurement */
+int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id);
+
+/*Get physical cell id*/
+int flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id);
+
+/*Get RSRP of neighbouring Cell*/
+int flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id);
+
+/*Get RSRQ of neighbouring Cell*/
+int flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id);
+
+/*Get MCC PLMN identity neighbouring Cell*/
+int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id);
+
+/*Get MNC PLMN identity neighbouring Cell*/
+int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id);
\ No newline at end of file
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index c441c102e3..c3c1421533 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -2868,13 +2868,13 @@ rrc_eNB_process_MeasurementReport(
      return;
 
    if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) {
-     neighboring_cells=measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count;
+     neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count;
      
      if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) {
        
        ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells);
      }
-     ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count=neighboring_cells;
+     ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count = neighboring_cells;
      for (i=0; i < neighboring_cells; i++){
        memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i],
 	       measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i],
-- 
GitLab