From 26bdf501092cebe4cee227b4f51c49672c4a2f8f Mon Sep 17 00:00:00 2001
From: Xenofon Foukas <x.foukas@sms.ed.ac.uk>
Date: Fri, 4 Mar 2016 15:46:31 +0000
Subject: [PATCH] Added bugfixes for remote scheduling

---
 openair1/SCHED/phy_procedures_lte_eNb.c       |   4 +-
 openair2/ENB_APP/enb_agent_common.c           | 126 +++++++++---------
 openair2/ENB_APP/enb_agent_mac.c              |   2 +
 .../MAC/eNB_agent_scheduler_dlsch_ue_remote.c |  38 ++++--
 4 files changed, 94 insertions(+), 76 deletions(-)

diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 60cd0ec0f7..211c64e373 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -153,8 +153,8 @@ void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
    * to be refined in case things don't work properly
    */
   if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
-    LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
-    abort();
+    //LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
+    //abort();
   }
   DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
 }
diff --git a/openair2/ENB_APP/enb_agent_common.c b/openair2/ENB_APP/enb_agent_common.c
index 64b51238f1..646470d13f 100644
--- a/openair2/ENB_APP/enb_agent_common.c
+++ b/openair2/ENB_APP/enb_agent_common.c
@@ -272,31 +272,33 @@ int enb_agent_destroy_echo_reply(Protocol__ProgranMessage *msg) {
 
 
 int enb_agent_destroy_enb_config_reply(Protocol__ProgranMessage *msg) {
-	if(msg->msg_case != PROTOCOL__PROGRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG)
-		goto error;
-	free(msg->enb_config_reply_msg->header);
-	int i, j;
-	Protocol__PrpEnbConfigReply *reply = msg->enb_config_reply_msg;
-
-	for(i = 0; i < reply->n_cell_config;i++){
-		free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
-		free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
-		free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
-		for(j = 0; j < reply->cell_config[i]->si_config->n_si_message;j++){
-			free(reply->cell_config[i]->si_config->si_message[j]);
-		}
-		free(reply->cell_config[i]->si_config->si_message);
-		free(reply->cell_config[i]->si_config);
-		free(reply->cell_config[i]);
-	}
-	free(reply->cell_config);
-	free(reply);
-	free(msg);
-
-	return 0;
-	error:
-	//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
-	return -1;
+  if(msg->msg_case != PROTOCOL__PROGRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG)
+    goto error;
+  free(msg->enb_config_reply_msg->header);
+  int i, j;
+  Protocol__PrpEnbConfigReply *reply = msg->enb_config_reply_msg;
+  
+  for(i = 0; i < reply->n_cell_config;i++){
+    free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
+    free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
+    free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
+    if (reply->cell_config[i]->si_config != NULL) {
+      for(j = 0; j < reply->cell_config[i]->si_config->n_si_message;j++){
+	free(reply->cell_config[i]->si_config->si_message[j]);
+      }
+      free(reply->cell_config[i]->si_config->si_message);
+      free(reply->cell_config[i]->si_config);
+    }
+    free(reply->cell_config[i]);
+  }
+  free(reply->cell_config);
+  free(reply);
+  free(msg);
+  
+  return 0;
+ error:
+  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
 }
 
 int enb_agent_destroy_ue_config_reply(Protocol__ProgranMessage *msg) {
@@ -507,7 +509,7 @@ uint16_t get_sfn_sf (mid_t mod_id) {
   frame = (frame_t) get_current_system_frame_num(mod_id);
   subframe = (sub_frame_t) get_current_subframe(mod_id);
   frame_mask = ((1<<12) - 1);
-  sf_mask = ((1<<4) -1);
+  sf_mask = ((1<<4) - 1);
   sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
   
   return sfn_sf;
@@ -1873,42 +1875,42 @@ int enb_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__Progr
       cell_conf[i]->init_nr_pdcch_ofdm_sym = get_num_pdcch_symb(enb_id,i);
       cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1;
       //TODO: Fill in with actual value
-      Protocol__PrpSiConfig *si_config;
-      si_config = malloc(sizeof(Protocol__PrpSiConfig));
-      if(si_config == NULL)
-	goto error;
-      protocol__prp_si_config__init(si_config);
-      //TODO: Fill in with actual value, Frame number to apply the SI configuration
-      si_config->sfn = 1;
-      si_config->has_sfn = 1;
-      //TODO: Fill in with actual value, the length of SIB1 in bytes
-      si_config->sib1_length = get_sib1_length(enb_id,i);
-      si_config->has_sib1_length = 1;
-      //TODO: Fill in with actual value, Scheduling window for all SIs in SF
-      si_config->si_window_length = (uint32_t) get_si_window_length(enb_id,i);
-      si_config->has_si_window_length = 1;
-      //TODO: Fill in with actual value, the number of SI messages
-      si_config->n_si_message=1;
-      Protocol__PrpSiMessage **si_message;
-      si_message = malloc(sizeof(Protocol__PrpSiMessage *) * si_config->n_si_message);
-      if(si_message == NULL)
-	goto error;
-      for(j = 0; j < si_config->n_si_message; j++){
-	si_message[j] = malloc(sizeof(Protocol__PrpSiMessage));
-	if(si_message[j] == NULL)
-	  goto error;
-	protocol__prp_si_message__init(si_message[j]);
-	//TODO: Fill in with actual value, Periodicity of SI msg in radio frames
-	si_message[j]->periodicity = 1;				//SIPeriod
-	si_message[j]->has_periodicity = 1;
-	//TODO: Fill in with actual value, rhe length of the SI message in bytes
-	si_message[j]->length = 10;
-	si_message[j]->has_length = 1;
-      }
-      if(si_config->n_si_message > 0){
-	si_config->si_message = si_message;
-      }
-      cell_conf[i]->si_config = si_config;
+      /* Protocol__PrpSiConfig *si_config; */
+      /* si_config = malloc(sizeof(Protocol__PrpSiConfig)); */
+      /* if(si_config == NULL) */
+      /* 	goto error; */
+      /* protocol__prp_si_config__init(si_config); */
+      /* //TODO: Fill in with actual value, Frame number to apply the SI configuration */
+      /* si_config->sfn = 1; */
+      /* si_config->has_sfn = 1; */
+      /* //TODO: Fill in with actual value, the length of SIB1 in bytes */
+      /* si_config->sib1_length = get_sib1_length(enb_id,i); */
+      /* si_config->has_sib1_length = 1; */
+      /* //TODO: Fill in with actual value, Scheduling window for all SIs in SF */
+      /* si_config->si_window_length = (uint32_t) get_si_window_length(enb_id,i); */
+      /* si_config->has_si_window_length = 1; */
+      /* //TODO: Fill in with actual value, the number of SI messages */
+      /* si_config->n_si_message=1; */
+      /* Protocol__PrpSiMessage **si_message; */
+      /* si_message = malloc(sizeof(Protocol__PrpSiMessage *) * si_config->n_si_message); */
+      /* if(si_message == NULL) */
+      /* 	goto error; */
+      /* for(j = 0; j < si_config->n_si_message; j++){ */
+      /* 	si_message[j] = malloc(sizeof(Protocol__PrpSiMessage)); */
+      /* 	if(si_message[j] == NULL) */
+      /* 	  goto error; */
+      /* 	protocol__prp_si_message__init(si_message[j]); */
+      /* 	//TODO: Fill in with actual value, Periodicity of SI msg in radio frames */
+      /* 	si_message[j]->periodicity = 1;				//SIPeriod */
+      /* 	si_message[j]->has_periodicity = 1; */
+      /* 	//TODO: Fill in with actual value, rhe length of the SI message in bytes */
+      /* 	si_message[j]->length = 10; */
+      /* 	si_message[j]->has_length = 1; */
+      /* } */
+      /* if(si_config->n_si_message > 0){ */
+      /* 	si_config->si_message = si_message; */
+      /* } */
+      /* cell_conf[i]->si_config = si_config; */
       
       //TODO: Fill in with actual value, the DL transmission bandwidth in RBs
       cell_conf[i]->dl_bandwidth = get_N_RB_DL(enb_id,i);
diff --git a/openair2/ENB_APP/enb_agent_mac.c b/openair2/ENB_APP/enb_agent_mac.c
index 630231560f..f00012f158 100644
--- a/openair2/ENB_APP/enb_agent_mac.c
+++ b/openair2/ENB_APP/enb_agent_mac.c
@@ -41,6 +41,7 @@
 
 #include "LAYER2/MAC/proto.h"
 #include "LAYER2/MAC/enb_agent_mac_proto.h"
+#include "LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.h"
 
 #include "liblfds700.h"
 
@@ -1369,6 +1370,7 @@ int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
   xface->enb_agent_send_sf_trigger = enb_agent_send_sf_trigger;
   xface->enb_agent_send_update_mac_stats = enb_agent_send_update_mac_stats;
   xface->enb_agent_schedule_ue_spec = schedule_ue_spec_default;
+  //xface->enb_agent_schedule_ue_spec = schedule_ue_spec_remote;
   xface->enb_agent_get_pending_dl_mac_config = enb_agent_get_pending_dl_mac_config;
   xface->enb_agent_notify_ue_state_change = enb_agent_ue_state_change;
 
diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c
index 4fffeea132..c4f40faff7 100644
--- a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c
+++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c
@@ -46,7 +46,7 @@ int queue_initialized = 0;
 void schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subframe,
 			     int *mbsfn_flag, Protocol__ProgranMessage **dl_info) {
 
-  if (queue_initialized) {
+  if (!queue_initialized) {
     TAILQ_INIT(&queue_head);
     queue_initialized = 1;
   }
@@ -54,22 +54,26 @@ void schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subframe,
   dl_mac_config_element_t *dl_config_elem;
 
   int diff;
-  
+  LOG_D(MAC, "Current frame and subframe %d, %d\n", frame, subframe);
   // First we check to see if we have a scheduling decision for this sfn_sf already in our queue
   while(queue_head.tqh_first != NULL) {
     dl_config_elem = queue_head.tqh_first;
+  
     diff = get_sf_difference(mod_id, dl_config_elem->dl_info->dl_mac_config_msg->sfn_sf);
     // Check if this decision is for now, for a later or a previous subframe
     if ( diff == 0) { // Now
+      LOG_D(MAC, "Found a decision for this subframe in the queue. Let's use it!\n");
       TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
       *dl_info = dl_config_elem->dl_info;
       free(dl_config_elem);
       return;
     } else if (diff < 0) { //previous subframe , delete message and free memory
+      LOG_D(MAC, "Found a decision for a previous subframe in the queue. Let's get rid of it\n");
       TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
       enb_agent_mac_destroy_dl_config(dl_config_elem->dl_info);
       free(dl_config_elem);
     } else { // next subframe, nothing to do now
+      LOG_D(MAC, "Found a decision for a future subframe in the queue. Nothing to do now\n");
       enb_agent_mac_create_empty_dl_config(mod_id, dl_info);
       return;
     }
@@ -81,17 +85,22 @@ void schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subframe,
 
     diff = get_sf_difference(mod_id, (*dl_info)->dl_mac_config_msg->sfn_sf);
     if (diff == 0) { // Got a command for this sfn_sf
+      LOG_D(MAC, "Found a decision for this subframe pending. Let's use it\n");
       return;
     } else if (diff < 0) {
+      LOG_D(MAC, "Found a decision for a previous subframe. Let's get rid of it\n");
       enb_agent_mac_destroy_dl_config(*dl_info);
+      *dl_info = NULL;
+      enb_agent_get_pending_dl_mac_config(mod_id, dl_info);
     } else { // Intended for future subframe. Store it in local cache
+      LOG_D(MAC, "Found a decision for a future subframe in the queue. Let's store it in the cache\n");
       dl_mac_config_element_t *e = malloc(sizeof(dl_mac_config_element_t));
+      e->dl_info = *dl_info;
       TAILQ_INSERT_TAIL(&queue_head, e, configs);
       enb_agent_mac_create_empty_dl_config(mod_id, dl_info);
       // No need to look for another. Messages arrive ordered
       return;
     }
-    enb_agent_get_pending_dl_mac_config(mod_id, dl_info);
   }
   
   // We found no pending command, so we will simply pass an empty one
@@ -114,25 +123,30 @@ int get_sf_difference(mid_t mod_id, uint16_t sfn_sf) {
   
   uint16_t sf_mask = ((1<<4) - 1);
   uint16_t subframe = (sfn_sf & sf_mask);
+
+ LOG_D(MAC, "Target frame and subframe %d, %d\n", frame, subframe);
   
   if (frame == current_frame) {
     return subframe - current_subframe;
   } else if (frame > current_frame) {
-    diff_in_subframes = 9 - current_subframe;
-    diff_in_subframes += (subframe + 1);
-    diff_in_subframes += (frame-2) * 10;
+    diff_in_subframes = ((frame*10)+subframe) - ((current_frame*10)+current_subframe);
+    
+    //    diff_in_subframes = 9 - current_subframe;
+    //diff_in_subframes += (subframe + 1);
+    //diff_in_subframes += (frame-2) * 10;
     if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
       return -1;
     } else {
       return 1;
     }
   } else { //frame < current_frame
-    diff_in_subframes = 9 - current_subframe;
-    diff_in_subframes += (subframe + 1);
-    if (frame > 0) {
-      diff_in_subframes += (frame - 1) * 10;
-    }
-    diff_in_subframes += (1023 - current_frame) * 10;
+    //diff_in_subframes = 9 - current_subframe;
+    //diff_in_subframes += (subframe + 1);
+    //if (frame > 0) {
+    //  diff_in_subframes += (frame - 1) * 10;
+    //}
+    //diff_in_subframes += (1023 - current_frame) * 10;
+    diff_in_subframes = 10240 - ((current_frame*10)+current_subframe) + ((frame*10)+subframe);
     if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
       return -1;
     } else {
-- 
2.26.2