diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index e4b027958de837ffbe23cf35b83d93063d8fe61b..18eaf0f8b6faeec205a17af6fa58533b9f983974 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1099,7 +1099,8 @@ set (MAC_SRC
${MAC_DIR}/config.c
${MAC_DIR}/eNB_agent_scheduler_dlsch_ue.c
${MAC_DIR}/eNB_agent_scheduler_dataplane.c
- )
+ ${MAC_DIR}/eNB_agent_scheduler_dlsch_ue_remote.c
+ )
set (ENB_APP_SRC
${OPENAIR2_DIR}/ENB_APP/enb_app.c
@@ -1113,7 +1114,7 @@ add_library(L2
${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c)
#Test for adding a shared library
-add_library(alt_sched SHARED ${MAC_DIR}/eNB_agent_scheduler_dlsch_ue_alt.c)
+#add_library(alt_sched SHARED ${MAC_DIR}/eNB_agent_scheduler_dlsch_ue_alt.c)
# L3 Libs
##########################
diff --git a/openair2/ENB_APP/enb_agent.c b/openair2/ENB_APP/enb_agent.c
index 95731d3654dc0f8568613b43302d1021620da078..a21e2f8e16045827802cbd4298c1274d2d3c7b00 100644
--- a/openair2/ENB_APP/enb_agent.c
+++ b/openair2/ENB_APP/enb_agent.c
@@ -276,6 +276,11 @@ int enb_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){
*/
enb_agent_init_timer();
+
+ /*
+ * Initialize the mac agent
+ */
+ enb_agent_init_mac_agent(mod_id);
/*
* start the enb agent task for tx and interaction with the underlying network function
diff --git a/openair2/ENB_APP/enb_agent_handler.c b/openair2/ENB_APP/enb_agent_handler.c
index d4e5706b1100d7a2cc34d51f2e89d4f26f41fd26..721b3678f802f2073851ad25fcd0b2ee4ec2fe82 100644
--- a/openair2/ENB_APP/enb_agent_handler.c
+++ b/openair2/ENB_APP/enb_agent_handler.c
@@ -55,7 +55,7 @@ enb_agent_message_decoded_callback agent_messages_callback[][3] = {
{0, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG*/
{enb_agent_lc_config_reply, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_LC_CONFIG_REQUEST_MSG*/
{0, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG*/
- {0, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_DL_MAC_CONFIG_MSG*/
+ {enb_agent_mac_handle_dl_mac_config, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_DL_MAC_CONFIG_MSG*/
{0, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG*/
{enb_agent_control_delegation, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_CONTROL_DELEGATION_MSG*/
@@ -116,10 +116,9 @@ Protocol__ProgranMessage* enb_agent_handle_message (mid_t mod_id,
err_code = ((*agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message));
if ( err_code < 0 ){
goto error;
+ } else if (err_code == 1) { //If err_code > 1, we do not want to dispose the message yet
+ protocol__progran_message__free_unpacked(decoded_message, NULL);
}
-
- protocol__progran_message__free_unpacked(decoded_message, NULL);
-
return reply_message;
error:
diff --git a/openair2/ENB_APP/enb_agent_mac.c b/openair2/ENB_APP/enb_agent_mac.c
index 7be6e6ba121c2ed15ba327dfea010d7ea89e6389..fa190bbf29be6c095c4faf4ce26d81b6d972e361 100644
--- a/openair2/ENB_APP/enb_agent_mac.c
+++ b/openair2/ENB_APP/enb_agent_mac.c
@@ -42,6 +42,8 @@
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/enb_agent_mac_proto.h"
+#include "liblfds700.h"
+
#include "log.h"
@@ -51,6 +53,13 @@ unsigned int mac_agent_registered[NUM_MAX_ENB];
/*Array containing the Agent-MAC interfaces*/
AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
+/* Ringbuffer related structs used for maintaining the dl mac config messages */
+//message_queue_t *dl_mac_config_queue;
+struct lfds700_misc_prng_state ps[NUM_MAX_ENB];
+struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB];
+struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB];
+
+
int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg){
// TODO: Must deal with sanitization of input
@@ -1154,6 +1163,56 @@ int enb_agent_mac_destroy_dl_config(Protocol__ProgranMessage *msg) {
return -1;
}
+void enb_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__ProgranMessage **msg) {
+
+ struct lfds700_misc_prng_state ls;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+ lfds700_misc_prng_init(&ls);
+
+ if (lfds700_ringbuffer_read(&ringbuffer_state[mod_id], NULL, (void **) msg, &ls) == 0) {
+ *msg = NULL;
+ }
+}
+
+int enb_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg) {
+
+ struct lfds700_misc_prng_state ls;
+ enum lfds700_misc_flag overwrite_occurred_flag;
+ Protocol__ProgranMessage *overwritten_dl_config;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+ lfds700_misc_prng_init(&ls);
+
+ lfds700_ringbuffer_write( &ringbuffer_state[mod_id],
+ NULL,
+ (void *) params,
+ &overwrite_occurred_flag,
+ NULL,
+ (void **)&overwritten_dl_config,
+ &ls);
+
+ if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
+ // Delete unmanaged dl_config
+ enb_agent_mac_destroy_dl_config(overwritten_dl_config);
+ }
+ *msg = NULL;
+ return 2;
+
+ error:
+ *msg = NULL;
+ return -1;
+}
+
+void enb_agent_init_mac_agent(mid_t mod_id) {
+ lfds700_misc_library_init_valid_on_current_logical_core();
+ lfds700_misc_prng_init(&ps[mod_id]);
+ int num_elements = RINGBUFFER_SIZE + 1;
+ //Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time
+ dl_mac_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) * num_elements);
+ lfds700_ringbuffer_init_valid_on_current_logical_core( &ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL );
+}
+
/***********************************************
* eNB agent - technology mac API implementation
***********************************************/
@@ -1284,6 +1343,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_get_pending_dl_mac_config = enb_agent_get_pending_dl_mac_config;
xface->enb_agent_notify_ue_state_change = enb_agent_ue_state_change;
mac_agent_registered[mod_id] = 1;
@@ -1299,6 +1359,8 @@ int enb_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
xface->enb_agent_send_sf_trigger = NULL;
xface->enb_agent_send_update_mac_stats = NULL;
xface->enb_agent_schedule_ue_spec = NULL;
+ xface->enb_agent_get_pending_dl_mac_config = NULL;
+ xface->enb_agent_notify_ue_state_change = NULL;
mac_agent_registered[mod_id] = 0;
agent_mac_xface[mod_id] = NULL;
diff --git a/openair2/ENB_APP/enb_agent_mac.h b/openair2/ENB_APP/enb_agent_mac.h
index 221d76e57fe22a43270bf6008e524000cfd1ed09..2a8f4c3a404936c486266950c2dc95d4c9379c7c 100644
--- a/openair2/ENB_APP/enb_agent_mac.h
+++ b/openair2/ENB_APP/enb_agent_mac.h
@@ -76,6 +76,9 @@ typedef struct stats_request_config_s{
report_config_t *config;
} stats_request_config_t;
+/* Initialization function for the agent structures etc */
+void enb_agent_init_mac_agent(mid_t mod_id);
+
int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg);
int enb_agent_mac_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__ProgranMessage **msg);
@@ -98,6 +101,8 @@ int enb_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__ProgranMessage
int enb_agent_mac_destroy_dl_config(Protocol__ProgranMessage *msg);
+int enb_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg);
+
/**********************************
* eNB agent - technology mac API
@@ -113,6 +118,9 @@ void enb_agent_send_sf_trigger(mid_t mod_id);
/// based on the stats request configuration
void enb_agent_send_update_mac_stats(mid_t mod_id);
+/// Provide to the scheduler a pending dl_mac_config message
+void enb_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__ProgranMessage **msg);
+
/*Register technology specific interface callbacks*/
int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface);
diff --git a/openair2/ENB_APP/enb_agent_mac_defs.h b/openair2/ENB_APP/enb_agent_mac_defs.h
index 657fc94fe4380eb2a53d21864a2afad3c6fe2059..c5a3204f0c43f2d6f0e69eb6552da8e230ef6948 100644
--- a/openair2/ENB_APP/enb_agent_mac_defs.h
+++ b/openair2/ENB_APP/enb_agent_mac_defs.h
@@ -42,6 +42,8 @@
#include "progran.pb-c.h"
#include "header.pb-c.h"
+#define RINGBUFFER_SIZE 100
+
/* ENB AGENT-MAC Interface */
typedef struct {
//msg_context_t *agent_ctxt;
@@ -56,11 +58,15 @@ typedef struct {
/// based on the stats request configuration
void (*enb_agent_send_update_mac_stats)(mid_t mod_id);
+ /// Provide to the scheduler a pending dl_mac_config message
+ void (*enb_agent_get_pending_dl_mac_config)(mid_t mod_id,
+ Protocol__ProgranMessage **msg);
+
/// Run the UE DL scheduler and fill the Protocol__ProgranMessage. Assumes that
/// dl_info is already initialized as prp_dl_mac_config and fills the
/// prp_dl_data part of it
void (*enb_agent_schedule_ue_spec)(mid_t mod_id, uint32_t frame, uint32_t subframe,
- int *mbsfn_flag, Protocol__ProgranMessage *dl_info);
+ int *mbsfn_flag, Protocol__ProgranMessage **dl_info);
/// Notify the controller for a state change of a particular UE, by sending the proper
diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dataplane.c b/openair2/LAYER2/MAC/eNB_agent_scheduler_dataplane.c
index 04efcb44ad80427ab4755672f99ef43e0d7b9b93..a1bd039dff15dd5fbb7bc7ac023ffc80d40f05ef 100644
--- a/openair2/LAYER2/MAC/eNB_agent_scheduler_dataplane.c
+++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dataplane.c
@@ -69,7 +69,7 @@ void apply_dl_scheduling_decisions(mid_t mod_id,
uint32_t frame,
uint32_t subframe,
int *mbsfn_flag,
- Protocol__ProgranMessage *dl_scheduling_info) {
+ const Protocol__ProgranMessage *dl_scheduling_info) {
Protocol__PrpDlMacConfig *mac_config = dl_scheduling_info->dl_mac_config_msg;
diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c
index 4d353232a851d3c84a4cdaf704dccb3417ce13e5..50318673940ecad64522f5ae9af74df91b36eb47 100644
--- a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c
+++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c
@@ -64,6 +64,7 @@
#include "header.pb-c.h"
#include "progran.pb-c.h"
+#include "enb_agent_mac.h"
#include "SIMULATION/TOOLS/defs.h" // for taus
@@ -80,7 +81,7 @@ schedule_ue_spec_default(
uint32_t frame,
uint32_t subframe,
int *mbsfn_flag,
- Protocol__ProgranMessage *dl_info
+ Protocol__ProgranMessage **dl_info
)
//------------------------------------------------------------------------------
{
@@ -126,11 +127,12 @@ schedule_ue_spec_default(
uint8_t ue_has_transmission = 0;
uint32_t ndi;
-
+ enb_agent_mac_create_empty_dl_config(mod_id, dl_info);
+
if (UE_list->head==-1) {
return;
}
-
+
start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
@@ -763,10 +765,10 @@ schedule_ue_spec_default(
} // CC_id loop
// Add all the dl_data elements to the progran message
- dl_info->dl_mac_config_msg->n_dl_ue_data = num_ues_added;
- dl_info->dl_mac_config_msg->dl_ue_data = (Protocol__PrpDlData **) malloc(sizeof(Protocol__PrpDlData *) * num_ues_added);
+ (*dl_info)->dl_mac_config_msg->n_dl_ue_data = num_ues_added;
+ (*dl_info)->dl_mac_config_msg->dl_ue_data = (Protocol__PrpDlData **) malloc(sizeof(Protocol__PrpDlData *) * num_ues_added);
for (i = 0; i < num_ues_added; i++) {
- dl_info->dl_mac_config_msg->dl_ue_data[i] = dl_data[i];
+ (*dl_info)->dl_mac_config_msg->dl_ue_data[i] = dl_data[i];
}
stop_meas(&eNB->schedule_dlsch);
diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c
new file mode 100644
index 0000000000000000000000000000000000000000..1818a6408781f5f12ea18482add2355c85399444
--- /dev/null
+++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.c
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenAirInterface.The full GNU General Public License is
+ included in this distribution in the file called "COPYING". If not,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+*******************************************************************************/
+
+/*! \file eNB_agent_scheduler_dlsch_ue_remote.c
+ * \brief procedures related to remote scheduling in the DLSCH transport channel
+ * \author Xenofon Foukas
+ * \date 2016
+ * \email: x.foukas@sms.ed.ac.uk
+ * \version 0.1
+ * @ingroup _mac
+
+ */
+
+#include "eNB_agent_scheduler_dlsch_ue_remote.h"
+
+struct DlMacConfigHead queue_head;
+
+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) {
+ TAILQ_INIT(&queue_head);
+ queue_initialized = 1;
+ }
+
+ dl_mac_config_element_t *dl_config_elem;
+
+ int diff;
+
+ // 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
+ 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
+ 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
+ enb_agent_create_empty_dl_config(mod_id, dl_info);
+ return;
+ }
+ }
+
+ //Done with the local cache. Now we need to check if something new arrived
+ enb_agent_get_pending_dl_mac_config(mod_id, dl_info);
+ while (*dl_info != NULL) {
+
+ diff = get_sf_difference(mod_id, (*dl_info)->dl_mac_config_msg->sfn_sf);
+ if (diff == 0) { // Got a command for this sfn_sf
+ return;
+ } else if (diff < 0) {
+ enb_agent_mac_destroy_dl_config(*dl_info);
+ } else { // Intended for future subframe. Store it in local cache
+ dl_mac_config_element_t *e = malloc(sizeof(dl_mac_config_element_t));
+ TAILQ_INSERT_TAIL(&queue_head, e, configs);
+ enb_agent_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
+ enb_agent_create_empty_dl_config(mod_id, dl_info);
+}
+
+int get_sf_difference(mid_t mod_id, uint16_t sfn_sf) {
+ int diff_in_subframes;
+
+ uint16_t current_frame = get_current_system_frame_num(mod_id);
+ uint16_t current_subframe = get_current_subframe(mod_id);
+ uint16_t current_sfn_sf = get_sfn_sf(mod_id);
+
+ if (sfn_sf == current_sfn_sf) {
+ return 0;
+ }
+
+ uint16_t frame_mask = !((1<<4) - 1);
+ uint16_t frame = (sfn_sf & frame_mask) >> 4;
+
+ uint16_t sf_mask = !(((1<<12) - 1) << 4);
+ uint16_t subframe = (sfn_sf & sf_mask);
+
+ if (frame == current_frame) {
+ return subframe - current_subframe;
+ } else if (frame > current_frame) {
+ diff_in_subframes = 9 - current_subframe;
+ diff_in_subframes += subframe;
+ 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;
+ if (frame > 0) {
+ diff_in_subframes += (frame - 1) * 10;
+ }
+ diff_in_subframes += (1023 - current_frame) * 10;
+ if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+}
diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.h b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b8ec3ec19b6870c7a350cca28786a2942224a21
--- /dev/null
+++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue_remote.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenAirInterface.The full GNU General Public License is
+ included in this distribution in the file called "COPYING". If not,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+*******************************************************************************/
+
+/*! \file eNB_agent_scheduler_dlsch_ue_remote.h
+ * \brief Local stub for remote scheduler used by the controller
+ * \author Xenofon Foukas
+ * \date 2016
+ * \email: x.foukas@sms.ed.ac.uk
+ * \version 0.1
+ * @ingroup _mac
+
+ */
+
+#ifndef __LAYER2_MAC_ENB_AGENT_SCHEDULER_DLSCH_UE_REMOTE_H__
+#define __LAYER2_MAC_ENB_AGENT_SCHEDULER_DLSCH_UE_REMOTE_H___
+
+#include "progran.pb-c.h"
+#include "header.pb-c.h"
+
+#include "ENB_APP/enb_agent_defs.h"
+#include "enb_agent_mac.h"
+
+#include
+
+// Maximum value of schedule ahead of time
+// Required to identify if a dl_command is for the future or not
+#define SCHED_AHEAD_SUBFRAMES 10
+
+typedef struct dl_mac_config_element_s {
+ Protocol__ProgranMessage *dl_info;
+ TAILQ_ENTRY(dl_mac_config_element_s) configs;
+} dl_mac_config_element_t;
+
+TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s);
+
+/*
+ * Default scheduler used by the eNB agent
+ */
+void schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subframe,
+ int *mbsfn_flag, Protocol__ProgranMessage **dl_info);
+
+
+// Find the difference in subframes from the given subframe
+// negative for older value
+// 0 for equal
+// positive for future value
+// Based on
+int get_sf_difference(mid_t mod_id, uint16_t sfn_sf);
+
+#endif
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index e2423e2c10804f2c3ad3505c905ca49e05ec861e..9a172cb37731366275a9f4968a500491e1a65976 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -281,13 +281,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -330,13 +329,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -361,13 +359,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -398,13 +395,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -427,13 +423,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -471,13 +466,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -502,13 +496,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -539,13 +532,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -567,13 +559,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -620,13 +611,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -645,13 +635,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -673,13 +662,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -707,13 +695,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -731,13 +718,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -759,13 +745,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -798,13 +783,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -826,13 +810,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -859,13 +842,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -885,13 +867,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -911,13 +892,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -937,13 +917,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
frameP,
@@ -965,19 +944,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
- enb_agent_mac_create_empty_dl_config(module_idP, &msg);
agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
- msg);
+ &msg);
apply_dl_scheduling_decisions(module_idP,
- frameP,
- subframeP,
- mbsfn_status,
- msg);
+ frameP,
+ subframeP,
+ mbsfn_status,
+ msg);
enb_agent_mac_destroy_dl_config(msg);
}
#endif
diff --git a/openair2/LAYER2/MAC/enb_agent_mac_proto.h b/openair2/LAYER2/MAC/enb_agent_mac_proto.h
index 7fcdbc29c3c891b5cb9aba34f56613205cc50120..f453fa2fa309ce62f448119164ef05b92e2d2d81 100644
--- a/openair2/LAYER2/MAC/enb_agent_mac_proto.h
+++ b/openair2/LAYER2/MAC/enb_agent_mac_proto.h
@@ -48,14 +48,13 @@
* Default scheduler used by the eNB agent
*/
void schedule_ue_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe,
- int *mbsfn_flag, Protocol__ProgranMessage *dl_info);
-
+ int *mbsfn_flag, Protocol__ProgranMessage **dl_info);
/*
* Data plane function for applying the DL decisions of the scheduler
*/
void apply_dl_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag,
- Protocol__ProgranMessage *dl_scheduling_info);
+ const Protocol__ProgranMessage *dl_scheduling_info);
/*
* Data plane function for applying the UE specific DL decisions of the scheduler