Commit 11b2f829 authored by Xenofon Foukas's avatar Xenofon Foukas

Integrated timer to work with periodic report messages and agent tasks

parent e88779c4
...@@ -53,7 +53,7 @@ static uint16_t in_port; ...@@ -53,7 +53,7 @@ static uint16_t in_port;
void *send_thread(void *args); void *send_thread(void *args);
void *receive_thread(void *args); void *receive_thread(void *args);
pthread_t new_thread(void *(*f)(void *), void *b); pthread_t new_thread(void *(*f)(void *), void *b);
err_code_t enb_agent_timeout(void* args); Protocol__ProgranMessage *enb_agent_timeout(void* args);
/* /*
* enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller
...@@ -61,6 +61,13 @@ err_code_t enb_agent_timeout(void* args); ...@@ -61,6 +61,13 @@ err_code_t enb_agent_timeout(void* args);
*/ */
void *enb_agent_task(void *args){ void *enb_agent_task(void *args){
msg_context_t *d = (msg_context_t *) args;
Protocol__ProgranMessage *msg;
void *data;
int size;
err_code_t err_code;
int priority;
MessageDef *msg_p = NULL; MessageDef *msg_p = NULL;
const char *msg_name = NULL; const char *msg_name = NULL;
instance_t instance; instance_t instance;
...@@ -86,7 +93,15 @@ void *enb_agent_task(void *args){ ...@@ -86,7 +93,15 @@ void *enb_agent_task(void *args){
break; break;
case TIMER_HAS_EXPIRED: case TIMER_HAS_EXPIRED:
enb_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, &msg_p->ittiMsg.timer_has_expired.arg); msg = enb_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, msg_p->ittiMsg.timer_has_expired.arg);
if (msg != NULL){
data=enb_agent_send_message(msg,&size);
if (message_put(d->tx_mq, data, size, priority)){
err_code = PROTOCOL__PROGRAN_ERR__MSG_ENQUEUING;
goto error;
}
LOG_D(ENB_AGENT,"sent message with size %d\n", size);
}
break; break;
default: default:
...@@ -96,46 +111,49 @@ void *enb_agent_task(void *args){ ...@@ -96,46 +111,49 @@ void *enb_agent_task(void *args){
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
continue;
error:
LOG_E(ENB_AGENT,"enb_agent_task: error %d occured\n",err_code);
} while (1); } while (1);
return NULL; return NULL;
} }
void *send_thread(void *args) { /* void *send_thread(void *args) { */
#ifdef TEST_TIMER /* #ifdef TEST_TIMER */
msg_context_t *d = args; /* msg_context_t *d = args; */
void *data; /* void *data; */
int size; /* int size; */
int priority; /* int priority; */
struct timeval t1, t2; /* struct timeval t1, t2; */
long long t; /* long long t; */
struct timespec ts; /* struct timespec ts; */
unsigned int delay = 250*1000; /* unsigned int delay = 250*1000; */
while(1) { /* while(1) { */
gettimeofday(&t1, NULL); /* gettimeofday(&t1, NULL); */
enb_agent_sleep_until(&ts, delay); /* enb_agent_sleep_until(&ts, delay); */
gettimeofday(&t2, NULL); /* gettimeofday(&t2, NULL); */
t = ((t2.tv_sec * 1000000) + t2.tv_usec) - ((t1.tv_sec * 1000000) + t1.tv_usec); /* t = ((t2.tv_sec * 1000000) + t2.tv_usec) - ((t1.tv_sec * 1000000) + t1.tv_usec); */
LOG_I(ENB_AGENT, "Call to sleep_until(%d) took %lld us\n", delay, t); /* LOG_I(ENB_AGENT, "Call to sleep_until(%d) took %lld us\n", delay, t); */
sleep(1); /* sleep(1); */
} /* } */
#endif /* #endif */
/* while (1) { /* /\* while (1) { */
// need logic for the timer, and /* // need logic for the timer, and */
usleep(10); /* usleep(10); */
if (message_put(d->tx_mq, data, size, priority)) goto error; /* if (message_put(d->tx_mq, data, size, priority)) goto error; */
}*/ /* }*\/ */
return NULL; /* return NULL; */
error: /* error: */
printf("receive_thread: there was an error\n"); /* printf("receive_thread: there was an error\n"); */
return NULL; /* return NULL; */
} /* } */
void *receive_thread(void *args) { void *receive_thread(void *args) {
...@@ -290,25 +308,25 @@ int enb_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){ ...@@ -290,25 +308,25 @@ int enb_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){
* start the enb agent task for tx and interaction with the underlying network function * start the enb agent task for tx and interaction with the underlying network function
*/ */
if (itti_create_task (TASK_ENB_AGENT, enb_agent_task, NULL) < 0) { if (itti_create_task (TASK_ENB_AGENT, enb_agent_task, (void *) &shared_ctxt[mod_id]) < 0) {
LOG_E(ENB_AGENT, "Create task for eNB Agent failed\n"); LOG_E(ENB_AGENT, "Create task for eNB Agent failed\n");
return -1; return -1;
} }
#ifdef TEST_TIMER //#ifdef TEST_TIMER
long timer_id=0; long timer_id=0;
enb_agent_timer_args_t timer_args; enb_agent_timer_args_t timer_args;
memset (&timer_args, 0, sizeof(enb_agent_timer_args_t)); memset (&timer_args, 0, sizeof(enb_agent_timer_args_t));
timer_args.mod_id = mod_id; timer_args.mod_id = mod_id;
timer_args.cc_actions= ENB_AGENT_ACTION_APPLY; //timer_args.cc_actions= ENB_AGENT_ACTION_APPLY;
timer_args.cc_report_flags = PROTOCOL__PRP_CELL_STATS_TYPE__PRCST_NOISE_INTERFERENCE; //timer_args.cc_report_flags = PROTOCOL__PRP_CELL_STATS_TYPE__PRCST_NOISE_INTERFERENCE;
timer_args.ue_actions = ENB_AGENT_ACTION_SEND; //timer_args.ue_actions = ENB_AGENT_ACTION_SEND;
timer_args.ue_report_flags = PROTOCOL__PRP_UE_STATS_TYPE__PRUST_BSR | PROTOCOL__PRP_UE_STATS_TYPE__PRUST_DL_CQI; //timer_args.ue_report_flags = PROTOCOL__PRP_UE_STATS_TYPE__PRUST_BSR | PROTOCOL__PRP_UE_STATS_TYPE__PRUST_DL_CQI;
enb_agent_create_timer(1, 0, ENB_AGENT_DEFAULT, mod_id, ENB_AGENT_TIMER_TYPE_PERIODIC, enb_agent_timeout,(void*)&timer_args, &timer_id); enb_agent_create_timer(1, 0, ENB_AGENT_DEFAULT, mod_id, ENB_AGENT_TIMER_TYPE_PERIODIC, enb_agent_timeout,(void*)&timer_args, &timer_id);
#endif //#endif
new_thread(send_thread, &shared_ctxt); //new_thread(send_thread, &shared_ctxt);
//while (1) pause(); //while (1) pause();
...@@ -342,15 +360,15 @@ int enb_agent_stop(mid_t mod_id){ ...@@ -342,15 +360,15 @@ int enb_agent_stop(mid_t mod_id){
err_code_t enb_agent_timeout(void* args){ Protocol__ProgranMessage *enb_agent_timeout(void* args){
// enb_agent_timer_args_t *timer_args = calloc(1, sizeof(*timer_args)); // enb_agent_timer_args_t *timer_args = calloc(1, sizeof(*timer_args));
//memcpy (timer_args, args, sizeof(*timer_args)); //memcpy (timer_args, args, sizeof(*timer_args));
enb_agent_timer_args_t *timer_args = (enb_agent_timer_args_t *) args; enb_agent_timer_args_t *timer_args = (enb_agent_timer_args_t *) args;
LOG_I(ENB_AGENT, "enb_agent %d timeout\n", timer_args->mod_id); LOG_I(ENB_AGENT, "enb_agent %d timeout\n", timer_args->mod_id);
LOG_I(ENB_AGENT, "eNB action %d ENB flags %d \n", timer_args->cc_actions,timer_args->cc_report_flags); //LOG_I(ENB_AGENT, "eNB action %d ENB flags %d \n", timer_args->cc_actions,timer_args->cc_report_flags);
LOG_I(ENB_AGENT, "UE action %d UE flags %d \n", timer_args->ue_actions,timer_args->ue_report_flags); //LOG_I(ENB_AGENT, "UE action %d UE flags %d \n", timer_args->ue_actions,timer_args->ue_report_flags);
return 0; return NULL;
} }
...@@ -311,7 +311,7 @@ uint16_t get_sfn_sf (mid_t mod_id) { ...@@ -311,7 +311,7 @@ uint16_t get_sfn_sf (mid_t mod_id) {
frame = (uint16_t) get_current_frame(mod_id); frame = (uint16_t) get_current_frame(mod_id);
subframe = (uint16_t) get_current_subframe(mod_id); subframe = (uint16_t) get_current_subframe(mod_id);
sfn_sf = (frame << 12) | subframe; sfn_sf = (subframe << 12) | frame;
return sfn_sf; return sfn_sf;
} }
......
...@@ -86,6 +86,8 @@ Protocol__ProgranMessage* enb_agent_handle_message (mid_t mod_id, ...@@ -86,6 +86,8 @@ Protocol__ProgranMessage* enb_agent_handle_message (mid_t mod_id,
uint8_t *data, uint8_t *data,
uint32_t size); uint32_t size);
Protocol__ProgranMessage *enb_agent_handle_timed_task(void *args);
void * enb_agent_send_message(Protocol__ProgranMessage *msg, void * enb_agent_send_message(Protocol__ProgranMessage *msg,
uint32_t * size); uint32_t * size);
...@@ -107,7 +109,7 @@ int get_current_frame(mid_t mod_id); ...@@ -107,7 +109,7 @@ int get_current_frame(mid_t mod_id);
int get_current_subframe(mid_t mod_id); int get_current_subframe(mid_t mod_id);
/*Return the frame and subframe number in compact 16-bit format. /*Return the frame and subframe number in compact 16-bit format.
Bits 0-3 frame, rest for subframe. Required by progRAN protocol*/ Bits 0-3 subframe, rest for frame. Required by progRAN protocol*/
uint16_t get_sfn_sf (mid_t mod_id); uint16_t get_sfn_sf (mid_t mod_id);
int get_num_ues(mid_t mod_id); int get_num_ues(mid_t mod_id);
...@@ -137,7 +139,7 @@ int get_ue_wcqi (mid_t mod_id, mid_t ue_id); ...@@ -137,7 +139,7 @@ int get_ue_wcqi (mid_t mod_id, mid_t ue_id);
/* Type of the callback executed when the timer expired */ /* Type of the callback executed when the timer expired */
typedef err_code_t (*enb_agent_timer_callback_t)(void*); typedef Protocol__ProgranMessage *(*enb_agent_timer_callback_t)(void*);
typedef enum { typedef enum {
/* oneshot timer: */ /* oneshot timer: */
...@@ -169,13 +171,7 @@ typedef enum { ...@@ -169,13 +171,7 @@ typedef enum {
typedef struct enb_agent_timer_args_s{ typedef struct enb_agent_timer_args_s{
mid_t mod_id; mid_t mod_id;
Protocol__ProgranMessage *msg;
agent_action_t cc_actions;
uint32_t cc_report_flags;
agent_action_t ue_actions;
uint32_t ue_report_flags;
} enb_agent_timer_args_t; } enb_agent_timer_args_t;
...@@ -225,7 +221,7 @@ struct enb_agent_timer_element_s * get_timer_entry(long timer_id); ...@@ -225,7 +221,7 @@ struct enb_agent_timer_element_s * get_timer_entry(long timer_id);
err_code_t enb_agent_process_timeout(long timer_id, void* timer_args); Protocol__ProgranMessage * enb_agent_process_timeout(long timer_id, void* timer_args);
int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b); int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b);
......
...@@ -133,11 +133,28 @@ void * enb_agent_send_message(Protocol__ProgranMessage *msg, ...@@ -133,11 +133,28 @@ void * enb_agent_send_message(Protocol__ProgranMessage *msg,
error : error :
LOG_E(ENB_AGENT,"errno %d occured\n",err_code); LOG_E(ENB_AGENT,"errno %d occured\n",err_code);
return NULL; return NULL;
}
Protocol__ProgranMessage *enb_agent_handle_timed_task(void *args) {
err_code_t err_code;
enb_agent_timer_args_t *timer_args = (enb_agent_timer_args_t *) args;
Protocol__ProgranMessage *timed_task, *reply_message;
timed_task = timer_args->msg;
err_code = ((*messages_callback[timed_task->msg_case-1][timed_task->msg_dir-1])(timer_args->mod_id, (void *) timed_task, &reply_message));
if ( err_code < 0 ){
goto error;
}
return reply_message;
error:
LOG_E(ENB_AGENT,"errno %d occured\n",err_code);
return NULL;
} }
err_code_t enb_agent_process_timeout(long timer_id, void* timer_args){ Protocol__ProgranMessage* enb_agent_process_timeout(long timer_id, void* timer_args){
struct enb_agent_timer_element_s *found = get_timer_entry(timer_id); struct enb_agent_timer_element_s *found = get_timer_entry(timer_id);
...@@ -148,7 +165,6 @@ err_code_t enb_agent_process_timeout(long timer_id, void* timer_args){ ...@@ -148,7 +165,6 @@ err_code_t enb_agent_process_timeout(long timer_id, void* timer_args){
LOG_W(ENB_AGENT,"null timer args\n"); LOG_W(ENB_AGENT,"null timer args\n");
return found->cb(timer_args); return found->cb(timer_args);
error: error:
LOG_E(ENB_AGENT, "can't get the timer element\n"); LOG_E(ENB_AGENT, "can't get the timer element\n");
......
...@@ -48,6 +48,7 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -48,6 +48,7 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
int size; int size;
err_code_t err_code; err_code_t err_code;
xid_t xid; xid_t xid;
uint32_t usec_interval, sec_interval;
//TODO: We do not deal with multiple CCs at the moment and eNB id is 0 //TODO: We do not deal with multiple CCs at the moment and eNB id is 0
int cc_id = 0; int cc_id = 0;
...@@ -70,12 +71,13 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -70,12 +71,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_PERIODICAL) { /* if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_PERIODICAL) { */
//TODO: Must create a periodic report. Implement once the /* //TODO: Must create a periodic report. Implement once the */
// timer functionality is supported /* // timer functionality is supported */
*msg = NULL; /* *msg = NULL; */
return 0; /* return 0; */
} else if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) { /* } else */
if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) {
//TODO: Must create an event based report mechanism //TODO: Must create an event based report mechanism
*msg = NULL; *msg = NULL;
return 0; return 0;
...@@ -83,7 +85,7 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -83,7 +85,7 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
//TODO: Must implement to deactivate the event based reporting //TODO: Must implement to deactivate the event based reporting
*msg = NULL; *msg = NULL;
return 0; return 0;
} else { //One-off reporting } else { //One-off or periodical 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;
...@@ -114,6 +116,33 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -114,6 +116,33 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
report_config.cc_report_type[i].cc_id = i; report_config.cc_report_type[i].cc_id = i;
report_config.cc_report_type[i].cc_report_flags = c_flags; report_config.cc_report_type[i].cc_report_flags = c_flags;
} }
/* Check if request was periodical */
if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_PERIODICAL) {
/* Create a one off progran message as an argument for the periodical task */
Protocol__ProgranMessage *timer_msg;
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_mac_stats_request(enb_id, xid, &request_config, &timer_msg);
/* Create a timer */
long timer_id = 0;
enb_agent_timer_args_t *timer_args;
timer_args = malloc(sizeof(enb_agent_timer_args_t));
memset (timer_args, 0, sizeof(enb_agent_timer_args_t));
timer_args->mod_id = enb_id;
timer_args->msg = timer_msg;
/*Convert subframes to usec time*/
usec_interval = 1000*comp_req->sf;
sec_interval = 0;
/*add seconds if required*/
if (usec_interval >= 1000*1000) {
sec_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, enb_agent_handle_timed_task,(void*) timer_args, &timer_id);
}
} }
break; break;
case PROTOCOL__PRP_STATS_REQUEST__BODY_CELL_STATS_REQUEST:; case PROTOCOL__PRP_STATS_REQUEST__BODY_CELL_STATS_REQUEST:;
...@@ -172,6 +201,132 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr ...@@ -172,6 +201,132 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
return err_code; return err_code;
} }
int enb_agent_mac_stats_request(mid_t mod_id,
xid_t xid,
const stats_request_config_t *report_config,
Protocol__ProgranMessage **msg) {
Protocol__PrpHeader *header;
int i;
if (prp_create_header(xid, PROTOCOL__PRP_TYPE__PRPT_STATS_REQUEST, &header) != 0)
goto error;
Protocol__PrpStatsRequest *stats_request_msg;
stats_request_msg = malloc(sizeof(Protocol__PrpStatsRequest));
if(stats_request_msg == NULL)
goto error;
protocol__prp_stats_request__init(stats_request_msg);
stats_request_msg->header = header;
stats_request_msg->type = report_config->report_type;
stats_request_msg->has_type = 1;
switch (report_config->report_type) {
case PROTOCOL__PRP_STATS_TYPE__PRST_COMPLETE_STATS:
stats_request_msg->body_case = PROTOCOL__PRP_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST;
Protocol__PrpCompleteStatsRequest *complete_stats;
complete_stats = malloc(sizeof(Protocol__PrpCompleteStatsRequest));
if(complete_stats == NULL)
goto error;
protocol__prp_complete_stats_request__init(complete_stats);
complete_stats->report_frequency = report_config->report_frequency;
complete_stats->has_report_frequency = 1;
complete_stats->sf = report_config->period;
complete_stats->has_sf = 1;
complete_stats->has_cell_report_flags = 1;
complete_stats->has_ue_report_flags = 1;
if (report_config->config->nr_cc > 0) {
complete_stats->cell_report_flags = report_config->config->cc_report_type[0].cc_report_flags;
}
if (report_config->config->nr_ue > 0) {
complete_stats->ue_report_flags = report_config->config->ue_report_type[0].ue_report_flags;
}
stats_request_msg->complete_stats_request = complete_stats;
break;
case PROTOCOL__PRP_STATS_TYPE__PRST_CELL_STATS:
stats_request_msg->body_case = PROTOCOL__PRP_STATS_REQUEST__BODY_CELL_STATS_REQUEST;
Protocol__PrpCellStatsRequest *cell_stats;
cell_stats = malloc(sizeof(Protocol__PrpCellStatsRequest));
if(cell_stats == NULL)
goto error;
protocol__prp_cell_stats_request__init(cell_stats);
cell_stats->n_cell = report_config->config->nr_cc;
cell_stats->has_flags = 1;
if (cell_stats->n_cell > 0) {
uint32_t *cells;
cells = (uint32_t *) malloc(sizeof(uint32_t)*cell_stats->n_cell);
for (i = 0; i < cell_stats->n_cell; i++) {
cells[i] = report_config->config->cc_report_type[i].cc_id;
}
cell_stats->cell = cells;
cell_stats->flags = report_config->config->cc_report_type[i].cc_report_flags;
}
stats_request_msg->cell_stats_request = cell_stats;
break;
case PROTOCOL__PRP_STATS_TYPE__PRST_UE_STATS:
stats_request_msg->body_case = PROTOCOL__PRP_STATS_REQUEST__BODY_UE_STATS_REQUEST;
Protocol__PrpUeStatsRequest *ue_stats;
ue_stats = malloc(sizeof(Protocol__PrpUeStatsRequest));
if(ue_stats == NULL)
goto error;
protocol__prp_ue_stats_request__init(ue_stats);
ue_stats->n_rnti = report_config->config->nr_ue;
ue_stats->has_flags = 1;
if (ue_stats->n_rnti > 0) {
uint32_t *ues;
ues = (uint32_t *) malloc(sizeof(uint32_t)*ue_stats->n_rnti);
for (i = 0; i < ue_stats->n_rnti; i++) {
ues[i] = report_config->config->ue_report_type[i].ue_rnti;
}
ue_stats->rnti = ues;
ue_stats->flags = report_config->config->ue_report_type[i].ue_report_flags;
}
stats_request_msg->ue_stats_request = ue_stats;
break;
default:
goto error;
}
*msg = malloc(sizeof(Protocol__ProgranMessage));
if(*msg == NULL)
goto error;
protocol__progran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__PROGRAN_MESSAGE__MSG_STATS_REQUEST_MSG;
(*msg)->msg_dir = PROTOCOL__PROGRAN_DIRECTION__INITIATING_MESSAGE;
(*msg)->stats_request_msg = stats_request_msg;
return 0;
error:
// TODO: Need to make proper error handling
if (header != NULL)
free(header);
if (stats_request_msg != NULL)
free(stats_request_msg);
if(*msg != NULL)
free(*msg);
//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int enb_agent_mac_destroy_stats_request(Protocol__ProgranMessage *msg) {
if(msg->msg_case != PROTOCOL__PROGRAN_MESSAGE__MSG_STATS_REQUEST_MSG)
goto error;
free(msg->stats_request_msg->header);
if (msg->stats_request_msg->body_case == PROTOCOL__PRP_STATS_REQUEST__BODY_CELL_STATS_REQUEST) {
free(msg->stats_request_msg->cell_stats_request->cell);
}
if (msg->stats_request_msg->body_case == PROTOCOL__PRP_STATS_REQUEST__BODY_UE_STATS_REQUEST) {
free(msg->stats_request_msg->ue_stats_request->rnti);
}
free(msg->stats_request_msg);
free(msg);
return 0;
error:
//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int enb_agent_mac_stats_reply(mid_t mod_id, int enb_agent_mac_stats_reply(mid_t mod_id,
xid_t xid, xid_t xid,
const report_config_t *report_config, const report_config_t *report_config,
......
...@@ -69,11 +69,24 @@ typedef struct { ...@@ -69,11 +69,24 @@ typedef struct {
cc_report_type_t *cc_report_type; cc_report_type_t *cc_report_type;
} report_config_t; } report_config_t;
typedef struct {
uint8_t report_type;
uint8_t report_frequency;
uint16_t period; /*In number of subframes*/
report_config_t *config;
} 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_destroy_stats_request(Protocol__ProgranMessage *msg);
int enb_agent_mac_stats_reply(mid_t mod_id, xid_t xid, const report_config_t *report_config, Protocol__ProgranMessage **msg); int enb_agent_mac_stats_reply(mid_t mod_id, xid_t xid, const report_config_t *report_config, Protocol__ProgranMessage **msg);
int enb_agent_mac_destroy_stats_reply(Protocol__ProgranMessage *msg); int enb_agent_mac_destroy_stats_reply(Protocol__ProgranMessage *msg);
#endif #endif
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