Integrated timer to work with periodic report messages and agent tasks
This commit is contained in:
@@ -53,7 +53,7 @@ static uint16_t in_port;
|
||||
void *send_thread(void *args);
|
||||
void *receive_thread(void *args);
|
||||
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
|
||||
@@ -61,6 +61,13 @@ err_code_t enb_agent_timeout(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;
|
||||
const char *msg_name = NULL;
|
||||
instance_t instance;
|
||||
@@ -86,7 +93,15 @@ void *enb_agent_task(void *args){
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
@@ -96,46 +111,49 @@ void *enb_agent_task(void *args){
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
|
||||
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);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *send_thread(void *args) {
|
||||
/* void *send_thread(void *args) { */
|
||||
|
||||
#ifdef TEST_TIMER
|
||||
/* #ifdef TEST_TIMER */
|
||||
|
||||
msg_context_t *d = args;
|
||||
void *data;
|
||||
int size;
|
||||
int priority;
|
||||
/* msg_context_t *d = args; */
|
||||
/* void *data; */
|
||||
/* int size; */
|
||||
/* int priority; */
|
||||
|
||||
struct timeval t1, t2;
|
||||
long long t;
|
||||
struct timespec ts;
|
||||
unsigned int delay = 250*1000;
|
||||
while(1) {
|
||||
gettimeofday(&t1, NULL);
|
||||
enb_agent_sleep_until(&ts, delay);
|
||||
gettimeofday(&t2, NULL);
|
||||
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);
|
||||
sleep(1);
|
||||
}
|
||||
/* struct timeval t1, t2; */
|
||||
/* long long t; */
|
||||
/* struct timespec ts; */
|
||||
/* unsigned int delay = 250*1000; */
|
||||
/* while(1) { */
|
||||
/* gettimeofday(&t1, NULL); */
|
||||
/* enb_agent_sleep_until(&ts, delay); */
|
||||
/* gettimeofday(&t2, NULL); */
|
||||
/* 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); */
|
||||
/* sleep(1); */
|
||||
/* } */
|
||||
|
||||
#endif
|
||||
/* while (1) {
|
||||
// need logic for the timer, and
|
||||
usleep(10);
|
||||
if (message_put(d->tx_mq, data, size, priority)) goto error;
|
||||
}*/
|
||||
/* #endif */
|
||||
/* /\* while (1) { */
|
||||
/* // need logic for the timer, and */
|
||||
/* usleep(10); */
|
||||
/* if (message_put(d->tx_mq, data, size, priority)) goto error; */
|
||||
/* }*\/ */
|
||||
|
||||
return NULL;
|
||||
/* return NULL; */
|
||||
|
||||
error:
|
||||
printf("receive_thread: there was an error\n");
|
||||
return NULL;
|
||||
}
|
||||
/* error: */
|
||||
/* printf("receive_thread: there was an error\n"); */
|
||||
/* return NULL; */
|
||||
/* } */
|
||||
|
||||
void *receive_thread(void *args) {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_TIMER
|
||||
//#ifdef TEST_TIMER
|
||||
long timer_id=0;
|
||||
enb_agent_timer_args_t timer_args;
|
||||
memset (&timer_args, 0, sizeof(enb_agent_timer_args_t));
|
||||
timer_args.mod_id = mod_id;
|
||||
timer_args.cc_actions= ENB_AGENT_ACTION_APPLY;
|
||||
timer_args.cc_report_flags = PROTOCOL__PRP_CELL_STATS_TYPE__PRCST_NOISE_INTERFERENCE;
|
||||
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.cc_actions= ENB_AGENT_ACTION_APPLY;
|
||||
//timer_args.cc_report_flags = PROTOCOL__PRP_CELL_STATS_TYPE__PRCST_NOISE_INTERFERENCE;
|
||||
//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;
|
||||
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();
|
||||
|
||||
@@ -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));
|
||||
//memcpy (timer_args, args, sizeof(*timer_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 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, "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);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ uint16_t get_sfn_sf (mid_t mod_id) {
|
||||
|
||||
frame = (uint16_t) get_current_frame(mod_id);
|
||||
subframe = (uint16_t) get_current_subframe(mod_id);
|
||||
sfn_sf = (frame << 12) | subframe;
|
||||
sfn_sf = (subframe << 12) | frame;
|
||||
return sfn_sf;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ Protocol__ProgranMessage* enb_agent_handle_message (mid_t mod_id,
|
||||
uint8_t *data,
|
||||
uint32_t size);
|
||||
|
||||
Protocol__ProgranMessage *enb_agent_handle_timed_task(void *args);
|
||||
|
||||
void * enb_agent_send_message(Protocol__ProgranMessage *msg,
|
||||
uint32_t * size);
|
||||
|
||||
@@ -107,7 +109,7 @@ int get_current_frame(mid_t mod_id);
|
||||
int get_current_subframe(mid_t mod_id);
|
||||
|
||||
/*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);
|
||||
|
||||
int get_num_ues(mid_t mod_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 */
|
||||
typedef err_code_t (*enb_agent_timer_callback_t)(void*);
|
||||
typedef Protocol__ProgranMessage *(*enb_agent_timer_callback_t)(void*);
|
||||
|
||||
typedef enum {
|
||||
/* oneshot timer: */
|
||||
@@ -169,13 +171,7 @@ typedef enum {
|
||||
|
||||
typedef struct enb_agent_timer_args_s{
|
||||
mid_t mod_id;
|
||||
|
||||
agent_action_t cc_actions;
|
||||
uint32_t cc_report_flags;
|
||||
|
||||
agent_action_t ue_actions;
|
||||
uint32_t ue_report_flags;
|
||||
|
||||
Protocol__ProgranMessage *msg;
|
||||
} enb_agent_timer_args_t;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -133,11 +133,28 @@ void * enb_agent_send_message(Protocol__ProgranMessage *msg,
|
||||
error :
|
||||
LOG_E(ENB_AGENT,"errno %d occured\n",err_code);
|
||||
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err_code_t enb_agent_process_timeout(long timer_id, void* timer_args){
|
||||
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;
|
||||
}
|
||||
|
||||
Protocol__ProgranMessage* enb_agent_process_timeout(long timer_id, void* timer_args){
|
||||
|
||||
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){
|
||||
LOG_W(ENB_AGENT,"null timer args\n");
|
||||
|
||||
return found->cb(timer_args);
|
||||
|
||||
|
||||
error:
|
||||
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
|
||||
int size;
|
||||
err_code_t err_code;
|
||||
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
|
||||
int cc_id = 0;
|
||||
@@ -70,12 +71,13 @@ int enb_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__Progr
|
||||
switch(stats_req->body_case) {
|
||||
case PROTOCOL__PRP_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ;
|
||||
Protocol__PrpCompleteStatsRequest *comp_req = stats_req->complete_stats_request;
|
||||
if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_PERIODICAL) {
|
||||
//TODO: Must create a periodic report. Implement once the
|
||||
// timer functionality is supported
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
} else if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) {
|
||||
/* if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_PERIODICAL) { */
|
||||
/* //TODO: Must create a periodic report. Implement once the */
|
||||
/* // timer functionality is supported */
|
||||
/* *msg = NULL; */
|
||||
/* return 0; */
|
||||
/* } else */
|
||||
if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) {
|
||||
//TODO: Must create an event based report mechanism
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
@@ -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
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
} else { //One-off reporting
|
||||
} else { //One-off or periodical reporting
|
||||
//Set the proper flags
|
||||
ue_flags = comp_req->ue_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
|
||||
report_config.cc_report_type[i].cc_id = i;
|
||||
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;
|
||||
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
|
||||
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,
|
||||
xid_t xid,
|
||||
const report_config_t *report_config,
|
||||
|
||||
@@ -69,11 +69,24 @@ typedef struct {
|
||||
cc_report_type_t *cc_report_type;
|
||||
} 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_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_destroy_stats_reply(Protocol__ProgranMessage *msg);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user