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 *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);
|
|||||||
*/
|
*/
|
||||||
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){
|
|||||||
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){
|
|||||||
|
|
||||||
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){
|
|||||||
* 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){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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) {
|
|||||||
|
|
||||||
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,
|
|||||||
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);
|
|||||||
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);
|
|||||||
|
|
||||||
|
|
||||||
/* 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 {
|
|||||||
|
|
||||||
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);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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");
|
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
|
|||||||
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
|
|||||||
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
|
|||||||
//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
|
|||||||
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
|
|||||||
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 {
|
|||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user