Commit 16bbb96d authored by Xenofon Foukas's avatar Xenofon Foukas

Added continuous update functionality in the MAC layer

parent 3ad4d26f
...@@ -35,13 +35,21 @@ ...@@ -35,13 +35,21 @@
*/ */
#include "enb_agent_mac.h" #include "enb_agent_mac.h"
#include "enb_agent_extern.h"
#include "enb_agent_common.h"
#include "enb_agent_mac_internal.h"
#include "log.h" #include "log.h"
/*Flags showing if a mac agent has already been registered*/
unsigned int mac_agent_registered[NUM_MAX_ENB];
int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg){ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg){
// TODO: Must deal with sanitization of input // TODO: Must deal with sanitization of input
// TODO: Must check if RNTIs and cell ids of the request actually exist // TODO: Must check if RNTIs and cell ids of the request actually exist
// TODO: Must resolve conflicts among stats requests
int i; int i;
void *buffer; void *buffer;
...@@ -71,15 +79,13 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -71,15 +79,13 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
switch(stats_req->body_case) { switch(stats_req->body_case) {
case PROTOCOL__PRP_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ; case PROTOCOL__PRP_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ;
Protocol__PrpCompleteStatsRequest *comp_req = stats_req->complete_stats_request; Protocol__PrpCompleteStatsRequest *comp_req = stats_req->complete_stats_request;
if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) { if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_OFF) {
//TODO: Must create an event based report mechanism /*Disable both periodic and continuous updates*/
*msg = NULL; enb_agent_disable_cont_mac_stats_update(mod_id);
return 0;
} else if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_OFF) {
enb_agent_destroy_timer_by_task_id(xid); enb_agent_destroy_timer_by_task_id(xid);
*msg = NULL; *msg = NULL;
return 0; return 0;
} else { //One-off or periodical reporting } else { //One-off, periodical or continuous reporting
//Set the proper flags //Set the proper flags
ue_flags = comp_req->ue_report_flags; ue_flags = comp_req->ue_report_flags;
c_flags = comp_req->cell_report_flags; c_flags = comp_req->cell_report_flags;
...@@ -136,6 +142,16 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -136,6 +142,16 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
usec_interval = usec_interval%(1000*1000); usec_interval = usec_interval%(1000*1000);
} }
enb_agent_create_timer(sec_interval, usec_interval, ENB_AGENT_DEFAULT, enb_id, ENB_AGENT_TIMER_TYPE_PERIODIC, xid, enb_agent_handle_timed_task,(void*) timer_args, &timer_id); enb_agent_create_timer(sec_interval, usec_interval, ENB_AGENT_DEFAULT, enb_id, ENB_AGENT_TIMER_TYPE_PERIODIC, xid, enb_agent_handle_timed_task,(void*) timer_args, &timer_id);
} else if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) {
/*If request was for continuous updates, disable the previous configuration and
set up a new one*/
enb_agent_disable_cont_mac_stats_update(mod_id);
stats_request_config_t request_config;
request_config.report_type = PROTOCOL__PRP_STATS_TYPE__PRST_COMPLETE_STATS;
request_config.report_frequency = PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_ONCE;
request_config.period = 0;
request_config.config = &report_config;
enb_agent_enable_cont_mac_stats_update(enb_id, xid, &request_config);
} }
} }
break; break;
...@@ -453,7 +469,7 @@ int enb_agent_mac_stats_reply(mid_t mod_id, ...@@ -453,7 +469,7 @@ int enb_agent_mac_stats_reply(mid_t mod_id,
dl_report->n_csi_report = 1; dl_report->n_csi_report = 1;
//TODO:Create the actual CSI reports. //TODO:Create the actual CSI reports.
Protocol__PrpDlCsi **csi_reports; Protocol__PrpDlCsi **csi_reports;
csi_reports = malloc(sizeof(Protocol__PrpDlCsi *)); csi_reports = malloc(sizeof(Protocol__PrpDlCsi *)*dl_report->n_csi_report);
if (csi_reports == NULL) if (csi_reports == NULL)
goto error; goto error;
for (j = 0; j < dl_report->n_csi_report; j++) { for (j = 0; j < dl_report->n_csi_report; j++) {
...@@ -505,7 +521,7 @@ int enb_agent_mac_stats_reply(mid_t mod_id, ...@@ -505,7 +521,7 @@ int enb_agent_mac_stats_reply(mid_t mod_id,
paging_report->n_paging_info = 1; paging_report->n_paging_info = 1;
//Provide a report for each pending paging message //Provide a report for each pending paging message
Protocol__PrpPagingInfo **p_info; Protocol__PrpPagingInfo **p_info;
p_info = malloc(sizeof(Protocol__PrpPagingInfo *)); p_info = malloc(sizeof(Protocol__PrpPagingInfo *) * paging_report->n_paging_info);
if (p_info == NULL) if (p_info == NULL)
goto error; goto error;
for (j = 0; j < paging_report->n_paging_info; j++) { for (j = 0; j < paging_report->n_paging_info; j++) {
...@@ -975,15 +991,21 @@ int enb_agent_mac_destroy_sf_trigger(Protocol__ProgranMessage *msg) { ...@@ -975,15 +991,21 @@ int enb_agent_mac_destroy_sf_trigger(Protocol__ProgranMessage *msg) {
return -1; return -1;
} }
void enb_agent_send_sr_info(mid_t mod_id, msg_context_t *context) { /***********************************************
* eNB agent - technology mac API implementation
***********************************************/
void enb_agent_send_sr_info(mid_t mod_id) {
int size; int size;
Protocol__ProgranMessage *msg; Protocol__ProgranMessage *msg;
void *data; void *data;
int priority; int priority;
err_code_t err_code; err_code_t err_code;
int xid = 0;
/*TODO: Must use a proper xid*/ /*TODO: Must use a proper xid*/
err_code = enb_agent_mac_sr_info(mod_id, (void *) &(context->tx_xid), &msg); err_code = enb_agent_mac_sr_info(mod_id, (void *) &xid, &msg);
if (err_code < 0) { if (err_code < 0) {
goto error; goto error;
} }
...@@ -997,20 +1019,23 @@ void enb_agent_send_sr_info(mid_t mod_id, msg_context_t *context) { ...@@ -997,20 +1019,23 @@ void enb_agent_send_sr_info(mid_t mod_id, msg_context_t *context) {
} }
LOG_D(ENB_AGENT,"sent message with size %d\n", size); LOG_D(ENB_AGENT,"sent message with size %d\n", size);
return;
} }
error: error:
LOG_D(ENB_AGENT, "Could not send sr message\n"); LOG_D(ENB_AGENT, "Could not send sr message\n");
} }
void enb_agent_send_sf_trigger(mid_t mod_id, msg_context_t *context) { void enb_agent_send_sf_trigger(mid_t mod_id) {
int size; int size;
Protocol__ProgranMessage *msg; Protocol__ProgranMessage *msg;
void *data; void *data;
int priority; int priority;
err_code_t err_code; err_code_t err_code;
int xid = 0;
/*TODO: Must use a proper xid*/ /*TODO: Must use a proper xid*/
err_code = enb_agent_mac_sf_trigger(mod_id, (void *) &(context->tx_xid), &msg); err_code = enb_agent_mac_sf_trigger(mod_id, (void *) &xid, &msg);
if (err_code < 0) { if (err_code < 0) {
goto error; goto error;
} }
...@@ -1024,6 +1049,60 @@ void enb_agent_send_sf_trigger(mid_t mod_id, msg_context_t *context) { ...@@ -1024,6 +1049,60 @@ void enb_agent_send_sf_trigger(mid_t mod_id, msg_context_t *context) {
} }
LOG_D(ENB_AGENT,"sent message with size %d\n", size); LOG_D(ENB_AGENT,"sent message with size %d\n", size);
return;
}
error:
LOG_D(ENB_AGENT, "Could not send sf trigger message\n");
}
void enb_agent_send_update_mac_stats(mid_t mod_id) {
Protocol__ProgranMessage *current_report, *msg;
void *data;
int size;
err_code_t err_code;
int priority;
mac_stats_updates_context_t stats_context = mac_stats_context[mod_id];
if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) {
goto error;
}
/*Create a fresh report with the required flags*/
err_code = enb_agent_mac_handle_stats(mod_id, (void *) mac_stats_context[mod_id].stats_req, &current_report);
if (err_code < 0) {
goto error;
}
/*TODO:Check if a previous reports exists and if yes, generate a report
*that is the diff between the old and the new report,
*respecting the thresholds. Otherwise send the new report*/
if (mac_stats_context[mod_id].prev_stats_reply != NULL) {
msg = enb_agent_generate_diff_mac_stats_report(current_report, mac_stats_context[mod_id].prev_stats_reply);
/*Destroy the old stats*/
enb_agent_destroy_progran_message(mac_stats_context[mod_id].prev_stats_reply);
}
/*Use the current report for future comparissons*/
mac_stats_context[mod_id].prev_stats_reply = current_report;
if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) {
goto error;
}
if (msg != NULL){
data=enb_agent_pack_message(msg, &size);
/*Send any stats updates using the MAC channel of the eNB*/
if (enb_agent_msg_send(mod_id, ENB_AGENT_MAC, data, size, priority)) {
err_code = PROTOCOL__PROGRAN_ERR__MSG_ENQUEUING;
goto error;
}
LOG_D(ENB_AGENT,"sent message with size %d\n", size);
return;
} }
error: error:
LOG_D(ENB_AGENT, "Could not send sf trigger message\n"); LOG_D(ENB_AGENT, "Could not send sf trigger message\n");
...@@ -1035,12 +1114,14 @@ int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { ...@@ -1035,12 +1114,14 @@ int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
return -1; return -1;
} }
xface->agent_ctxt = &shared_ctxt[mod_id]; //xface->agent_ctxt = &shared_ctxt[mod_id];
xface->enb_agent_send_sr_info = enb_agent_send_sr_info; xface->enb_agent_send_sr_info = enb_agent_send_sr_info;
xface->enb_agent_send_sf_trigger = enb_agent_send_sf_trigger; xface->enb_agent_send_sf_trigger = enb_agent_send_sf_trigger;
xface->enb_agent_send_update_mac_stats = enb_agent_send_update_mac_stats;
mac_agent_registered[mod_id] = 1; mac_agent_registered[mod_id] = 1;
return 1;
return 0;
} }
int enb_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { int enb_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
...@@ -1050,10 +1131,97 @@ int enb_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { ...@@ -1050,10 +1131,97 @@ int enb_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
return -1; return -1;
} }
xface->agent_ctxt = NULL; //xface->agent_ctxt = NULL;
xface->enb_agent_send_sr_info = NULL; xface->enb_agent_send_sr_info = NULL;
xface->enb_agent_send_sf_trigger = NULL; xface->enb_agent_send_sf_trigger = NULL;
return 0;
}
/******************************************************
*Implementations of enb_agent_mac_internal.h functions
******************************************************/
err_code_t enb_agent_init_cont_mac_stats_update(mid_t mod_id) {
/*Initialize the Mac stats update structure*/
/*Initially the continuous update is set to false*/
mac_stats_context[mod_id].cont_update = 0;
mac_stats_context[mod_id].is_initialized = 1;
mac_stats_context[mod_id].stats_req = NULL;
mac_stats_context[mod_id].prev_stats_reply = NULL;
mac_stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t));
if (mac_stats_context[mod_id].mutex == NULL)
goto error;
if (pthread_mutex_init(mac_stats_context[mod_id].mutex, NULL))
goto error;;
return 0;
error:
return -1;
}
err_code_t enb_agent_destroy_cont_mac_stats_update(mid_t mod_id) {
/*Disable the continuous updates for the MAC*/
mac_stats_context[mod_id].cont_update = 0;
mac_stats_context[mod_id].is_initialized = 0;
enb_agent_destroy_progran_message(mac_stats_context[mod_id].stats_req);
enb_agent_destroy_progran_message(mac_stats_context[mod_id].prev_stats_reply);
free(mac_stats_context[mod_id].mutex);
mac_agent_registered[mod_id] = NULL; mac_agent_registered[mod_id] = NULL;
return 1; return 1;
} }
err_code_t enb_agent_enable_cont_mac_stats_update(mid_t mod_id,
xid_t xid, stats_request_config_t *stats_req) {
/*Enable the continuous updates for the MAC*/
if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) {
goto error;
}
Protocol__ProgranMessage *req_msg;
enb_agent_mac_stats_request(mod_id, xid, stats_req, &req_msg);
mac_stats_context[mod_id].stats_req = req_msg;
mac_stats_context[mod_id].prev_stats_reply = NULL;
mac_stats_context[mod_id].cont_update = 1;
mac_stats_context[mod_id].xid = xid;
if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) {
goto error;
}
return 0;
error:
LOG_E(ENB_AGENT, "mac_stats_context for eNB %d is not initialized\n", mod_id);
return -1;
}
err_code_t enb_agent_disable_cont_mac_stats_update(mid_t mod_id) {
/*Disable the continuous updates for the MAC*/
if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) {
goto error;
}
mac_stats_context[mod_id].cont_update = 0;
mac_stats_context[mod_id].xid = 0;
if (mac_stats_context[mod_id].stats_req != NULL) {
enb_agent_destroy_progran_message(mac_stats_context[mod_id].stats_req);
}
if (mac_stats_context[mod_id].prev_stats_reply != NULL) {
enb_agent_destroy_progran_message(mac_stats_context[mod_id].prev_stats_reply);
}
if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) {
goto error;
}
return 0;
error:
LOG_E(ENB_AGENT, "mac_stats_context for eNB %d is not initialized\n", mod_id);
return -1;
}
...@@ -45,9 +45,6 @@ ...@@ -45,9 +45,6 @@
#include "enb_agent_common.h" #include "enb_agent_common.h"
#include "enb_agent_extern.h" #include "enb_agent_extern.h"
/*Flags showing if a mac agent has already been registered*/
unsigned int mac_agent_registered[NUM_MAX_ENB_AGENT];
/* These types will be used to give /* These types will be used to give
instructions for the type of stats reports instructions for the type of stats reports
we need to create */ we need to create */
...@@ -72,14 +69,13 @@ typedef struct { ...@@ -72,14 +69,13 @@ typedef struct {
cc_report_type_t *cc_report_type; cc_report_type_t *cc_report_type;
} report_config_t; } report_config_t;
typedef struct { typedef struct stats_request_config_s{
uint8_t report_type; uint8_t report_type;
uint8_t report_frequency; uint8_t report_frequency;
uint16_t period; /*In number of subframes*/ uint16_t period; /*In number of subframes*/
report_config_t *config; report_config_t *config;
} stats_request_config_t; } stats_request_config_t;
int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__ProgranMessage **msg); 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); int enb_agent_mac_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__ProgranMessage **msg);
...@@ -104,10 +100,14 @@ int enb_agent_mac_destroy_sf_trigger(Protocol__ProgranMessage *msg); ...@@ -104,10 +100,14 @@ int enb_agent_mac_destroy_sf_trigger(Protocol__ProgranMessage *msg);
**********************************/ **********************************/
/*Inform controller about received scheduling requests during a subframe*/ /*Inform controller about received scheduling requests during a subframe*/
void enb_agent_send_sr_info(mid_t mod_id, msg_context_t *context); void enb_agent_send_sr_info(mid_t mod_id);
/*Inform the controller about the current UL/DL subframe*/ /*Inform the controller about the current UL/DL subframe*/
void enb_agent_send_sf_trigger(mid_t mod_id, msg_context_t *context); void enb_agent_send_sf_trigger(mid_t mod_id);
/// Send to the controller all the mac stat updates that occured during this subframe
/// based on the stats request configuration
void enb_agent_send_update_mac_stats(mid_t mod_id);
/*Register technology specific interface callbacks*/ /*Register technology specific interface callbacks*/
int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface); int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment