diff --git a/.gitignore b/.gitignore index d7126a6224..7b227ecca8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ log/ lte_build_oai/ targets/bin/ cmake_targets/nas_sim_tools/build/ + +# vscode +.vscode \ No newline at end of file diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h index f69186e4b8..09b3f2aab4 100644 --- a/openair2/COMMON/mac_messages_def.h +++ b/openair2/COMMON/mac_messages_def.h @@ -45,3 +45,6 @@ MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDat MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind) MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req) + +/* RRC configures DRX context (MAC timers) of a UE */ +MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req) \ No newline at end of file diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index 3bbea66d0d..e227296d05 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -29,6 +29,8 @@ #ifndef MAC_MESSAGES_TYPES_H_ #define MAC_MESSAGES_TYPES_H_ +#include + //-------------------------------------------------------------------------------------------// // Defines to access message fields. #define RRC_MAC_IN_SYNC_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_in_sync_ind @@ -48,6 +50,8 @@ #define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind #define RRC_MAC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req +#define RRC_MAC_DRX_CONFIG_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_drx_config_req + // Some constants from "LAYER2/MAC/defs.h" #define BCCH_SDU_SIZE (512) #define BCCH_SDU_MBMS_SIZE (512) @@ -145,4 +149,14 @@ typedef struct RrcMacPcchDataReq_s { uint8_t sdu[PCCH_SDU_SIZE]; uint8_t enb_index; } RrcMacPcchDataReq; + +/* RRC configures DRX context (MAC timers) of a UE */ +typedef struct rrc_mac_drx_config_req_s { + /* UE RNTI to configure */ + rnti_t rnti; + + /* DRX configuration from MacMainConfig to configure UE's local timers */ + LTE_DRX_Config_t * drx_Configuration; +} rrc_mac_drx_config_req_t; + #endif /* MAC_MESSAGES_TYPES_H_ */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 9692c084c1..1ee8383da9 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -387,7 +387,6 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - //RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate // In the configuration file it is in seconds. For RRC it has to be in milliseconds RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = (*ENBParamList.paramarray[i][ENB_RRC_INACTIVITY_THRES_IDX].uptr) * 1000; RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 19e06c8600..15ecfd2173 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -47,6 +47,8 @@ #include "common/ran_context.h" #include "rrc_eNB_UE_context.h" +#include "asn1_msg.h" +#include "intertask_interface.h" // undefine C_RNTI from // openair1/PHY/LTE_TRANSPORT/transport_common.h which @@ -398,11 +400,32 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, LTE_SRB_ToAddModList_t *SRB_configList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->srb_ToAddModList; LTE_DRB_ToReleaseList_t *DRB_ReleaseList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToReleaseList; LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + for (i = 0; i< 8; i++){ DRB2LCHAN[i] = 0; } - if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) + + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { + LOG_D(F1AP, "MAC Main Configuration is present\n"); + mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + + /* CDRX Configuration */ + if (mac_MainConfig->drx_Config == NULL) { + LOG_W(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); + } else { + MessageDef *message_p = NULL; + + /* Send DRX configuration to MAC task to configure timers of local UE context */ + message_p = itti_alloc_new_message(TASK_DU_F1, RRC_MAC_DRX_CONFIG_REQ); + RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = ctxt.rnti; + RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; + itti_send_msg_to_task(TASK_MAC_ENB, ctxt.module_id, message_p); + LOG_D(F1AP, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); + } + /* End of CDRX configuration */ + } + LTE_MeasGapConfig_t *measGapConfig = NULL; struct LTE_PhysicalConfigDedicated* physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated; rrc_rlc_config_asn1_req( @@ -602,7 +625,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } -int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) { +int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + const f1ap_ul_rrc_message_t *msg) { const rnti_t rnti = msg->rnti; F1AP_F1AP_PDU_t pdu; @@ -703,6 +727,25 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + LOG_I(F1AP, "[MSG] RRC UL rrcConnectionReconfigurationComplete\n"); + + /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ + int UE_id_mac = find_UE_id(instance, rnti); + + if (UE_id_mac == -1) { + LOG_E(F1AP, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); + break; + } + + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); + + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received + LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + } + /* End of CDRX processing */ + break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -710,14 +753,16 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: LOG_I(F1AP, "[MSG] RRC UL rrcConnectionSetupComplete \n"); - if(!ue_context_p){ + + if(!ue_context_p){ LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti); - }else { + + } else { LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti); ue_context_p->ue_context.Status = RRC_CONNECTED; } - break; + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: LOG_I(F1AP, "[MSG] RRC securityModeComplete \n"); break; diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index d287e1e5bf..566391ac7a 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) { &received_msg->ittiMsg.sctp_data_ind); break; - case F1AP_UL_RRC_MESSAGE: // from rrc + case F1AP_UL_RRC_MESSAGE: // to rrc LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), &F1AP_UL_RRC_MESSAGE(received_msg)); diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index b687a22909..7d1ea8e158 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1115,18 +1115,18 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, //----------------------------------------------------------------------------- /* -* Configure local DRX timers and thresholds following the drx_configuration input +* Configure local CDRX timers and thresholds following the drx_configuration input */ -void eNB_Config_Local_DRX( - module_id_t Mod_id, - rnti_t rnti, - LTE_DRX_Config_t *const drx_Configuration -) +void eNB_Config_Local_DRX(instance_t Mod_id, + rrc_mac_drx_config_req_t *rrc_mac_drx_config_req) //----------------------------------------------------------------------------- { UE_list_t *UE_list_mac = NULL; - int UE_id = -1; UE_sched_ctrl_t *UE_scheduling_control = NULL; + int UE_id = -1; + + rnti_t rnti = rrc_mac_drx_config_req->rnti; + LTE_DRX_Config_t *const drx_Configuration = rrc_mac_drx_config_req->drx_Configuration; UE_list_mac = &(RC.mac[Mod_id]->UE_list); @@ -1134,40 +1134,35 @@ void eNB_Config_Local_DRX( /* Check UE_id */ if (UE_id == -1) { - LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", - __FILE__, - __LINE__, - __FUNCTION__); + LOG_E(MAC, "[eNB_Config_Local_DRX] UE_id == -1\n"); return; } /* Get struct to modify */ UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]); + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { - LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; + LOG_W(MAC, "[eNB_Config_Local_DRX] drx_Configuration parameter is NULL, cannot configure local UE parameters for CDRX\n"); return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { - LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; + LOG_I(MAC, "[eNB_Config_Local_DRX] No drx_Configuration present, don't configure local UE parameters for CDRX\n"); return; } - /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when ACK is received - UE_scheduling_control->cdrx_waiting_ack = TRUE; // set to true first, waiting for the UE to configure CDRX on its side + /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when receiving RRC Reconfiguration Complete + UE_scheduling_control->cdrx_waiting_ack = TRUE; // waiting for RRC Reconfiguration Complete message UE_scheduling_control->in_active_time = FALSE; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; - switch (drx_Configuration->choice.setup.onDurationTimer) { + struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; + switch (choiceSetup->onDurationTimer) { case 0: UE_scheduling_control->on_duration_timer_thres = 1; break; @@ -1217,12 +1212,12 @@ void eNB_Config_Local_DRX( UE_scheduling_control->on_duration_timer_thres = 200; break; default: - LOG_E(MAC, "Error in local DRX configuration, the on duration timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the on duration timer value specified is unknown\n"); break; } UE_scheduling_control->drx_inactivity_timer = 0; - switch (drx_Configuration->choice.setup.drx_InactivityTimer) { + switch (choiceSetup->drx_InactivityTimer) { case 0: UE_scheduling_control->drx_inactivity_timer_thres = 1; break; @@ -1293,11 +1288,11 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_inactivity_timer_thres = 0; break; default: - LOG_E(MAC, "Error in local DRX configuration, the drx inactivity timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx inactivity timer value specified is unknown\n"); break; } - if (drx_Configuration->choice.setup.shortDRX == NULL) { + if (choiceSetup->shortDRX == NULL) { UE_scheduling_control->in_short_drx_cycle = FALSE; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; @@ -1305,8 +1300,8 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { UE_scheduling_control->in_short_drx_cycle = FALSE; - UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) drx_Configuration->choice.setup.shortDRX->drxShortCycleTimer; - switch (drx_Configuration->choice.setup.shortDRX->shortDRX_Cycle) { + UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; + switch (choiceSetup->shortDRX->shortDRX_Cycle) { case 0: UE_scheduling_control->short_drx_cycle_duration = 2; break; @@ -1356,7 +1351,7 @@ void eNB_Config_Local_DRX( UE_scheduling_control->short_drx_cycle_duration = 640; break; default: - LOG_E(MAC, "Error in local DRX configuration, the short drx timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the short drx timer value specified is unknown\n"); break; } @@ -1366,78 +1361,78 @@ void eNB_Config_Local_DRX( UE_scheduling_control->in_long_drx_cycle = FALSE; UE_scheduling_control->drx_longCycle_timer = 0; - switch (drx_Configuration->choice.setup.longDRX_CycleStartOffset.present) { + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: UE_scheduling_control->drx_longCycle_timer_thres = 10; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf10; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf10; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: UE_scheduling_control->drx_longCycle_timer_thres = 20; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf20; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf20; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: UE_scheduling_control->drx_longCycle_timer_thres = 32; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf32; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf32; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: UE_scheduling_control->drx_longCycle_timer_thres = 40; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf40; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf40; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: UE_scheduling_control->drx_longCycle_timer_thres = 64; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf64; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf64; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: UE_scheduling_control->drx_longCycle_timer_thres = 80; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf80; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf80; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: UE_scheduling_control->drx_longCycle_timer_thres = 128; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf128; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf128; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: UE_scheduling_control->drx_longCycle_timer_thres = 160; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf160; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf160; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: UE_scheduling_control->drx_longCycle_timer_thres = 256; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf256; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf256; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: UE_scheduling_control->drx_longCycle_timer_thres = 320; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf320; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf320; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: UE_scheduling_control->drx_longCycle_timer_thres = 512; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf512; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf512; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: UE_scheduling_control->drx_longCycle_timer_thres = 640; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf640; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf640; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: UE_scheduling_control->drx_longCycle_timer_thres = 1024; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1024; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1024; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: UE_scheduling_control->drx_longCycle_timer_thres = 1280; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1280; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1280; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: UE_scheduling_control->drx_longCycle_timer_thres = 2048; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2048; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2048; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: UE_scheduling_control->drx_longCycle_timer_thres = 2560; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2560; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560; break; default: - LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Invalid long_DRX value in DRX local configuration\n"); break; } memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer)); - switch (drx_Configuration->choice.setup.drx_RetransmissionTimer) { + switch (choiceSetup->drx_RetransmissionTimer) { case 0: memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; @@ -1463,7 +1458,7 @@ void eNB_Config_Local_DRX( memset(UE_scheduling_control->drx_retransmission_timer_thres, 33, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; default: - LOG_E(MAC, "Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); break; } } diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 4f6f9cd75b..132fc544d7 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -31,6 +31,7 @@ #include "LAYER2/MAC/mac.h" #include "PHY/defs_common.h" // for PRACH_RESOURCES_t and lte_subframe_t +#include "openair2/COMMON/mac_messages_types.h" /** \addtogroup _mac * @{ @@ -1338,9 +1339,13 @@ int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); /* DRX Configuration */ /* Configure local DRX timers and thresholds in UE context, following the drx_configuration input */ -void eNB_Config_Local_DRX(module_id_t Mod_id, rnti_t rnti, LTE_DRX_Config_t *drx_Configuration); +void eNB_Config_Local_DRX(instance_t Mod_id, rrc_mac_drx_config_req_t *rrc_mac_drx_config_req); /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); #endif /** @}*/ + +/* MAC ITTI messaging related functions */ +/* Main loop of MAC itti message handling */ +void *mac_enb_task(void *arg); \ No newline at end of file diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 8fb8d44e0a..64cb03774b 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -34,15 +34,12 @@ #include "mac_proto.h" #include "mac_extern.h" #include "assertions.h" -//#include "PHY_INTERFACE/phy_extern.h" -//#include "PHY/defs_eNB.h" -//#include "SCHED/sched_eNB.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "RRC/LTE/rrc_defs.h" #include "common/utils/LOG/log.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - #include "common/ran_context.h" +#include "intertask_interface.h" extern RAN_CONTEXT_t RC; @@ -223,3 +220,47 @@ int l2_init_eNB(void) return (1); } + +//----------------------------------------------------------------------------- +/* + * Main loop of MAC itti message handling + */ +void *mac_enb_task(void *arg) +//----------------------------------------------------------------------------- +{ + MessageDef *received_msg = NULL; + int result; + + itti_mark_task_ready(TASK_MAC_ENB); // void function 10/2019 + LOG_I(MAC,"Starting main loop of MAC message task\n"); + + while (1) { + itti_receive_msg(TASK_MAC_ENB, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case RRC_MAC_DRX_CONFIG_REQ: + LOG_I(MAC, "MAC Task Received RRC_MAC_DRX_CONFIG_REQ\n"); + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.rrc_mac_drx_config_req); + break; + + case TERMINATE_MESSAGE: + LOG_W(MAC, " *** Exiting MAC thread\n"); + itti_exit_task(); + break; + + default: + LOG_E(MAC, "MAC instance received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), + ITTI_MSG_NAME(received_msg)); + break; + } // end switch + + result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + received_msg = NULL; + } // end while + + return NULL; +} \ No newline at end of file diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index aea1ff61a1..4f5a6051aa 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -312,10 +312,8 @@ mac_rrc_data_ind( if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) { LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status); return (-1); - } else { - rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - } + } + rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 5d824debbe..cbd7baa422 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -621,36 +621,123 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, return((enc_rval.encoded+7)/8); } #endif + //----------------------------------------------------------------------------- /* * Generate the configuration structure for CDRX feature */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, - int CC_id, - RrcConfigurationReq *configuration, - LTE_UE_EUTRA_Capability_t *UEcap) +LTE_DRX_Config_t *do_DrxConfig(int CC_id, + RrcConfigurationReq *configuration, + LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { + /* Check CC id */ + if (CC_id >= MAX_NUM_CCs) { + LOG_E(RRC, "[do_DrxConfig] Invalid CC_id for DRX configuration\n"); + return NULL; + } + + /* No CDRX configuration */ + if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { + return NULL; + } + + /* CDRX not implemented for TDD */ + if (configuration->frame_type[CC_id] == 1) { + LOG_E(RRC, "[do_DrxConfig] CDRX not implemented for TDD\n"); + return NULL; + } + + /* Need UE capabilities */ + if (!UEcap) { + LOG_E(RRC,"[do_DrxConfig] No UEcap pointer\n"); + return NULL; + } + + /* Check the UE capabilities, CDRX not implemented for Coverage Extension */ + LTE_UE_EUTRA_Capability_v920_IEs_t *cap_920 = NULL; + LTE_UE_EUTRA_Capability_v940_IEs_t *cap_940 = NULL; + LTE_UE_EUTRA_Capability_v1020_IEs_t *cap_1020 = NULL; + LTE_UE_EUTRA_Capability_v1060_IEs_t *cap_1060 = NULL; + LTE_UE_EUTRA_Capability_v1090_IEs_t *cap_1090 = NULL; + LTE_UE_EUTRA_Capability_v1130_IEs_t *cap_1130 = NULL; + LTE_UE_EUTRA_Capability_v1170_IEs_t *cap_1170 = NULL; + LTE_UE_EUTRA_Capability_v1180_IEs_t *cap_1180 = NULL; + LTE_UE_EUTRA_Capability_v11a0_IEs_t *cap_11a0 = NULL; + LTE_UE_EUTRA_Capability_v1250_IEs_t *cap_1250 = NULL; + LTE_UE_EUTRA_Capability_v1260_IEs_t *cap_1260 = NULL; + LTE_UE_EUTRA_Capability_v1270_IEs_t *cap_1270 = NULL; + LTE_UE_EUTRA_Capability_v1280_IEs_t *cap_1280 = NULL; + LTE_UE_EUTRA_Capability_v1310_IEs_t *cap_1310 = NULL; + LTE_CE_Parameters_r13_t *CE_param = NULL; + long *ce_a_param = NULL; + + cap_920 = UEcap->nonCriticalExtension; + if (cap_920) { + cap_940 = cap_920->nonCriticalExtension; + if (cap_940) { + cap_1020 = cap_940->nonCriticalExtension; + if (cap_1020) { + cap_1060 = cap_1020->nonCriticalExtension; + if (cap_1060) { + cap_1090 = cap_1060->nonCriticalExtension; + if (cap_1090) { + cap_1130 = cap_1090->nonCriticalExtension; + if (cap_1130) { + cap_1170 = cap_1130->nonCriticalExtension; + if (cap_1170) { + cap_1180 = cap_1170->nonCriticalExtension; + if (cap_1180) { + cap_11a0 = cap_1180->nonCriticalExtension; + if (cap_11a0) { + cap_1250 = cap_11a0->nonCriticalExtension; + if (cap_1250) { + cap_1260 = cap_1250->nonCriticalExtension; + if (cap_1260) { + cap_1270 = cap_1260->nonCriticalExtension; + if (cap_1270) { + cap_1280 = cap_1270->nonCriticalExtension; + if (cap_1280) { + cap_1310 = cap_1280->nonCriticalExtension; + if (cap_1310) { + CE_param = cap_1310->ce_Parameters_r13; + if (CE_param) { + ce_a_param = CE_param->ce_ModeA_r13; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + if (ce_a_param) { + LOG_E(RRC,"[do_DrxConfig] Coverage Extension not supported by CDRX\n"); + return NULL; + } + LTE_DRX_Config_t *drxConfig = NULL; BIT_STRING_t *featureGroupIndicators = NULL; bool ueSupportCdrxShortFlag = false; bool ueSupportCdrxLongFlag = false; /* Check the UE capabilities for short and long CDRX cycles support */ - if (UEcap) { - featureGroupIndicators = UEcap->featureGroupIndicators; - if (featureGroupIndicators) { - if (featureGroupIndicators->size > 1 || (featureGroupIndicators->size == 1 && featureGroupIndicators->bits_unused < 4)) { - ueSupportCdrxShortFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x10) > 0); - ueSupportCdrxLongFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x08) > 0); - LOG_I(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); - } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); - } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); - } else LOG_W(RRC,"[do_DrxConfig] No UEcap pointer\n"); - - if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { - return NULL; - } + featureGroupIndicators = UEcap->featureGroupIndicators; + if (featureGroupIndicators) { + if (featureGroupIndicators->size > 1 || (featureGroupIndicators->size == 1 && featureGroupIndicators->bits_unused < 4)) { + ueSupportCdrxShortFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x10) > 0); + ueSupportCdrxLongFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x08) > 0); + LOG_D(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); + } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); + } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); drxConfig = (LTE_DRX_Config_t *) malloc(sizeof(LTE_DRX_Config_t)); if (drxConfig == NULL) return NULL; @@ -666,58 +753,59 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, if (drxConfig->present == LTE_DRX_Config_PR_release) { drxConfig->choice.release = (NULL_t) 0; } else { - drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - drxConfig->choice.setup.drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; - drxConfig->choice.setup.drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; - drxConfig->choice.setup.longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; - switch (drxConfig->choice.setup.longDRX_CycleStartOffset.present) { + struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; + choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; + choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; + choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; default: break; @@ -725,12 +813,12 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, /* Short DRX cycle configuration */ if (!ueSupportCdrxShortFlag || configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer == 0) { - drxConfig->choice.setup.shortDRX = NULL; + choiceSetup->shortDRX = NULL; } else { - drxConfig->choice.setup.shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); - memset(drxConfig->choice.setup.shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); - drxConfig->choice.setup.shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; - drxConfig->choice.setup.shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; + choiceSetup->shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); + memset(choiceSetup->shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); + choiceSetup->shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; + choiceSetup->shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 7ddf939e6d..29e2e8e389 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -81,12 +81,11 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFNSubframes, uint32_t frame); /** \brief Generate configuration structure for DRX_Config -@param Mod_id Instance of eNB @param CC_id Id of component to configure @param configuration Pointer Configuration Request structure @param UEcap Pointer Configuration UE capablities @return DRX_Config structure pointer or NULL => error */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); +LTE_DRX_Config_t *do_DrxConfig(int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); /** \brief Generate configuration for SIB1 (eNB). diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 5ce317a225..b5050e6bd2 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -2968,6 +2968,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; + MessageDef *message_p = NULL; /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */ eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; @@ -3201,46 +3202,29 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf500; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_infinity mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB - - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX Configuration */ - // Need to check if UE is a BR UE - rnti_t rnti = ue_context_pP->ue_id_rnti; - module_id_t module_id = ctxt_pP->module_id; - int UE_id = find_UE_id(module_id, rnti); - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); - - if (UE_id != -1) { - if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && - (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); - - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - - } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - mac_MainConfig->drx_Config = NULL; - } - } else { // UE_id invalid - LOG_E(RRC, "Invalid UE_id found!\n"); - mac_MainConfig->drx_Config = NULL; + + /* CDRX Configuration */ + mac_MainConfig->drx_Config = NULL; + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ + if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + + if (mac_MainConfig->drx_Config == NULL) { + LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); + } else { + /* Send DRX configuration to MAC task to configure timers of local UE context */ + message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_MAC_DRX_CONFIG_REQ); + RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = rnti; + RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; + itti_send_msg_to_task(TASK_MAC_ENB, module_id, message_p); + LOG_D(RRC, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); } - } else { // No CDRX with the CU/DU split in this version - LOG_E(RRC, "CU/DU split activated\n"); - mac_MainConfig->drx_Config = NULL; } + /* End of CDRX configuration */ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -3701,6 +3685,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; + MessageDef *message_p = NULL; /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */ eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; @@ -3752,8 +3737,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LTE_C_RNTI_t *cba_RNTI = NULL; int measurements_enabled; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, - uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; - LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; #ifdef CBA // Contention Based Access uint8_t *cba_RNTI_buf; @@ -3934,45 +3917,30 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX Configuration */ - // Need to check if UE is a BR UE - rnti_t rnti = ue_context_pP->ue_id_rnti; - module_id_t module_id = ctxt_pP->module_id; - int UE_id = find_UE_id(module_id, rnti); - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); - - if (UE_id != -1) { - if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && - (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); - - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - - } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - mac_MainConfig->drx_Config = NULL; - } - } else { // UE_id invalid - LOG_E(RRC, "Invalid UE_id found!\n"); - mac_MainConfig->drx_Config = NULL; + /* CDRX Configuration */ + mac_MainConfig->drx_Config = NULL; + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; + uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ + if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + + if (mac_MainConfig->drx_Config == NULL) { + LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); + } else { + /* Send DRX configuration to MAC task to configure timers of local UE context */ + message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_MAC_DRX_CONFIG_REQ); + RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = rnti; + RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; + itti_send_msg_to_task(TASK_MAC_ENB, module_id, message_p); + LOG_D(RRC, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); } - } else { // No CDRX with the CU/DU split in this version - LOG_E(RRC, "CU/DU split activated\n"); - mac_MainConfig->drx_Config = NULL; } + /* End of CDRX configuration */ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -6489,25 +6457,31 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; LTE_DRB_Identity_t *drb_id_p = NULL; - + ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX: activated if ack was expected */ - int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); - if (UE_id_mac == -1){ - LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n",PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ue_context_pP->ue_context.rnti); + /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; + + if (NODE_IS_MONOLITHIC(RC.rrc[module_id]->node_type)) { + int UE_id_mac = find_UE_id(module_id, rnti); + + if (UE_id_mac == -1) { + LOG_E(RRC, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); return; } - UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); + + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; + UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is received LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } - } // No CDRX with the CU/DU split in this version of the code + } + /* End of CDRX processing */ T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), @@ -6692,16 +6666,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif - ); - } + ); + } } else { // remove LCHAN from MAC/PHY if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB @@ -6710,11 +6684,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_req(ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - DRB2LCHAN[i], - Rlc_info_um); + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + DRB2LCHAN[i], + Rlc_info_um); } } @@ -6766,13 +6740,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index cfc2bc2215..cbbd30b62c 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -26,11 +26,11 @@ # include "common/ran_context.h" #ifdef OPENAIR2 - #include "sctp_eNB_task.h" - #include "x2ap_eNB.h" - #include "s1ap_eNB.h" - #include "udp_eNB_task.h" - #include "gtpv1u_eNB_task.h" + #include "sctp_eNB_task.h" + #include "x2ap_eNB.h" + #include "s1ap_eNB.h" + #include "udp_eNB_task.h" + #include "gtpv1u_eNB_task.h" #if ENABLE_RAL #include "lteRALue.h" #include "lteRALenb.h" @@ -40,6 +40,7 @@ # include "f1ap_cu_task.h" # include "f1ap_du_task.h" # include "enb_app.h" +# include "openair2/LAYER2/MAC/mac_proto.h" extern RAN_CONTEXT_t RC; @@ -63,7 +64,6 @@ int create_tasks(uint32_t enb_nb) { AssertFatal(rc >= 0, "Create task for SCTP failed\n"); } - if (EPC_MODE_ENABLED && !NODE_IS_DU(type)) { rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL); AssertFatal(rc >= 0, "Create task for S1AP failed\n"); @@ -91,5 +91,11 @@ int create_tasks(uint32_t enb_nb) { AssertFatal(rc >= 0, "Create task for DU F1AP failed\n"); } + if (!NODE_IS_CU(type)) { + LOG_I(MAC,"Creating MAC eNB Task\n"); + rc = itti_create_task(TASK_MAC_ENB, mac_enb_task, NULL); + AssertFatal(rc >= 0, "Create task for MAC eNB failed\n"); + } + return 0; }