diff --git a/openair2/ENB_APP/enb_agent_handler.c b/openair2/ENB_APP/enb_agent_handler.c
index dd39a7315a233f59d2901ffaca282342b873622c..9a37d01fc1661750d610150f299678c292fc6176 100644
--- a/openair2/ENB_APP/enb_agent_handler.c
+++ b/openair2/ENB_APP/enb_agent_handler.c
@@ -45,7 +45,7 @@ enb_agent_message_decoded_callback messages_callback[][3] = {
   {enb_agent_hello, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_HELLO_MSG*/
   {enb_agent_echo_reply, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_ECHO_REQUEST_MSG*/
   {0, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_ECHO_REPLY_MSG*/ //Must add handler when receiving echo reply
-  {enb_agent_mac_reply, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/
+  {enb_agent_mac_handle_stats, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/
   {0,0,0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_STATS_REPLY_MSG*/
 
 };
diff --git a/openair2/ENB_APP/enb_agent_mac.c b/openair2/ENB_APP/enb_agent_mac.c
index 4b299ca919c906a8f89f0427cd8e19467148d9b7..e1c465105a63b13d8b183534bda8d9afa3136d1f 100644
--- a/openair2/ENB_APP/enb_agent_mac.c
+++ b/openair2/ENB_APP/enb_agent_mac.c
@@ -40,71 +40,127 @@
 #include "LAYER2/RLC/rlc.h"
 #include "log.h"
 
-int enb_agent_mac_reply(uint32_t xid, const void *params, Protocol__ProgranMessage **msg){
+int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__ProgranMessage **msg){
   
+  // TODO: Must deal with sanitization of input
+  // TODO: Must check if RNTIs and cell ids of the request actually exist
+
+  int i;
   void *buffer;
   int size;
   err_code_t err_code;
-  // test code 
+  
+  //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 
+  int cc_id = 0;
+  int enb_id = 0;
 
+  eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id];
+  UE_list_t *eNB_UE_list= &eNB->UE_list;
 
-  // Create and serialize a stats reply message. This would be done by one of the agents
-  // Let's assume that we want the power headroom, the pending CEs for UEs 1 & 2 and their
-  // DL CQI reports as well as the noise and interference for cell 1
   report_config_t report_config;
 
-  // We set the flags indicating what kind of stats we need for each UE. Both UEs will have
-  // the same flags in this example
   uint32_t ue_flags = 0;
-  // Set the power headroom flag
-  ue_flags |= PROTOCOL__PRP_UE_STATS_TYPE__PRUST_PRH;
-  // Set the pending CEs flag
-  ue_flags |= PROTOCOL__PRP_UE_STATS_TYPE__PRUST_MAC_CE_BS;
-  // Set the DL CQI report flag
-  ue_flags |= PROTOCOL__PRP_UE_STATS_TYPE__PRUST_DL_CQI;
-
-  // We do the same with the Cell flags
   uint32_t c_flags = 0;
-  // Set the noise and interference flag
-  c_flags |= PROTOCOL__PRP_CELL_STATS_TYPE__PRCST_NOISE_INTERFERENCE;
-
-  // We create the appropriate configurations
-  ue_report_type_t ue_configs[2];
-  cc_report_type_t cell_configs[1];
-
-  // Create the config for UE with RNTI 1
-  ue_report_type_t ue1_config;
-  ue1_config.ue_rnti = 1;
-  ue1_config.ue_report_flags = ue_flags;
-
-  // Do the same for UE with RNTI 2
-  ue_report_type_t ue2_config;
-  ue2_config.ue_rnti = 2;
-  ue2_config.ue_report_flags = ue_flags;
-
-  // Add them to the UE list
-  ue_configs[0] = ue1_config;
-  ue_configs[1] = ue2_config;
-  
-  // Do the same for cell with id 1  
-  cc_report_type_t c1_config;
-  c1_config.cc_id = 1;
-  c1_config.cc_report_flags = c_flags;
 
-  // Add them to the cell list
-  cell_configs[0] = c1_config;
-
-  //Create the full report configuration
-  report_config.nr_ue = 2;
-  report_config.nr_cc = 1;
-  report_config.ue_report_type = ue_configs;
-  report_config.cc_report_type = cell_configs;
+  Protocol__ProgranMessage *input = (Protocol__ProgranMessage *)params;
+
+  Protocol__PrpStatsRequest *stats_req = input->stats_request_msg;
+
+  // Check the type of request that is made
+  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
+      return -1;
+    } else if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_CONTINUOUS) {
+      //TODO: Must create an event based report mechanism
+      return -1;
+    } else if (comp_req->report_frequency == PROTOCOL__PRP_STATS_REPORT_FREQ__PRSRF_OFF) {
+      //TODO: Must implement to deactivate the event based reporting
+    } else { //One-off reporting
+      //Set the proper flags
+      ue_flags = comp_req->ue_report_flags;
+      c_flags = comp_req->cell_report_flags;
+      //Create a list of all eNB RNTIs and cells
+      
+      //Set the number of UEs and create list with their RNTIs stats configs
+      report_config.nr_ue = eNB_UE_list->num_UEs;
+      report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
+      if (report_config.ue_report_type == NULL) {
+	// TODO: Add appropriate error code
+	err_code = -100;
+	goto error;
+      }
+      for (i = 0; i < report_config.nr_ue; i++) {
+	report_config.ue_report_type[i].ue_rnti = eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti;
+	report_config.ue_report_type[i].ue_report_flags = ue_flags;
+      }
+      //Set the number of CCs and create a list with the cell stats configs
+      report_config.nr_cc = MAX_NUM_CCs;
+      report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
+      if (report_config.cc_report_type == NULL) {
+	// TODO: Add appropriate error code
+	err_code = -100;
+	goto error;
+      }
+      for (i = 0; i < report_config.nr_cc; i++) {
+	//TODO: Must fill in the proper cell ids
+	report_config.cc_report_type[i].cc_id = i;
+	report_config.cc_report_type[i].cc_report_flags = c_flags;
+      }
+    }
+    break;
+  case PROTOCOL__PRP_STATS_REQUEST__BODY_CELL_STATS_REQUEST:;
+    Protocol__PrpCellStatsRequest *cell_req = stats_req->cell_stats_request;
+    // UE report config will be blank
+    report_config.nr_ue = 0;
+    report_config.ue_report_type = NULL;
+    report_config.nr_cc = cell_req->n_cell;
+    report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
+    if (report_config.cc_report_type == NULL) {
+      // TODO: Add appropriate error code
+      err_code = -100;
+      goto error;
+    }
+    for (i = 0; i < report_config.nr_cc; i++) {
+	//TODO: Must fill in the proper cell ids
+      report_config.cc_report_type[i].cc_id = cell_req->cell[i];
+      report_config.cc_report_type[i].cc_report_flags = cell_req->flags;
+    }
+    break;
+  case PROTOCOL__PRP_STATS_REQUEST__BODY_UE_STATS_REQUEST:;
+    Protocol__PrpUeStatsRequest *ue_req = stats_req->ue_stats_request;
+    // Cell report config will be blank
+    report_config.nr_cc = 0;
+    report_config.cc_report_type = NULL;
+    report_config.nr_ue = ue_req->n_rnti;
+    report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
+    if (report_config.ue_report_type == NULL) {
+      // TODO: Add appropriate error code
+      err_code = -100;
+      goto error;
+    }
+    for (i = 0; i < report_config.nr_ue; i++) {
+      report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i];
+      report_config.ue_report_type[i].ue_report_flags = ue_req->flags;
+    }
+    break;
+  default:
+    //TODO: Add appropriate error code
+    err_code = -100;
+    goto error;
+  }
 
   if (enb_agent_mac_stats_reply(xid, &report_config, msg) < 0 ){
     err_code = PROTOCOL__PROGRAN_ERR__MSG_BUILD;
     goto error;
   }
 
+  free(report_config.ue_report_type);
+  free(report_config.cc_report_type);
+
   return 0;
 
  error :
diff --git a/openair2/ENB_APP/enb_agent_mac.h b/openair2/ENB_APP/enb_agent_mac.h
index 590570630e7f623507f2d75a2a0f7948ce355d93..e22253cf2784bfe36b215f3724766d7159ee105c 100644
--- a/openair2/ENB_APP/enb_agent_mac.h
+++ b/openair2/ENB_APP/enb_agent_mac.h
@@ -68,7 +68,7 @@ typedef struct {
 } report_config_t;
 
 
-int enb_agent_mac_reply(uint32_t xid, const void *params, Protocol__ProgranMessage **msg);
+int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__ProgranMessage **msg);
 
 int enb_agent_mac_stats_reply(uint32_t xid, const report_config_t *report_config, Protocol__ProgranMessage **msg);