diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 1fc3114754..370697660e 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -37,7 +37,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 115; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -183,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 2ef30ea4c2..fbbc2f1154 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -183,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); @@ -204,7 +204,7 @@ RUs = ( att_rx = 0; bands = [38]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 125; eNB_instances = [0]; } diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index fbbade22f3..f49d860a51 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -37,7 +37,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -183,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); @@ -204,7 +204,7 @@ RUs = ( att_rx = 0; bands = [38]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 120; eNB_instances = [0]; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 87beafad6b..92a6e6f0bc 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -94,6 +94,14 @@ eNBs = pcch_default_PagingCycle = 128; pcch_nB = "oneT"; + drx_Config_present = "prSetup"; //"prSetup" "prRelease" + drx_onDurationTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100 + drx_InactivityTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100,200,300,500,750,1280,1920,2560 + drx_RetransmissionTimer = "psf1"; // "psfX": X=1,2,4,6,8,16,24,33 + drx_longDrx_CycleStartOffset_present = "prSf128"; // "psfX": X=10,20,32,40,64,80,128,160,256,320,512,640,1024,1280,2048,2560 + drx_longDrx_CycleStartOffset = 0; // X >= 0 && X < drx_longDrx_CycleStartOffset_present + drx_shortDrx_Cycle = "sf16"; // "sfX": X=2,5,8,10,16,20,32,40,64,80,128,160,256,320,512,640 + drx_shortDrx_ShortCycleTimer = 3; // 1..16 integer. Total duration in short cycle = drx_shortDrx_Cycle*drx_shortDrx_ShortCycleTimer [subframe] bcch_modificationPeriodCoeff = 2; ue_TimersAndConstants_t300 = 1000; ue_TimersAndConstants_t301 = 1000; diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 9846dabc0f..d45f0d5c57 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -2137,6 +2137,7 @@ class SSHConnection(): uciStatMsgCount = 0 pdcpFailure = 0 ulschFailure = 0 + cdrxActivationMessageCount = 0 self.htmleNBFailureMsg = '' for line in enb_log_file.readlines(): if self.rruOptions != '': @@ -2188,6 +2189,9 @@ class SSHConnection(): result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) if result is not None: rrcReestablishReject += 1 + result = re.search('CDRX configuration activated after RRC Connection', str(line)) + if result is not None: + cdrxActivationMessageCount += 1 result = re.search('uci->stat', str(line)) if result is not None: uciStatMsgCount += 1 @@ -2242,6 +2246,10 @@ class SSHConnection(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' + if cdrxActivationMessageCount > 0: + rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' if rachCanceledProcedure > 0: rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml index d5a25c7fa7..6ac6dc980a 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml @@ -26,7 +26,7 @@ tasks 040101 - 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 + 030104 040301 040501 040602 040601 040603 040604 040605 040642 040641 040643 040644 040645 040401 040201 030201 @@ -92,6 +92,21 @@ unbalanced + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec) + -t 30 -i 1 -fm + 50 + + Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) @@ -116,4 +131,19 @@ unbalanced + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec) + -t 30 -i 1 -fm -R + 50 + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml index ef50933d4a..c5e4321b89 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml @@ -26,7 +26,7 @@ tasks 040101 - 030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201 + 030114 040301 040511 040612 040611 040613 040614 040615 040652 040651 040653 040654 040655 040401 040201 030201 @@ -92,6 +92,21 @@ unbalanced + + Iperf + iperf (10MHz - DL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (10MHz - DL/TCP)(30 sec) + -t 30 -i 1 -fm + 50 + + Iperf iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) @@ -116,4 +131,19 @@ unbalanced + + Iperf + iperf (10MHz - UL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/TCP)(30 sec) + -t 30 -i 1 -fm -R + 50 + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml index 9a96baac3f..2dc1efd994 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml @@ -26,7 +26,7 @@ tasks 040101 - 030124 040301 040521 040622 040621 040623 040662 040661 040663 040401 040201 030201 + 030124 040301 040521 040622 040621 040623 040624 040625 040662 040661 040663 040664 040665 040401 040201 030201 @@ -92,6 +92,21 @@ unbalanced + + Iperf + iperf (20MHz - DL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (20MHz - DL/TCP)(30 sec) + -t 30 -i 1 -fm + 50 + + Iperf iperf (20MHz - UL/2Mbps/UDP)(30 sec)(balanced) @@ -116,4 +131,19 @@ unbalanced + + Iperf + iperf (20MHz - UL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/TCP)(30 sec) + -t 30 -i 1 -fm -R + 50 + + diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 666bf46d44..2b18e75806 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -189,7 +189,15 @@ const char* eurecomVariablesNames[] = { "ue0_trx_write_ns_missing", "enb_thread_rxtx_CPUID", "ru_thread_CPUID", - "ru_thread_tx_CPUID" + "ru_thread_tx_CPUID", + "ue0_on_duration_timer", + "ue0_drx_inactivity", + "ue0_drx_short_cycle", + "ue0_short_drx_cycle_number", + "ue0_drx_long_cycle", + "ue0_drx_retransmission_harq0", + "ue0_drx_active_time", + "ue0_drx_active_time_condition" }; const char* eurecomFunctionsNames[] = { diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 749978bb48..cb98da3e82 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -167,6 +167,14 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX, VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD, VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX, + VCD_SIGNAL_DUMPER_VARIABLES_ON_DURATION_TIMER, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_SHORT_CYCLE, + VCD_SIGNAL_DUMPER_VARIABLES_SHORT_DRX_CYCLE_NUMBER, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_LONG_CYCLE, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME_CONDITION, VCD_SIGNAL_DUMPER_VARIABLES_END } vcd_signal_dump_variables; diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 83a380662d..908a94f532 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ typedef struct { #define VCD_NUM_FUNCTIONS 190 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES 128 +#define VCD_NUM_VARIABLES 136 /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 1dbfe64a2a..3e3b5052e1 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1676,6 +1676,46 @@ ID = VCD_VARIABLE_CPUID_RU_THREAD_TX GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value VCD_NAME = ru_thread_tx_CPUID +ID = VCD_VARIABLE_ON_DURATION_TIMER + DESC = VCD variable ON_DURATION_TIMER + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_on_duration_timer +ID = VCD_VARIABLE_DRX_INACTIVITY + DESC = VCD variable DRX_INACTIVITY + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_inactivity +ID = VCD_VARIABLE_DRX_SHORT_CYCLE + DESC = VCD variable DRX_SHORT_CYCLE + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_short_cycle +ID = VCD_VARIABLE_SHORT_DRX_CYCLE_NUMBER + DESC = VCD variable SHORT_DRX_CYCLE_NUMBER + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_short_drx_cycle_number +ID = VCD_VARIABLE_DRX_LONG_CYCLE + DESC = VCD variable DRX_LONG_CYCLE + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_long_cycle +ID = VCD_VARIABLE_DRX_RETRANSMISSION_HARQ0 + DESC = VCD variable DRX_RETRANSMISSION_HARQ0 + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_retransmission_harq0 +ID = VCD_VARIABLE_DRX_ACTIVE_TIME + DESC = VCD variable DRX_ACTIVE_TIME + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_active_time +ID = VCD_VARIABLE_DRX_ACTIVE_TIME_CONDITION + DESC = VCD variable DRX_ACTIVE_TIME_CONDITION + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_active_time_condition #functions diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 7e2cc30388..bf50be357a 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -72,6 +72,7 @@ The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support - RLC interface (AM, UM) - UL power control - Link adaptation +- Connected DRX (CDRX) support for FDD LTE UE. Compatible with R13 from 3GPP. Support for Cat-M1 UE comming soon. ## eNB RLC Layer ## diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index f1b5c356c7..0df94e55e5 100644 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -115,10 +115,10 @@ void init_mpdcch5ss1tab_normal_regular_subframe_evenNRBDL(PHY_VARS_eNB * eNB) for (k = 0; k < 72; k++) { kmod = k % 12; if (((l != 5) && (l != 6) && (l != 12) && (l != 13)) || (kmod == 2) || (kmod == 3) || (kmod == 4) || (kmod == 7) || (kmod == 8) || (kmod == 9)) { - mpdcch5ss1tab[re] = (l * eNB->frame_parms.ofdm_symbol_size) + k; - re++; + mpdcch5ss1tab[re] = (l * eNB->frame_parms.ofdm_symbol_size) + k; + re++; } else if ((kmod == 0) || (kmod == 5) || (kmod == 10)) { - mpdcch5ss1tab[re++] = (l * eNB->frame_parms.ofdm_symbol_size) + k; + mpdcch5ss1tab[re++] = (l * eNB->frame_parms.ofdm_symbol_size) + k; } } } diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index f9eee10b2a..676d753ab5 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -722,17 +722,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,uint8_t br_flag #endif - ) +) +//----------------------------------------------------------------------------- { - - - static int first_call=1; - LTE_eNB_COMMON *common_vars = &eNB->common_vars; - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; - // PUCCH_CONFIG_DEDICATED *pucch_config_dedicated = &eNB->pucch_config_dedicated[UE_id]; - - int8_t sigma2_dB = max(eNB->measurements.n0_subband_power_tot_dB[0], - eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]); + static int first_call = 1; + LTE_eNB_COMMON *common_vars = &eNB->common_vars; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + int8_t sigma2_dB = max(eNB->measurements.n0_subband_power_tot_dB[0], eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]); uint32_t u,v,n,aa; uint32_t z[12*14]; @@ -770,7 +766,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, uint16_t Ret = 0; int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] - double delta_theta[NB_ANTENNAS_RX][12]; //[Antenna][Subcarrier][Complex] + double delta_theta[NB_ANTENNAS_RX][12]; //[Antenna][Subcarrier][Complex] int16_t ChestValue[NB_ANTENNAS_RX][2][12][2]; //[Antenna][Slot][Subcarrier][Complex] int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2]; //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex] @@ -779,7 +775,6 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, int16_t Fmt3xDataAvgSym[2][12][2]; //[Slot][Subcarrier][Complex] int16_t IFFTOutData_Fmt3[2][12][2]; //[Slot][Subcarrier][Complex] int16_t b[48]; //[bit] - //int16_t IP_CsData_allavg[NB_ANTENNAS_RX][12][4][2]; //[Antenna][Symbol][Nouse Cyclic Shift][Complex] int16_t payload_entity = -1; int16_t Interpw; int16_t payload_max; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index 35e7beeeab..6c1f674788 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -329,7 +329,7 @@ typedef struct { uint8_t subframe; /// corresponding UE RNTI uint16_t rnti; - /// Type (SR,HARQ,CQI,HARQ_SR,HARQ_CQI,SR_CQI,HARQ_SR_CQI) + /// Type (SR, HARQ, CQI, HARQ_SR, HARQ_CQI, SR_CQI, HARQ_SR_CQI) UCI_type_t type; /// SRS active flag uint8_t srs_active; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 394ab3e4f0..a2754b835a 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -573,7 +573,13 @@ void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_co } } -void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { +void handle_uci_sr_pdu(PHY_VARS_eNB *eNB, + int UE_id, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame, + uint8_t subframe, + uint8_t srs_active) +{ LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; if (NFAPI_MODE==NFAPI_MODE_VNF) return; @@ -594,7 +600,10 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t uci->total_repetitions = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel13.total_number_of_repetitions; #endif LOG_D(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n", - uci->rnti,uci->n_pucch_1_0_sr[0],frame,subframe); + uci->rnti, + uci->n_pucch_1_0_sr[0], + frame, + subframe); } void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a9fd782af8..3b3b9336d4 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -613,54 +613,64 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void uci_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]= {0,0,0,0}; - int32_t metric[4]= {0,0,0,0},metric_SR=0,max_metric=0; +//----------------------------------------------------------------------------- +/* + * Main handler of PUCCH received + */ +void +uci_procedures(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc) +//----------------------------------------------------------------------------- +{ + uint8_t SR_payload = 0; + uint8_t pucch_b0b1[4][2] = {{0,0},{0,0},{0,0},{0,0}}; + uint8_t harq_ack[4] = {0,0,0,0}; + uint16_t tdd_multiplexing_mask = 0; + int32_t metric[4] = {0,0,0,0}; + int32_t metric_SR = 0; + int32_t max_metric = 0; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - int i; - LTE_eNB_UCI *uci; - uint16_t tdd_multiplexing_mask=0; + LTE_eNB_UCI *uci = NULL; + LTE_DL_FRAME_PARMS *fp = &(eNB->frame_parms); - for (i=0; iuci_vars[i]; + for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { + uci = &(eNB->uci_vars[i]); if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) { - LOG_D (PHY, "Frame %d, subframe %d: Running uci procedures (type %d) for %d \n", frame, subframe, uci->type, i); + LOG_D(PHY,"Frame %d, subframe %d: Running uci procedures (type %d) for %d \n", + frame, + subframe, + uci->type, + i); + uci->active = 0; // Null out PUCCH PRBs for noise measurement switch (fp->N_RB_UL) { case 6: - eNB->rb_mask_ul[0] |= (0x1 | (1 << 5)); //position 5 + eNB->rb_mask_ul[0] |= (0x1 | (1 << 5)); // position 5 break; - case 15: - eNB->rb_mask_ul[0] |= (0x1 | (1 << 14)); // position 14 + eNB->rb_mask_ul[0] |= (0x1 | (1 << 14)); // position 14 break; - case 25: - eNB->rb_mask_ul[0] |= (0x1 | (1 << 24)); // position 24 + eNB->rb_mask_ul[0] |= (0x1 | (1 << 24)); // position 24 break; - case 50: eNB->rb_mask_ul[0] |= 0x1; - eNB->rb_mask_ul[1] |= (1 << 17); // position 49 (49-32) + eNB->rb_mask_ul[1] |= (1 << 17); // position 49 (49-32) break; - case 75: eNB->rb_mask_ul[0] |= 0x1; - eNB->rb_mask_ul[2] |= (1 << 10); // position 74 (74-64) + eNB->rb_mask_ul[2] |= (1 << 10); // position 74 (74-64) break; - case 100: eNB->rb_mask_ul[0] |= 0x1; eNB->rb_mask_ul[3] |= (1 << 3); // position 99 (99-96) break; - default: - LOG_E (PHY, "Unknown number for N_RB_UL %d\n", fp->N_RB_UL); + LOG_E(PHY,"Unknown number for N_RB_UL %d\n", fp->N_RB_UL); break; } @@ -1135,8 +1145,8 @@ void uci_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { } } } - } - } + } // end if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) { + } // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { } void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { @@ -1226,7 +1236,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { //compute the expected ULSCH RX power (for the stats) ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered - if (RC.mac != NULL) { /* ulsim dose not use RC.mac context. */ + if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */ if (ulsch_harq->cqi_crc_status == 1) { #ifdef DEBUG_PHY_PROC //if (((frame%10) == 0) || (frame < 50)) @@ -1471,93 +1481,131 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -/* release the harq if its round is >= 'after_rounds' */ -static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int after_rounds) { - LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; - LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; +//----------------------------------------------------------------------------- +/* + * Release the harq process if its round is >= 'after_rounds' + */ +static void do_release_harq(PHY_VARS_eNB *eNB, + int UE_id, + int tb, + uint16_t frame, + uint8_t subframe, + uint16_t mask, + int after_rounds) +//----------------------------------------------------------------------------- +{ + LTE_eNB_DLSCH_t *dlsch0 = NULL; + LTE_eNB_DLSCH_t *dlsch1 = NULL; + LTE_DL_eNB_HARQ_t *dlsch0_harq = NULL; + LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; int harq_pid; - int subframe_tx,frame_tx; - int M,m; - AssertFatal (UE_id != -1, "no existing dlsch context\n"); - AssertFatal (UE_id < NUMBER_OF_UE_MAX, "returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n", UE_id, NUMBER_OF_UE_MAX); + int subframe_tx; + int frame_tx; + + AssertFatal(UE_id != -1, "No existing dlsch context\n"); + AssertFatal(UE_id < NUMBER_OF_UE_MAX, "Returned UE_id %d >= %d (NUMBER_OF_UE_MAX)\n", UE_id, NUMBER_OF_UE_MAX); + dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; if (eNB->frame_parms.frame_type == FDD) { - subframe_tx = (subframe+6)%10; - frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,subframe,subframe_tx); - harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; // or just use 0 for fdd? - AssertFatal((harq_pid>=0) && (harq_pid<10),"harq_pid %d not in 0...9\n",harq_pid); - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + subframe_tx = (subframe + 6) % 10; + frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms, + frame, + subframe, + subframe_tx); + + harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; + + AssertFatal((harq_pid >= 0) && (harq_pid < 8),"harq_pid %d not in 0...7\n", harq_pid); + + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + + AssertFatal(dlsch0_harq != NULL, "dlsch0_harq is null\n"); + #if T_TRACER if (after_rounds != -1) { - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); + T(T_ENB_PHY_DLSCH_UE_NACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); } else { - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); + T(T_ENB_PHY_DLSCH_UE_ACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); } #endif if (dlsch0_harq->round >= after_rounds) { dlsch0_harq->status = SCH_IDLE; - /*if ((dlsch1_harq == NULL)|| - ((dlsch1_harq!=NULL)&& - (dlsch1_harq->status == SCH_IDLE)))*/ - dlsch0->harq_mask &= ~(1<harq_mask &= ~(1 << harq_pid); } - LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti); - } else { // release all processes in the bundle that was acked, based on mask - // This is at most 4 for multiplexing and 9 for bundling/special bundling - M=ul_ACK_subframe2_M(&eNB->frame_parms, - subframe); + } else { + /* Release all processes in the bundle that was acked, based on mask */ + /* This is at most 4 for multiplexing and 9 for bundling/special bundling */ + int M = ul_ACK_subframe2_M(&eNB->frame_parms, subframe); - for (m=0; mframe_parms, - subframe, - m); - frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,subframe,subframe_tx); + subframe, + m); - if (((1< 0) { + frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms, + frame, + subframe, + subframe_tx); + + if (((1 << m) & mask) > 0) { harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - if ((harq_pid>=0) && (harq_pidMdlharq)) { - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + if ((harq_pid >= 0) && (harq_pid < dlsch0->Mdlharq)) { + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + + AssertFatal(dlsch0_harq != NULL, "Dlsch0_harq is null\n"); + #if T_TRACER - if (after_rounds != -1) { - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); + T(T_ENB_PHY_DLSCH_UE_NACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); } else { - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); + T(T_ENB_PHY_DLSCH_UE_ACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); } - #endif - if (dlsch0_harq->round >= after_rounds) { dlsch0_harq->status = SCH_IDLE; - if ((dlsch1_harq == NULL)|| - ((dlsch1_harq!=NULL)&& - (dlsch1_harq->status == SCH_IDLE))) - dlsch0->harq_mask &= ~(1<status == SCH_IDLE))) { + dlsch0->harq_mask &= ~(1 << harq_pid); + } } - } - } - } - } + } // end if ((harq_pid >= 0) && (harq_pid < dlsch0->Mdlharq)) + } // end if (((1 << m) & mask) > 0) + } // end for (int m=0; m < M; m++) + } // end if TDD } static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack) { - /* Maximum number of DL transmissions = 4. + /* + * Maximum number of DL transmissions = 4. * TODO: get the value from configuration. * If is_ack is true then we release immediately. The value -1 can be used for that. */ diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 5b33923b92..64810e644a 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -36,6 +36,7 @@ #include "LTE_SystemInformationBlockType2.h" #include "LTE_SL-OffsetIndicator-r12.h" #include "LTE_SubframeBitmapSL-r12.h" +#include "LTE_DRX-Config.h" #include "LTE_SL-CP-Len-r12.h" #include "LTE_SL-PeriodComm-r12.h" #include "LTE_SL-DiscResourcePool-r12.h" @@ -141,6 +142,14 @@ typedef struct RadioResourceConfig_s { long bcch_modificationPeriodCoeff; long pcch_defaultPagingCycle; long pcch_nB; + LTE_DRX_Config_PR drx_Config_present; + long drx_onDurationTimer; + long drx_InactivityTimer; + long drx_RetransmissionTimer; + LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR drx_longDrx_CycleStartOffset_present; + long drx_longDrx_CycleStartOffset; + long drx_shortDrx_Cycle; + long drx_shortDrx_ShortCycleTimer; long ue_TimersAndConstants_t300; long ue_TimersAndConstants_t301; long ue_TimersAndConstants_t310; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 341981fcf0..84c2f8e6a7 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -283,6 +283,8 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { int j,k = 0; int32_t enb_id = 0; int nb_cc = 0; + int32_t offsetMaxLimit = 0; + int32_t cycleNb = 0; MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_CONFIGURATION_REQ); ccparams_lte_t ccparams_lte; ccparams_sidelink_t SLconfig; @@ -1137,31 +1139,331 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { break; } - if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_fourT; - } else if (strcmp(ccparams_lte.pcch_nB, "twoT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_twoT; - } else if (strcmp(ccparams_lte.pcch_nB, "oneT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneT; - } else if (strcmp(ccparams_lte.pcch_nB, "halfT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_halfT; - } else if (strcmp(ccparams_lte.pcch_nB, "quarterT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_quarterT; - } else if (strcmp(ccparams_lte.pcch_nB, "oneEighthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneEighthT; - } else if (strcmp(ccparams_lte.pcch_nB, "oneSixteenthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneSixteenthT; - } else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", - RC.config_file_name, i, ccparams_lte.pcch_nB); + if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_fourT; + } + else if (strcmp(ccparams_lte.pcch_nB, "twoT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_twoT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneT; + } + else if (strcmp(ccparams_lte.pcch_nB, "halfT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_halfT; + } + else if (strcmp(ccparams_lte.pcch_nB, "quarterT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_quarterT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneEighthT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneEighthT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneSixteenthT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneSixteenthT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT; + } + else { + AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", + RC.config_file_name, + i, + ccparams_lte.pcch_nB); + } - switch (ccparams_lte.bcch_modificationPeriodCoeff) { - case 2: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2; - break; + if (strcmp(ccparams_lte.drx_Config_present, "prNothing") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_NOTHING; + } else if (strcmp(ccparams_lte.drx_Config_present, "prRelease") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_release; + } else if (strcmp(ccparams_lte.drx_Config_present, "prSetup") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_setup; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_Config_present choice: prNothing, prRelease, prSetup!\n", + RC.config_file_name, i, ccparams_lte.drx_Config_present); + } + + if (strcmp(ccparams_lte.drx_onDurationTimer, "psf1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf1; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf2; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf3") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf3; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf4; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf5") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf5; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf6; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf8; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf10") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf10; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf20") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf20; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf30") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf30; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf40") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf40; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf50") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf50; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf60") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf60; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf80") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf80; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf100") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf100; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf200") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf200; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_onDurationTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_onDurationTimer); + break; + } + + if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf1; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf2; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf3") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf3; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf4; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf5") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf5; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf6; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf8; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf10") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf10; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf20") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf20; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf30") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf30; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf40") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf40; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf50") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf50; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf60") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf60; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf80") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf80; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf100") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf100; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf200") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf200; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf300") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf300; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf500") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf500; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf750") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf750; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1280") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf1280; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1920") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf1920; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf2560") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf2560; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf0-v1020") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf0_v1020; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare9") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare9; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare8; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare7") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare7; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare6; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare5") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare5; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare4; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare3") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare3; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare2; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare1; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_InactivityTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_InactivityTimer); + break; + } + + if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf1; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf2; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf4; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf6; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf8; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf16") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf16; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf24") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf24; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf33") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf33; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_RetransmissionTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_RetransmissionTimer); + break; + } + + if (ccparams_lte.drx_longDrx_CycleStartOffset_present == NULL || strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prNothing") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_NOTHING; + } else { + if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf10") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10; + offsetMaxLimit = 10; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf20") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20; + offsetMaxLimit = 20; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf32") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32; + offsetMaxLimit = 32; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf40") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40; + offsetMaxLimit = 40; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf64") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64; + offsetMaxLimit = 64; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf80") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80; + offsetMaxLimit = 80; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf128") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128; + offsetMaxLimit = 128; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf160") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160; + offsetMaxLimit = 160; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf256") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256; + offsetMaxLimit = 256; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf320") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320; + offsetMaxLimit = 320; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf512") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512; + offsetMaxLimit = 512; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf640") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640; + offsetMaxLimit = 640; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf1024") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024; + offsetMaxLimit = 1024; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf1280") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280; + offsetMaxLimit = 1280; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf2048") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048; + offsetMaxLimit = 2048; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf2560") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560; + offsetMaxLimit = 2560; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file \"%s\", enb %d unknown string value \"%s\" for drx_longDrx_CycleStartOffset_present choice !\n", + RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset_present); + } + + if (ccparams_lte.drx_longDrx_CycleStartOffset >= 0 && ccparams_lte.drx_longDrx_CycleStartOffset < offsetMaxLimit) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset = ccparams_lte.drx_longDrx_CycleStartOffset; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incoherent value \"%d\" for drx_longDrx_CycleStartOffset !\n", + RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset); + } + } + + if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") == 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer == 0) { + if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") != 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer != 0) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incoherent values \"%s\" - \"%d\" for drx_shortDrx_Cycle or drx_shortDrx_ShortCycleTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle, ccparams_lte.drx_shortDrx_ShortCycleTimer); + } else { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = -1; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = 0; + } + } else { + if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf2") == 0) { + cycleNb = 2; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf2; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf5") == 0) { + cycleNb = 5; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf5; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf8") == 0) { + cycleNb = 8; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf8; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf10") == 0) { + cycleNb = 10; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf10; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf16") == 0) { + cycleNb = 16; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf16; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf20") == 0) { + cycleNb = 20; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf20; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf32") == 0) { + cycleNb = 32; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf32; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf40") == 0) { + cycleNb = 40; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf40; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf64") == 0) { + cycleNb = 64; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf64; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf80") == 0) { + cycleNb = 80; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf80; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf128") == 0) { + cycleNb = 128; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf128; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf160") == 0) { + cycleNb = 160; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf160; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf256") == 0) { + cycleNb = 256; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf256; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf320") == 0) { + cycleNb = 320; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf320; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf512") == 0) { + cycleNb = 512; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf512; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf640") == 0) { + cycleNb = 640; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf640; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incoherent value \"%s\" for drx_shortDrx_Cycle !\n", + RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle); + } + + if (cycleNb > 0 && (offsetMaxLimit % cycleNb != 0 || cycleNb == offsetMaxLimit)) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incompatible (not multiple) values \"%d\" - \"%d\" for drx_shortDrx_Cycle and drx_longDrx_CycleStartOffset choice !\n", + RC.config_file_name, i, cycleNb, offsetMaxLimit); + } + + if (ccparams_lte.drx_shortDrx_ShortCycleTimer >= 1 && ccparams_lte.drx_shortDrx_ShortCycleTimer <= 16 ) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = ccparams_lte.drx_shortDrx_ShortCycleTimer; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for drx_shortDrx_ShortCycleTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_shortDrx_ShortCycleTimer ); + } + } + + switch (ccparams_lte.bcch_modificationPeriodCoeff) { + case 2: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2; + break; case 4: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n4; diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c index 5a8362300e..effc93d244 100644 --- a/openair2/ENB_APP/enb_config_eMTC.c +++ b/openair2/ENB_APP/enb_config_eMTC.c @@ -932,8 +932,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in break; } RRC_CONFIGURATION_REQ (msg_p).rar_HoppingConfig_r13[cc_idx][rachCEInfoIndex] = eMTCconfig->rar_HoppingConfig_r13; + AssertFatal(eMTCconfig->rar_HoppingConfig_r13 == 0 || eMTCconfig->rar_HoppingConfig_r13 == 1, - "illegal rar_HoppingConfig_r13 %d\n",eMTCconfig->rar_HoppingConfig_r13); + "illegal rar_HoppingConfig_r13 %d\n",eMTCconfig->rar_HoppingConfig_r13); } // end for loop (rach ce level info) char rsrpRangeListPath[MAX_OPTNAME_SIZE * 2]; @@ -1101,11 +1102,12 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in /** PCCH CONFIG V1310 */ - RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = TRUE; RRC_CONFIGURATION_REQ(msg_p).paging_narrowbands_r13[cc_idx] = eMTCconfig->paging_narrowbands_r13; RRC_CONFIGURATION_REQ(msg_p).mpdcch_numrepetition_paging_r13[cc_idx] = eMTCconfig->mpdcch_numrepetition_paging_r13; - AssertFatal (eMTCconfig->mpdcch_numrepetition_paging_r13 == 1 || + + AssertFatal (eMTCconfig->mpdcch_numrepetition_paging_r13 == 0 || + eMTCconfig->mpdcch_numrepetition_paging_r13 == 1 || eMTCconfig->mpdcch_numrepetition_paging_r13 == 2 || eMTCconfig->mpdcch_numrepetition_paging_r13 == 4 || eMTCconfig->mpdcch_numrepetition_paging_r13 == 8 || @@ -1117,7 +1119,6 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "illegal mpdcch_numrepetition_paging_r13 %d\n", eMTCconfig->mpdcch_numrepetition_paging_r13); - // RRC_CONFIGURATION_REQ(msg_p).nb_v1310[cc_idx] = CALLOC(1, sizeof(long)); // if (!strcmp(nb_v1310, "one64thT")) { // *RRC_CONFIGURATION_REQ(msg_p).nb_v1310[cc_idx] = 0; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 54d6decfee..dff16ff9d7 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -321,8 +321,7 @@ typedef enum { #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL2 "pucch_NumRepetitionCE_Msg4_Level2_r13" #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL3 "pucch_NumRepetitionCE_Msg4_Level3_r13" -#define ENB_CONFIG_STRING_FREQ_HOPPING_PARAMETERS_R13 "sib2_freq_hoppingParameters_r13" - +#define ENB_CONFIG_STRING_FREQ_HOPPING_PARAMETERS_R13 "sib2_freq_hoppingParameters_r13" #define ENB_CONFIG_STRING_PDSCH_RS_EPRE "pdsch_referenceSignalPower" #define ENB_CONFIG_STRING_PDSCH_PB "pdsch_p_b" @@ -364,6 +363,14 @@ typedef enum { #define ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX "rach_maxHARQ_Msg3Tx" #define ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE "pcch_default_PagingCycle" #define ENB_CONFIG_STRING_PCCH_NB "pcch_nB" +#define ENB_CONFIG_STRING_DRX_CONFIG_PRESENT "drx_Config_present" +#define ENB_CONFIG_STRING_DRX_ONDURATIONTIMER "drx_onDurationTimer" +#define ENB_CONFIG_STRING_DRX_INACTIVITYTIMER "drx_InactivityTimer" +#define ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER "drx_RetransmissionTimer" +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT "drx_longDrx_CycleStartOffset_present" +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET "drx_longDrx_CycleStartOffset" +#define ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE "drx_shortDrx_Cycle" +#define ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER "drx_shortDrx_ShortCycleTimer" #define ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF "bcch_modificationPeriodCoeff" #define ENB_CONFIG_STRING_UETIMERS_T300 "ue_TimersAndConstants_t300" #define ENB_CONFIG_STRING_UETIMERS_T301 "ue_TimersAndConstants_t301" @@ -496,6 +503,14 @@ typedef struct ccparams_lte_s { int32_t rach_maxHARQ_Msg3Tx; int32_t pcch_defaultPagingCycle; char *pcch_nB; + char *drx_Config_present; + char *drx_onDurationTimer; + char *drx_InactivityTimer; + char *drx_RetransmissionTimer; + char *drx_longDrx_CycleStartOffset_present; + int32_t drx_longDrx_CycleStartOffset; + char *drx_shortDrx_Cycle; + int32_t drx_shortDrx_ShortCycleTimer; int32_t bcch_modificationPeriodCoeff; int32_t ue_TimersAndConstants_t300; int32_t ue_TimersAndConstants_t301; @@ -574,6 +589,14 @@ typedef struct ccparams_lte_s { { .s5= {NULL }} , \ { .s5= {NULL }} , \ { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ { .s5= {NULL }} , \ { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ @@ -688,6 +711,14 @@ typedef struct ccparams_lte_s { {ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX, NULL, 0, iptr:&ccparams.rach_maxHARQ_Msg3Tx, defintval:4, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE, NULL, 0, iptr:&ccparams.pcch_defaultPagingCycle, defintval:128, TYPE_INT, 0}, \ {ENB_CONFIG_STRING_PCCH_NB, NULL, 0, strptr:&ccparams.pcch_nB, defstrval:"oneT", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_CONFIG_PRESENT, NULL, 0, strptr:&ccparams.drx_Config_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_ONDURATIONTIMER, NULL, 0, strptr:&ccparams.drx_onDurationTimer, defstrval:"psf10", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_INACTIVITYTIMER, NULL, 0, strptr:&ccparams.drx_InactivityTimer, defstrval:"psf10", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER, NULL, 0, strptr:&ccparams.drx_RetransmissionTimer, defstrval:"psf8", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT, NULL, 0, strptr:&ccparams.drx_longDrx_CycleStartOffset_present, defstrval:"prSf128", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET, NULL, 0, iptr:&ccparams.drx_longDrx_CycleStartOffset, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE, NULL, 0, strptr:&ccparams.drx_shortDrx_Cycle, defstrval:"sf32", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER, NULL, 0, iptr:&ccparams.drx_shortDrx_ShortCycleTimer, defintval:3, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF, NULL, 0, iptr:&ccparams.bcch_modificationPeriodCoeff, defintval:2, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_T300, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t300, defintval:1000, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_T301, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t301, defintval:1000, TYPE_UINT, 0}, \ @@ -696,7 +727,7 @@ typedef struct ccparams_lte_s { {ENB_CONFIG_STRING_UETIMERS_N310, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n310, defintval:20, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ccparams.ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \ -{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0} \ +{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0} \ } @@ -761,14 +792,22 @@ typedef struct ccparams_lte_s { #define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 #define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 #define ENB_CONFIG_PCCH_NB_IDX 59 -#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 60 -#define ENB_CONFIG_UETIMERS_T300_IDX 61 -#define ENB_CONFIG_UETIMERS_T301_IDX 62 -#define ENB_CONFIG_UETIMERS_T310_IDX 63 -#define ENB_CONFIG_UETIMERS_T311_IDX 64 -#define ENB_CONFIG_UETIMERS_N310_IDX 65 -#define ENB_CONFIG_UETIMERS_N311_IDX 66 -#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 67 +#define ENB_CONFIG_STRING_DRX_CONFIG_PRESENT_IDX 60 +#define ENB_CONFIG_STRING_DRX_ONDURATIONTIMER_IDX 61 +#define ENB_CONFIG_STRING_DRX_INACTIVITYTIMER_IDX 62 +#define ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER_IDX 63 +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT_IDX 64 +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_IDX 65 +#define ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE_IDX 66 +#define ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER_IDX 67 +#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 68 +#define ENB_CONFIG_UETIMERS_T300_IDX 69 +#define ENB_CONFIG_UETIMERS_T301_IDX 70 +#define ENB_CONFIG_UETIMERS_T310_IDX 71 +#define ENB_CONFIG_UETIMERS_T311_IDX 72 +#define ENB_CONFIG_UETIMERS_N310_IDX 73 +#define ENB_CONFIG_UETIMERS_N311_IDX 74 +#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 75 /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ diff --git a/openair2/ENB_APP/enb_paramdef_emtc.h b/openair2/ENB_APP/enb_paramdef_emtc.h index 9f76bac2fa..25ab43ccf6 100644 --- a/openair2/ENB_APP/enb_paramdef_emtc.h +++ b/openair2/ENB_APP/enb_paramdef_emtc.h @@ -61,7 +61,10 @@ #define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13 "preamble_TransMax_ce_r13" #define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13_VAL "preamble_TransMax_ce_r13_val" #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13" +#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" +#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" +#define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" #define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI" #define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13" #define ENB_CONFIG_STRING_LAST_PREAMBLE_R13 "lastPreamble_r13" @@ -81,6 +84,9 @@ #define ENB_CONFIG_STRING_PUCCH_INFO_VALUE "pucch_info_value" #define ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13 "n1PUCCH_AN_InfoList_r13" #define ENB_CONFIG_STRING_PCCH_CONFIG_V1310 "pcch_config_v1310" +#define ENB_CONFIG_STRING_PAGING_NARROWBANDS_R13 "paging_narrowbands_r13" +#define ENB_CONFIG_STRING_MPDCCH_NUMREPETITION_PAGING_R13 "mpdcch_numrepetition_paging_r13" +#define ENB_CONFIG_STRING_NB_V1310 "nb_v1310" #define ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13 "sib2_freq_hoppingParameters_r13" typedef struct ccparams_eMTC_s { diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index c547e497fa..669f3cf1fe 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -928,3 +928,359 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, RC.mac[Mod_idP]->scheduler_mode = global_scheduler_mode; return(0); } + + +//----------------------------------------------------------------------------- +/* +* Configure local DRX 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 +) +//----------------------------------------------------------------------------- +{ + UE_list_t *UE_list_mac = NULL; + int UE_id = -1; + UE_sched_ctrl *UE_scheduling_control = NULL; + + UE_list_mac = &(RC.mac[Mod_id]->UE_list); + + UE_id = find_UE_id(Mod_id, rnti); + + /* Check UE_id */ + if (UE_id == -1) { + LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", + __FILE__, + __LINE__, + __FUNCTION__); + return; + } + + /* Get struct to modify */ + UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]); + + /* 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; + 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; + 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 + 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) { + case 0: + UE_scheduling_control->on_duration_timer_thres = 1; + break; + case 1: + UE_scheduling_control->on_duration_timer_thres = 2; + break; + case 2: + UE_scheduling_control->on_duration_timer_thres = 3; + break; + case 3: + UE_scheduling_control->on_duration_timer_thres = 4; + break; + case 4: + UE_scheduling_control->on_duration_timer_thres = 5; + break; + case 5: + UE_scheduling_control->on_duration_timer_thres = 6; + break; + case 6: + UE_scheduling_control->on_duration_timer_thres = 8; + break; + case 7: + UE_scheduling_control->on_duration_timer_thres = 10; + break; + case 8: + UE_scheduling_control->on_duration_timer_thres = 20; + break; + case 9: + UE_scheduling_control->on_duration_timer_thres = 30; + break; + case 10: + UE_scheduling_control->on_duration_timer_thres = 40; + break; + case 11: + UE_scheduling_control->on_duration_timer_thres = 50; + break; + case 12: + UE_scheduling_control->on_duration_timer_thres = 60; + break; + case 13: + UE_scheduling_control->on_duration_timer_thres = 80; + break; + case 14: + UE_scheduling_control->on_duration_timer_thres = 100; + break; + case 15: + 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"); + break; + } + + UE_scheduling_control->drx_inactivity_timer = 0; + switch (drx_Configuration->choice.setup.drx_InactivityTimer) { + case 0: + UE_scheduling_control->drx_inactivity_timer_thres = 1; + break; + case 1: + UE_scheduling_control->drx_inactivity_timer_thres = 2; + break; + case 2: + UE_scheduling_control->drx_inactivity_timer_thres = 3; + break; + case 3: + UE_scheduling_control->drx_inactivity_timer_thres = 4; + break; + case 4: + UE_scheduling_control->drx_inactivity_timer_thres = 5; + break; + case 5: + UE_scheduling_control->drx_inactivity_timer_thres = 6; + break; + case 6: + UE_scheduling_control->drx_inactivity_timer_thres = 8; + break; + case 7: + UE_scheduling_control->drx_inactivity_timer_thres = 10; + break; + case 8: + UE_scheduling_control->drx_inactivity_timer_thres = 20; + break; + case 9: + UE_scheduling_control->drx_inactivity_timer_thres = 30; + break; + case 10: + UE_scheduling_control->drx_inactivity_timer_thres = 40; + break; + case 11: + UE_scheduling_control->drx_inactivity_timer_thres = 50; + break; + case 12: + UE_scheduling_control->drx_inactivity_timer_thres = 60; + break; + case 13: + UE_scheduling_control->drx_inactivity_timer_thres = 80; + break; + case 14: + UE_scheduling_control->drx_inactivity_timer_thres = 100; + break; + case 15: + UE_scheduling_control->drx_inactivity_timer_thres = 200; + break; + case 16: + UE_scheduling_control->drx_inactivity_timer_thres = 300; + break; + case 17: + UE_scheduling_control->drx_inactivity_timer_thres = 500; + break; + case 18: + UE_scheduling_control->drx_inactivity_timer_thres = 750; + break; + case 19: + UE_scheduling_control->drx_inactivity_timer_thres = 1280; + break; + case 20: + UE_scheduling_control->drx_inactivity_timer_thres = 1920; + break; + case 21: + UE_scheduling_control->drx_inactivity_timer_thres = 2560; + break; + case 22: + 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"); + break; + } + + if (drx_Configuration->choice.setup.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; + UE_scheduling_control->drx_shortCycle_timer = 0; + 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) { + case 0: + UE_scheduling_control->short_drx_cycle_duration = 2; + break; + case 1: + UE_scheduling_control->short_drx_cycle_duration = 5; + break; + case 2: + UE_scheduling_control->short_drx_cycle_duration = 8; + break; + case 3: + UE_scheduling_control->short_drx_cycle_duration = 10; + break; + case 4: + UE_scheduling_control->short_drx_cycle_duration = 16; + break; + case 5: + UE_scheduling_control->short_drx_cycle_duration = 20; + break; + case 6: + UE_scheduling_control->short_drx_cycle_duration = 32; + break; + case 7: + UE_scheduling_control->short_drx_cycle_duration = 40; + break; + case 8: + UE_scheduling_control->short_drx_cycle_duration = 64; + break; + case 9: + UE_scheduling_control->short_drx_cycle_duration = 80; + break; + case 10: + UE_scheduling_control->short_drx_cycle_duration = 128; + break; + case 11: + UE_scheduling_control->short_drx_cycle_duration = 160; + break; + case 12: + UE_scheduling_control->short_drx_cycle_duration = 256; + break; + case 13: + UE_scheduling_control->short_drx_cycle_duration = 320; + break; + case 14: + UE_scheduling_control->short_drx_cycle_duration = 512; + break; + case 15: + 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"); + break; + } + + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->drx_shortCycle_timer_thres = UE_scheduling_control->drx_shortCycle_timer_value * UE_scheduling_control->short_drx_cycle_duration; + } + + UE_scheduling_control->in_long_drx_cycle = FALSE; + UE_scheduling_control->drx_longCycle_timer = 0; + switch (drx_Configuration->choice.setup.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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + break; + default: + LOG_E(MAC, "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) { + case 0: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 1: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 2, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 2: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 4, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 3: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 6, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 4: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 8, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 5: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 16, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 6: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 24, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 7: + 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"); + break; + } +} \ No newline at end of file diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 8a9e3883d5..d5bab36f60 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -69,67 +69,91 @@ extern RAN_CONTEXT_t RC; uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; - -void -schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; - struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; - uint8_t TSFC; - uint16_t deltaTSFC; // bitmap - uint8_t srs_SubframeConfig; +//----------------------------------------------------------------------------- +/* + * Schedule periodic SRS + */ +void schedule_SRS(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- +{ + int CC_id = 0; + int UE_id = -1; + uint8_t TSFC = 0; + uint8_t srs_SubframeConfig = 0; + uint16_t srsPeriodicity = 0; + uint16_t srsOffset = 0; + uint16_t deltaTSFC = 0; // bitmap // table for TSFC (Period) and deltaSFC (offset) const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD - uint16_t srsPeriodicity, srsOffset; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &(eNB->UE_list); + nfapi_ul_config_request_body_t *ul_req = NULL; + UE_sched_ctrl *UE_scheduling_control = NULL; + COMMON_channels_t *cc = eNB->common_channels; + LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon = NULL; + struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated = NULL; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; + soundingRS_UL_ConfigCommon = &(cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon); - // check if SRS is enabled in this frame/subframe + /* Check if SRS is enabled in this frame/subframe */ if (soundingRS_UL_ConfigCommon) { srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; - if (cc[CC_id].tdd_Config == NULL) { // FDD + if (cc[CC_id].tdd_Config == NULL) { // FDD deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; - } else { // TDD + } else { // TDD deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; } - // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC + /* Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC) */ uint16_t tmp = (subframeP % TSFC); if ((1 << tmp) & deltaTSFC) { - // This is an SRS subframe, loop over UEs + /* This is an SRS subframe, loop over UEs */ for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (!RC.mac[module_idP]->UE_list.active[UE_id]) continue; + if (!UE_list->active[UE_id]) { + continue; + } - ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; - - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; + /* Drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet */ + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { + continue; + } AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", UE_id); + /* CDRX condition on Active Time and SRS type-0 report (36.321 5.7) */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + + /* Test if Active Time not running since 6+ subframes */ + if (UE_scheduling_control->cdrx_configured == TRUE && UE_scheduling_control->in_active_time == FALSE) { + /* + * TODO: 6+ subframes condition not checked here + */ + continue; + } + + ul_req = &(eNB->UL_req[CC_id].ul_config_request_body); + if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { if (soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { get_srs_pos(&cc[CC_id], - soundingRS_UL_ConfigDedicated->choice. - setup.srs_ConfigIndex, - &srsPeriodicity, &srsOffset); + soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, + &srsPeriodicity, + &srsOffset); if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) { // Program SRS ul_req->srs_present = 1; - nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &(ul_req->ul_config_pdu_list[ul_req->number_of_pdus]); memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu)); @@ -141,194 +165,250 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; - ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = - soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// - // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; + + eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + eNB->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req->number_of_pdus++; } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) - } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) - } // for (UE_id ... - } // if((1<UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) + } // end for loop on UE_id + } // if((1<UE_list; - COMMON_channels_t *cc; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic; - uint16_t Npd, N_OFFSET_CQI; - int H; + COMMON_channels_t *cc = NULL; + nfapi_ul_config_request_body_t *ul_req = NULL; + UE_sched_ctrl *UE_scheduling_control = NULL; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { cc = &eNB->common_channels[CC_id]; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (!UE_list->active[UE_id]) continue; + if (UE_list->active[UE_id] == FALSE) { + continue; + } - ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + /* Drop the allocation if the UE hasn't sent RRCConnectionSetupComplete yet */ + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { + continue; + } - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated - != NULL, + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", UE_id); + /* + * CDRX condition on Active Time and CSI report on PUCCH (36.321 5.7). + * Here we consider classic periodic reports on PUCCH without PUSCH simultaneous transmission condition. + * TODO: add the handling or test on simultaneous PUCCH/PUSCH transmission + */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); - if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { - if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL - && (cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_release)) { - //Rel8 Periodic CQI/PMI/RI reporting - get_csi_params(cc, cqi_ReportPeriodic, &Npd, - &N_OFFSET_CQI, &H); - - if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity - UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] = (((frameP * 10) + subframeP) / Npd) % H; - // Program CQI - nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, - get_tmode(module_idP, CC_id, UE_id), - cqi_ReportPeriodic); - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - // PUT rel10-13 UCI options here -#endif - } else if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) - && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % - 161))) { // RI opportunity - // Program RI - nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + if (UE_scheduling_control->cdrx_configured == TRUE) { + /* Test if CQI masking activated */ + if (UE_scheduling_control->cqi_mask_boolean == TRUE) { + // CQI masking => test if onDurationTime not running since 6+ subframe + if (UE_scheduling_control->on_duration_timer == 0) { + /* + * TODO: 6+ subframes condition not checked here + */ + continue; } - } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { - } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - } // for (CC_id=0; CC_id test if Active Time not running since 6+ subframe + if (UE_scheduling_control->in_active_time == FALSE) { + /* + * TODO: 6+ subframes condition not checked here + */ + continue; + } + } + } + + ul_req = &(eNB->UL_req[CC_id].ul_config_request_body); + + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL) { + cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic; + + if (cqi_ReportPeriodic != NULL) { + /* Rel8 Periodic CSI (CQI/PMI/RI) reporting */ + if (cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_release) { + get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); + + if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI periodic opportunity + UE_scheduling_control->feedback_cnt[CC_id] = (((frameP * 10) + subframeP) / Npd) % H; + + // Program CQI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, get_tmode(module_idP, CC_id, UE_id), cqi_ReportPeriodic); + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // PUT rel10-13 UCI options here +#endif + } else if (cqi_ReportPeriodic->choice.setup.ri_ConfigIndex != NULL) { + if ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == + N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161)) { // RI opportunity + + // Program RI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } + } + } // if CSI Periodic is not release state + } // if (cqi_ReportPeriodic != NULL) + } // if cqi_ReportConfig != NULL + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + } // for (CC_id=0; CC_idUE_list; - nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_body_t *ul_req_body; - int CC_id; - int UE_id; - LTE_SchedulingRequestConfig_t *SRconfig; - int skip_ue; - int is_harq; +schedule_SR (module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- +{ + int skip_ue = 0; + int is_harq = 0; + int pdu_list_index = 0; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_t *ul_req = NULL; + nfapi_ul_config_request_body_t *ul_req_body = NULL; + LTE_SchedulingRequestConfig_t *SRconfig = NULL; nfapi_ul_config_sr_information sr; - int i; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (!RC.mac[module_idP]->UE_list.active[UE_id]) continue; + for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (!UE_list->active[UE_id]) { + continue; + } - ul_req = &RC.mac[module_idP]->UL_req[CC_id]; - ul_req_body = &ul_req->ul_config_request_body; - - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - //if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - - if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated== NULL) continue; + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) continue; if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) { if (SRconfig->present == LTE_SchedulingRequestConfig_PR_setup) { - if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period + if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period if (subframeP != (SRconfig->choice.setup.sr_ConfigIndex - 5)) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period if ((10 * (frameP & 1) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 15)) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period if ((10 * (frameP & 3) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 35)) continue; } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period if ((10 * (frameP & 7) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 75)) continue; } - } // SRconfig->present == SchedulingRequestConfig_PR_setup) - } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) + } // SRconfig->present == SchedulingRequestConfig_PR_setup) + } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) - // if we get here there is some PUCCH1 reception to schedule for SR + /* If we get here there is some PUCCH1 reception to schedule for SR */ + ul_req = &(eNB->UL_req[CC_id]); + ul_req_body = &(ul_req->ul_config_request_body); skip_ue = 0; is_harq = 0; + pdu_list_index = 0; - // check that there is no existing UL grant for ULSCH which overrides the SR - for (i = 0; i < ul_req_body->number_of_pdus; i++) { + /* Check that there is no existing UL grant for ULSCH which overrides the SR */ + for (int i = 0; i < ul_req_body->number_of_pdus; i++) { if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { skip_ue = 1; + pdu_list_index = i; break; } - /* if there is already an HARQ pdu, convert to SR_HARQ */ + /* If there is already an HARQ pdu, convert to SR_HARQ */ else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { is_harq = 1; + pdu_list_index = i; break; } } - // drop the allocation because ULSCH with handle it with BSR + /* Drop the allocation because ULSCH will handle it with BSR */ if (skip_ue == 1) continue; - LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); - // check Rel10 or Rel8 SR -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LOG_D(MAC, "Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d \n", + frameP, + subframeP, + UE_id, + UE_list->UE_template[CC_id][UE_id].rnti, + is_harq); - if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) - && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) - && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { + /* Check Rel10 or Rel8 SR */ +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) && + (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) && + (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; sr.sr_information_rel10.number_of_pucch_resources = 1; sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; - LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); + + LOG_D(MAC, "REL10 PUCCH INDEX P1:%d \n", sr.sr_information_rel10.pucch_index_p1); + } else #endif { - sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; - sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; - LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); + sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; + sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; + + LOG_D(MAC, "REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); } - /* if there is already an HARQ pdu, convert to SR_HARQ */ + /* If there is already an HARQ pdu, convert to SR_HARQ */ if (is_harq) { - nfapi_ul_config_harq_information h = ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.harq_information; - ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; + nfapi_ul_config_harq_information harq = ul_req_body->ul_config_pdu_list[pdu_list_index].uci_harq_pdu.harq_information; + ul_req_body->ul_config_pdu_list[pdu_list_index].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_req_body->ul_config_pdu_list[pdu_list_index].uci_sr_harq_pdu.sr_information = sr; + ul_req_body->ul_config_pdu_list[pdu_list_index].uci_sr_harq_pdu.harq_information = harq; } else { ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; @@ -337,11 +417,12 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; ul_req_body->number_of_pdus++; - } /* if (is_harq) */ + } // if (is_harq) - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) - } // for (CC_id=0; CC_idtl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + + } // for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) + } // for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) } void @@ -411,10 +492,14 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, itti_send_msg_to_task(TASK_DU_F1, module_idP, m); } else { // inform RRC of failure and clear timer - LOG_I(MAC, - "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", - UE_id, rnti); - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti); + LOG_I(MAC, "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", + UE_id, + rnti); + mac_eNB_rrc_ul_failure(module_idP, + CC_id, + frameP, + subframeP, + rnti); } UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; @@ -474,80 +559,295 @@ copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { } void -eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) { +eNB_dlsch_ulsch_scheduler(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +{ int mbsfn_status[MAX_NUM_CCs]; protocol_ctxt_t ctxt; - int CC_id, i = -1; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - rnti_t rnti; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - start_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_IN); - RC.mac[module_idP]->frame = frameP; - RC.mac[module_idP]->subframe = subframeP; + rnti_t rnti = 0; + int CC_id = 0; + int UE_id = -1; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &(eNB->UE_list); + COMMON_channels_t *cc = eNB->common_channels; + UE_sched_ctrl *UE_scheduling_control = NULL; + + start_meas(&(eNB->eNB_scheduler)); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_IN); + + eNB->frame = frameP; + eNB->subframe = subframeP; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { mbsfn_status[CC_id] = 0; - // clear vrb_maps + + /* Clear vrb_maps */ memset(cc[CC_id].vrb_map, 0, 100); memset(cc[CC_id].vrb_map_UL, 0, 100); + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - cc[CC_id].mcch_active = 0; + cc[CC_id].mcch_active = 0; #endif clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, subframeP); } - // refresh UE list based on UEs dropped by PHY in previous subframe - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_list->active[i]) { - rnti = UE_RNTI(module_idP, i); - CC_id = UE_PCCID(module_idP, i); + /* Refresh UE list based on UEs dropped by PHY in previous subframe */ + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id]) { + rnti = UE_RNTI(module_idP, UE_id); + CC_id = UE_PCCID(module_idP, UE_id); - if (((frameP&127) == 0) && (subframeP == 0)) { - LOG_I(MAC, - "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + + if (((frameP & 127) == 0) && (subframeP == 0)) { + LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync == - 0 ? "in synch" : "out of sync", - UE_list->UE_template[CC_id][i].phr_info, - UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], - (5*UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 640) / 10, - (5*UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 640) / 10); + UE_scheduling_control->ul_out_of_sync == 0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][UE_id].phr_info, + UE_scheduling_control->dl_cqi[CC_id], + (5 * UE_scheduling_control->pusch_snr[CC_id] - 640) / 10, + (5 * UE_scheduling_control->pucch1_snr[CC_id] - 640) / 10); } - RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + - subframeP] = -63; + RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = -63; - if (i == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[module_idP][CC_id]-> - pusch_stats_bsr[i][(frameP * 10) + subframeP]); + if (UE_id == UE_list->head) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP]); + } - // increment this, it is cleared when we receive an sdu - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. - ul_inactivity_timer, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); - check_ul_failure(module_idP, CC_id, i, frameP, subframeP); + /* Set and increment CDRX related timers */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + boolean_t harq_active_time_condition = FALSE; + UE_TEMPLATE *UE_template = NULL; - if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) { - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++; + unsigned long active_time_condition = 0; // variable used only for tracing purpose - if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >= - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) { - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0; + /* (UL and DL) HARQ RTT timers and DRX retransmission timers */ + for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { + /* DL asynchronous HARQ process */ + if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > 0) { + UE_scheduling_control->drx_retransmission_timer[harq_process_id]++; - //clear reestablish_rnti_map - if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres >20) { + if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > UE_scheduling_control->drx_retransmission_timer_thres[harq_process_id]) { + UE_scheduling_control->drx_retransmission_timer[harq_process_id] = 0; + } + } + + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 8) { + /* Note: here drx_retransmission_timer is restarted instead of started in the specification */ + UE_scheduling_control->drx_retransmission_timer[harq_process_id] = 1; // started when HARQ RTT timer expires + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + + /* UL asynchronous HARQ process: only UL HARQ RTT timer is implemented (hence not implemented) */ + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 4) { + /* + * TODO: implement the handling of UL asynchronous HARQ + * drx_ULRetransmissionTimer should be (re)started here + */ + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + + /* UL synchronous HARQ process */ + if (UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] > 5) { + harq_active_time_condition = TRUE; + UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] = 0; + active_time_condition = 5; // for tracing purpose + } + } + } + + /* On duration timer */ + if (UE_scheduling_control->on_duration_timer > 0) { + UE_scheduling_control->on_duration_timer++; + + if (UE_scheduling_control->on_duration_timer > UE_scheduling_control->on_duration_timer_thres) { + UE_scheduling_control->on_duration_timer = 0; + } + } + + /* DRX inactivity timer */ + if (UE_scheduling_control->drx_inactivity_timer > 0) { + UE_scheduling_control->drx_inactivity_timer++; + + if (UE_scheduling_control->drx_inactivity_timer > (UE_scheduling_control->drx_inactivity_timer_thres + 1)) { + /* Note: the +1 on the threshold is due to information in table C-1 of 36.321 */ + UE_scheduling_control->drx_inactivity_timer = 0; + + /* When timer expires switch into short or long DRX cycle */ + if (UE_scheduling_control->drx_shortCycle_timer_thres > 0) { + UE_scheduling_control->in_short_drx_cycle = TRUE; + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->in_long_drx_cycle = FALSE; + } else { + UE_scheduling_control->in_long_drx_cycle = TRUE; + } + } + } + + /* Short DRX Cycle */ + if (UE_scheduling_control->in_short_drx_cycle == TRUE) { + UE_scheduling_control->drx_shortCycle_timer++; + + /* When the Short DRX cycles are over, switch to long DRX cycle */ + if (UE_scheduling_control->drx_shortCycle_timer > UE_scheduling_control->drx_shortCycle_timer_thres) { + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_long_drx_cycle = TRUE; + UE_scheduling_control->drx_longCycle_timer = 0; + } + } else { + UE_scheduling_control->drx_shortCycle_timer = 0; + } + + /* Long DRX Cycle */ + if (UE_scheduling_control->in_long_drx_cycle == TRUE) { + UE_scheduling_control->drx_longCycle_timer++; + + if (UE_scheduling_control->drx_longCycle_timer > UE_scheduling_control->drx_longCycle_timer_thres) { + UE_scheduling_control->drx_longCycle_timer = 1; + } + } else { + UE_scheduling_control->drx_longCycle_timer = 0; + } + + /* Check for error cases */ + if ((UE_scheduling_control->in_short_drx_cycle == TRUE) && (UE_scheduling_control->in_long_drx_cycle == TRUE)) { + LOG_E(MAC, "Error in C-DRX: UE id %d is in both short and long DRX cycle. Should not happen. Back it to long cycle only\n", UE_id); + UE_scheduling_control->in_short_drx_cycle = FALSE; + } + + /* Condition to start On Duration Timer */ + if (UE_scheduling_control->in_short_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + if (((frameP * 10) + subframeP) % (UE_scheduling_control->short_drx_cycle_duration) == + (UE_scheduling_control->drx_start_offset) % (UE_scheduling_control->short_drx_cycle_duration)) { + + UE_scheduling_control->on_duration_timer = 1; + } + } else if (UE_scheduling_control->in_long_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + if (((frameP * 10) + subframeP) % (UE_scheduling_control->drx_longCycle_timer_thres) == + (UE_scheduling_control->drx_start_offset)) { + + UE_scheduling_control->on_duration_timer = 1; + } + } + + /* Update Active Time status of UE + * Based on 36.321 5.7 the differents conditions for the UE to be in Acttive Should be check ONLY + * here for the current subframe. The variable 'UE_scheduling_control->in_active_time' should be updated + * ONLY here. The variable can then be used for testing the actual state of the UE for scheduling purpose. + */ + UE_template = &(UE_list->UE_template[CC_id][UE_id]); + /* (a)synchronous HARQ processes handling for Active Time */ + for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { + if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > 0) { + harq_active_time_condition = TRUE; + active_time_condition = 2; // for tracing purpose + break; + } + } + + /* Active time conditions */ + if (UE_scheduling_control->on_duration_timer > 0 || + UE_scheduling_control->drx_inactivity_timer > 1 || + harq_active_time_condition || + UE_template->ul_SR > 0) { + + UE_scheduling_control->in_active_time = TRUE; + + } else { + UE_scheduling_control->in_active_time = FALSE; + } + + /* BEGIN VCD */ + if (UE_id == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_ON_DURATION_TIMER, (unsigned long) UE_scheduling_control->on_duration_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_scheduling_control->drx_inactivity_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_SHORT_CYCLE, (unsigned long) UE_scheduling_control->drx_shortCycle_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_LONG_CYCLE, (unsigned long) UE_scheduling_control->drx_longCycle_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) UE_scheduling_control->drx_retransmission_timer[0]); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME, (unsigned long) UE_scheduling_control->in_active_time); + + /* For tracing purpose */ + if (UE_template->ul_SR > 0) { + active_time_condition = 1; + } else if ((UE_scheduling_control->on_duration_timer > 0) && (active_time_condition == 0)) { + active_time_condition = 3; + } else if ((UE_scheduling_control->drx_inactivity_timer > 1) && (active_time_condition == 0)) { + active_time_condition = 4; + } + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME_CONDITION, (unsigned long) active_time_condition); + } + /* END VCD */ + + /* DCI0 ongoing timer */ + if (UE_scheduling_control->dci0_ongoing_timer > 0) { + if (UE_scheduling_control->dci0_ongoing_timer > 7) { + UE_scheduling_control->dci0_ongoing_timer = 0; + } else { + UE_scheduling_control->dci0_ongoing_timer++; + } + } + + } else { // else: CDRX not configured + /* Note: (UL) HARQ RTT timers processing is done here and can be used by other features than CDRX */ + /* HARQ RTT timers */ + for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 8) { + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 4) { + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + } // end loop harq process + } // end else CDRX not configured + + /* Increment these timers, they are cleared when we receive an sdu */ + UE_scheduling_control->ul_inactivity_timer++; + UE_scheduling_control->cqi_req_timer++; + + LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", + UE_id, + rnti, + UE_scheduling_control->ul_inactivity_timer, + UE_scheduling_control->cqi_req_timer); + + check_ul_failure(module_idP, CC_id, UE_id, frameP, subframeP); + + if (UE_scheduling_control->ue_reestablishment_reject_timer > 0) { + UE_scheduling_control->ue_reestablishment_reject_timer++; + + if (UE_scheduling_control->ue_reestablishment_reject_timer >= UE_scheduling_control->ue_reestablishment_reject_timer_thres) { + UE_scheduling_control->ue_reestablishment_reject_timer = 0; + + /* Clear reestablish_rnti_map */ + if (UE_scheduling_control->ue_reestablishment_reject_timer_thres > 20) { for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_ENB; ue_id_l++) { if (reestablish_rnti_map[ue_id_l][0] == rnti) { - // clear currentC-RNTI from map + /* Clear currentC-RNTI from map */ reestablish_rnti_map[ue_id_l][0] = 0; reestablish_rnti_map[ue_id_l][1] = 0; break; @@ -559,13 +859,15 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, pdcp_remove_UE(&ctxt); } - // Note: This should not be done in the MAC! + /* Note: This should not be done in the MAC! */ for (int ii=0; iiulsch[ii]; if((ulsch != NULL) && (ulsch->rnti == rnti)) { void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti); + clean_eNb_ulsch(ulsch); } } @@ -575,44 +877,52 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, if((dlsch != NULL) && (dlsch->rnti == rnti)) { void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti); + clean_eNb_dlsch(dlsch); } } - for(int j = 0; j < 10; j++) { + for (int j = 0; j < 10; j++) { nfapi_ul_config_request_body_t *ul_req_tmp = NULL; - ul_req_tmp = &RC.mac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body; + ul_req_tmp = &(eNB->UL_req_tmp[CC_id][j].ul_config_request_body); - if(ul_req_tmp) { + if (ul_req_tmp) { int pdu_number = ul_req_tmp->number_of_pdus; - for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) { - if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) { - LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); + for (int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) { + if (ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) { + LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", + rnti, + pdu_index, + pdu_number); - if(pdu_index < pdu_number -1) { - memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); + if (pdu_index < pdu_number -1) { + memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], + &ul_req_tmp->ul_config_pdu_list[pdu_index+1], + (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); } ul_req_tmp->number_of_pdus--; } - } - } - } + } // end for pdu_index + } // end if (ul_req_tmp) + } // end for j rrc_mac_remove_ue(module_idP,rnti); - } - } - } - } + + } // end if (UE_scheduling_control->ue_reestablishment_reject_timer >= UE_scheduling_control->ue_reestablishment_reject_timer_thres) + } // end if (UE_scheduling_control->ue_reestablishment_reject_timer > 0) + } // end if UE active + } // end for loop on UE_id #if (!defined(PRE_SCD_THREAD)) - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, - NOT_A_RNTI, frameP, subframeP, - module_idP); + + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP); pdcp_run(&ctxt); rrc_rx_tx(&ctxt, CC_id); + #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -625,79 +935,84 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, } #endif - static int debug_flag=0; - void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe)=NULL; - void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag)=NULL; - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_DEFAULT) { + static int debug_flag = 0; + void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe) = NULL; + void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag) = NULL; + + if (eNB->scheduler_mode == SCHED_MODE_DEFAULT) { schedule_ulsch_p = schedule_ulsch; schedule_ue_spec_p = schedule_dlsch; - } else if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) { + } else if (eNB->scheduler_mode == SCHED_MODE_FAIR_RR) { memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select)); schedule_ulsch_p = schedule_ulsch_fairRR; schedule_ue_spec_p = schedule_ue_spec_fairRR; } - if(debug_flag==0) { - LOG_E(MAC,"SCHED_MODE=%d\n",RC.mac[module_idP]->scheduler_mode); - debug_flag=1; + if(debug_flag == 0){ + LOG_E(MAC,"SCHED_MODE = %d\n", eNB->scheduler_mode); + debug_flag = 1; } - // This schedules MIB + /* This schedules MIB */ if ((subframeP == 0) && (frameP & 3) == 0) schedule_mib(module_idP, frameP, subframeP); if (get_softmodem_params()->phy_test == 0) { - // This schedules SI for legacy LTE and eMTC starting in subframeP + /* This schedules SI for legacy LTE and eMTC starting in subframeP */ schedule_SI(module_idP, frameP, subframeP); - // This schedules Paging in subframeP + /* This schedules Paging in subframeP */ schedule_PCH(module_idP,frameP,subframeP); - // This schedules Random-Access for legacy LTE and eMTC starting in subframeP + /* This schedules Random-Access for legacy LTE and eMTC starting in subframeP */ schedule_RA(module_idP, frameP, subframeP); - // copy previously scheduled UL resources (ULSCH + HARQ) + /* Copy previously scheduled UL resources (ULSCH + HARQ) */ copy_ulreq(module_idP, frameP, subframeP); - // This schedules SRS in subframeP + /* This schedules SRS in subframeP */ schedule_SRS(module_idP, frameP, subframeP); - // This schedules ULSCH in subframeP (dci0) + /* This schedules ULSCH in subframeP (dci0) */ if (schedule_ulsch_p != NULL) { schedule_ulsch_p(module_idP, frameP, subframeP); } else { - LOG_E(MAC," %s %d: schedule_ulsch_p is NULL, function not called\n",__FILE__,__LINE__); + LOG_E(MAC," %s %d: schedule_ulsch_p is NULL, function not called\n", + __FILE__, + __LINE__); } - // This schedules UCI_SR in subframeP + /* This schedules UCI_SR in subframeP */ schedule_SR(module_idP, frameP, subframeP); - // This schedules UCI_CSI in subframeP + /* This schedules UCI_CSI in subframeP */ schedule_CSI(module_idP, frameP, subframeP); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - // This schedules DLSCH in subframeP + /* This schedules DLSCH in subframeP for BR UE*/ schedule_ue_spec_br(module_idP, frameP, subframeP); #endif - - // This schedules DLSCH in subframeP + /* This schedules DLSCH in subframeP */ if (schedule_ue_spec_p != NULL) { schedule_ue_spec_p(module_idP, frameP, subframeP, mbsfn_status); } else { - LOG_E(MAC," %s %d: schedule_ue_spec_p is NULL, function not called\n",__FILE__,__LINE__); + LOG_E(MAC," %s %d: schedule_ue_spec_p is NULL, function not called\n", + __FILE__, + __LINE__); } + } else { schedule_ulsch_phy_test(module_idP,frameP,subframeP); schedule_ue_spec_phy_test(module_idP,frameP,subframeP,mbsfn_status); } - // Allocate CCEs for good after scheduling is done + /* Allocate CCEs for good after scheduling is done */ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if(cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) + if (cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) { allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); + } } if (flexran_agent_get_mac_xface(module_idP) && subframeP == 9) { flexran_agent_slice_update(module_idP); } - stop_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_OUT); + stop_meas(&(eNB->eNB_scheduler)); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index fa0aaec3f0..90afc0a00c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -329,6 +329,9 @@ void generate_Msg2(module_id_t module_idP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + + LOG_E(MAC, "start_symbol = %d \n", dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index bf5cfef0c3..95e2bf59e8 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -450,6 +450,9 @@ void getRepetition(UE_TEMPLATE *pue_template,unsigned int *maxRep, unsigned int } //------------------------------------------------------------------------------ +/* +* Schedule the DLSCH +*/ void schedule_ue_spec(module_id_t module_idP, int slice_idxP, @@ -470,7 +473,7 @@ schedule_ue_spec(module_id_t module_idP, int TBS, j, padding = 0, post_padding = 0; rnti_t rnti; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - int round = 0; + int round_DL = 0; int harq_pid = 0; uint16_t release_num; uint8_t ra_ii; @@ -556,14 +559,13 @@ schedule_ue_spec(module_id_t module_idP, } } - //weight = get_ue_weight(module_idP,UE_id); aggregation = 2; for (CC_id = 0, eNB_stats = &eNB->eNB_stats[0]; CC_id < nb_mac_CC; CC_id++, eNB_stats++) { dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth; N_RB_DL[CC_id] = to_prb(dl_Bandwidth); - min_rb_unit[CC_id] = get_min_rb_unit(module_idP, - CC_id); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; @@ -595,14 +597,6 @@ schedule_ue_spec(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - //RC.mac[module_idP]->slice_info.slice_counter--; - // Do the multiplexing and actual allocation only when all slices have been pre-processed. - //if (RC.mac[module_idP]->slice_info.slice_counter > 0) { - //stop_meas(&eNB->schedule_dlsch); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - //return; - //} - if (RC.mac[module_idP]->slice_info.interslice_share_active) { dlsch_scheduler_interslice_multiplexing(module_idP, frameP, @@ -628,12 +622,15 @@ schedule_ue_spec(module_id_t module_idP, LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", CC_id, UE_id); + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs rnti = UE_RNTI(module_idP, UE_id); ue_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; ue_template = &UE_list->UE_template[CC_id][UE_id]; - if (ue_template->rach_resource_type > 0) continue_flag = 1; + if (ue_template->rach_resource_type > 0) { + continue_flag = 1; + } if (&(UE_list->eNB_UE_stats[CC_id][UE_id]) == NULL) { LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); @@ -714,11 +711,11 @@ schedule_ue_spec(module_id_t module_idP, harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frameP, subframeP); - round = ue_sched_ctrl->round[CC_id][harq_pid]; + round_DL = ue_sched_ctrl->round[CC_id][harq_pid]; eNB_UE_stats->crnti = rnti; eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); eNB_UE_stats->harq_pid = harq_pid; - eNB_UE_stats->harq_round = round; + eNB_UE_stats->harq_round = round_DL; if (eNB_UE_stats->rrc_status < RRC_CONNECTED) { LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", @@ -752,24 +749,38 @@ schedule_ue_spec(module_id_t module_idP, LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", module_idP, - frameP, UE_id, + frameP, + UE_id, CC_id, rnti, harq_pid, - round, + round_DL, nb_available_rb, ue_sched_ctrl->dl_cqi[CC_id], eNB_UE_stats->dlsch_mcs1, eNB_UE_stats->rrc_status); - /* process retransmission */ - if (round != 8) { + /* Process retransmission */ + if (round_DL != 8) { // get freq_allocation nb_rb = ue_template->nb_rb[harq_pid]; TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid], nb_rb); if (nb_rb <= nb_available_rb) { + /* CDRX */ + ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer + + if (ue_sched_ctrl->cdrx_configured) { + ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission + /* + * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop. + */ + if (harq_pid == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]); + } + } + if (cc[CC_id].tdd_Config != NULL) { ue_template->DAI++; update_ul_dci(module_idP, @@ -809,14 +820,6 @@ schedule_ue_spec(module_id_t module_idP, } nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctrl->dl_pow_off[CC_id]; - - for(j = 0; j < N_RBG[CC_id]; ++j) { - eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = ue_template->rballoc_subband[harq_pid][j]; - } - */ switch (get_tmode(module_idP, CC_id, UE_id)) { case 1: @@ -845,7 +848,7 @@ schedule_ue_spec(module_id_t module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ue_template->oldNDI[harq_pid]; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = ue_template->oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round_DL & 3; // TDD if (cc[CC_id].tdd_Config != NULL) { @@ -854,7 +857,7 @@ schedule_ue_spec(module_id_t module_idP, module_idP, CC_id, harq_pid, - round, + round_DL, ue_template->DAI - 1, ue_template->oldmcs1[harq_pid]); } else { @@ -862,7 +865,7 @@ schedule_ue_spec(module_id_t module_idP, module_idP, CC_id, harq_pid, - round, + round_DL, ue_template->oldmcs1[harq_pid]); } @@ -886,7 +889,7 @@ schedule_ue_spec(module_id_t module_idP, 0, // virtual_resource_block_assignment_flag, unused here 0, // resource_block_coding, to be filled in later getQm(ue_template->oldmcs1[harq_pid]), - round & 3, // redundancy version + round_DL & 3, // redundancy version 1, // transport blocks 0, // transport block to codeword swap flag cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme @@ -903,7 +906,7 @@ schedule_ue_spec(module_id_t module_idP, 0); // number of beamforming vectors, not used here LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", eNB->pdu_index[CC_id], - round); + round_DL); program_dlsch_acknak(module_idP, CC_id, UE_id, @@ -938,7 +941,8 @@ schedule_ue_spec(module_id_t module_idP, CC_id, UE_id); } - } else { /* This is a potentially new SDU opportunity */ + } else { + /* This is a potentially new SDU opportunity */ rlc_status.bytes_in_buffer = 0; // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request @@ -1245,6 +1249,7 @@ schedule_ue_spec(module_id_t module_idP, header_length_total += header_length_last; num_sdus++; ue_sched_ctrl->uplane_inactivity_timer = 0; + // reset RRC inactivity timer after uplane activity ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); @@ -1262,7 +1267,7 @@ schedule_ue_spec(module_id_t module_idP, } } - /* last header does not have length field */ + /* Last header does not have length field */ if (header_length_total) { header_length_total -= header_length_last; header_length_total++; @@ -1568,6 +1573,22 @@ schedule_ue_spec(module_id_t module_idP, dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + /* CDRX */ + ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer + + if (ue_sched_ctrl->cdrx_configured) { + ue_sched_ctrl->drx_inactivity_timer = 1; // restart drx inactivity timer when new transmission + ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission + /* + * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop. + */ + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) ue_sched_ctrl->drx_inactivity_timer); + if (harq_pid == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]); + } + } + // Toggle NDI for next time LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", CC_id, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 0d6b319f9b..0385ae6730 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -350,9 +350,10 @@ subframe2harqpid(COMMON_channels_t *cc, sub_frame_t subframe) //------------------------------------------------------------------------------ { - uint8_t ret = 255; AssertFatal(cc != NULL, "cc is null\n"); + uint8_t ret = 255; + if (cc->tdd_Config == NULL) { // FDD ret = (((frame << 1) + subframe) & 7); } else { @@ -590,39 +591,27 @@ is_UL_sf(COMMON_channels_t *ccP, break; case 3: - if ((subframeP <= 1) || (subframeP >= 5)) - return (0); - else if ((subframeP > 1) && (subframeP < 5)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); + if (subframeP <= 1 || subframeP >= 5) + return 0; - break; + return 1; case 4: - if ((subframeP <= 1) || (subframeP >= 4)) - return (0); - else if ((subframeP > 1) && (subframeP < 4)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); + if (subframeP <= 1 || subframeP >= 4) + return 0; - break; + return 1; case 5: - if ((subframeP <= 1) || (subframeP >= 3)) - return (0); - else if ((subframeP > 1) && (subframeP < 3)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); + if (subframeP <= 1 || subframeP >= 3) + return 0; - break; + return 1; default: - AssertFatal(1 == 0, - "subframe %d Unsupported TDD configuration %d\n", - subframeP, (int) ccP->tdd_Config->subframeAssignment); + AssertFatal(1 == 0, "subframe %d Unsupported TDD configuration %d\n", + subframeP, + (int) ccP->tdd_Config->subframeAssignment); break; } @@ -864,6 +853,10 @@ get_srs_pos(COMMON_channels_t *cc, } //------------------------------------------------------------------------------ +/* +* Get some CSI (CQI/PMI/RI) parameters for SFN and subframe number calculation +* with periodic report. +*/ void get_csi_params(COMMON_channels_t *cc, struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic, @@ -899,19 +892,22 @@ get_csi_params(COMMON_channels_t *cc, *Npd = 160; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 157; } else if (cqi_PMI_ConfigIndex > 317) { - if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period - *Npd = 32; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; - } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period - *Npd = 64; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; - } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period - *Npd = 128; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; + + if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period + *Npd = 32; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; + } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period + *Npd = 64; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; + } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period + *Npd = 128; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; } + } - } else { // TDD - if (cqi_PMI_ConfigIndex == 0) { // all UL subframes + + } else { // TDD + if (cqi_PMI_ConfigIndex == 0) { // all UL subframes *Npd = 1; *N_OFFSET_CQI = 0; } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period @@ -1150,7 +1146,8 @@ fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t vrb_flag) //------------------------------------------------------------------------------ { - memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; @@ -1427,7 +1424,6 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ else harq_information_rel10->harq_size = 1; } - break; default: // for any other TM we need 2 bits harq @@ -1442,7 +1438,6 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ else harq_information_rel10->harq_size = 2; } - break; } // get Tmode @@ -1587,7 +1582,7 @@ fill_nfapi_uci_acknak(module_id_t module_idP, ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rntiP; fill_nfapi_harq_information(module_idP, CC_idP, @@ -1606,6 +1601,7 @@ fill_nfapi_uci_acknak(module_id_t module_idP, ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req->sfn_sf = (ackNAK_absSF/10) << 4 | ackNAK_absSF%10; + return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); } @@ -1713,7 +1709,9 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd uint8_t ul_tx_mode, uint8_t current_tx_nb, uint8_t n_srs, - uint16_t size) { + uint16_t size) +//------------------------------------------------------------------------------ +{ uint8_t ri_size = 0; memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; @@ -2113,22 +2111,23 @@ get_aggregation(uint8_t bw_index, } //------------------------------------------------------------------------------ +/* + * Dump the UL or DL UE_list into LOG_T(MAC) + */ void dump_ue_list(UE_list_t *listP, int ul_flag) //------------------------------------------------------------------------------ { - int j; - if (ul_flag == 0) { - for (j = listP->head; j >= 0; j = listP->next[j]) { - LOG_T(MAC, "node %d => %d\n", + for (int j = listP->head; j >= 0; j = listP->next[j]) { + LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]); } } else { - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - LOG_T(MAC, "node %d => %d\n", + for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + LOG_T(MAC, "UL list node %d => %d\n", j, listP->next_ul[j]); } @@ -2220,17 +2219,18 @@ add_new_ue(module_id_t mod_idP, } //------------------------------------------------------------------------------ +/* + * Remove MAC context of UE + */ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int j; UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - int UE_id = find_UE_id(mod_idP, - rntiP); - int pCC_id; - eNB_UE_STATS *ue_stats; + int UE_id = find_UE_id(mod_idP, rntiP); + eNB_UE_STATS *ue_stats = NULL; + int pCC_id = -1; if (UE_id == -1) { LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", @@ -2238,45 +2238,49 @@ rrc_mac_remove_ue(module_id_t mod_idP, return 0; } - pCC_id = UE_PCCID(mod_idP, - UE_id); + pCC_id = UE_PCCID(mod_idP, UE_id); + LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n", UE_id, pCC_id, rntiP); - dump_ue_list(UE_list, - 0); + + dump_ue_list(UE_list, 0); // DL list displayed in LOG_T(MAC) + UE_list->active[UE_id] = FALSE; UE_list->num_UEs--; - if (UE_list->head == UE_id) UE_list->head = UE_list->next[UE_id]; - else UE_list->next[prev(UE_list, - UE_id, - 0)] = UE_list->next[UE_id]; + /* If present, remove UE from DL list */ + if (UE_list->head == UE_id) { + UE_list->head = UE_list->next[UE_id]; + } else { + int previous = prev(UE_list, UE_id, 0); - if (UE_list->head_ul == UE_id) UE_list->head_ul = UE_list->next_ul[UE_id]; - else UE_list->next_ul[prev(UE_list, - UE_id, - 0)] = UE_list->next_ul[UE_id]; + if (previous != -1) { + UE_list->next[previous] = UE_list->next[UE_id]; + } + } - // clear all remaining pending transmissions - /* UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0; + /* If present, remove UE from UL list */ + if (UE_list->head_ul == UE_id) { + UE_list->head_ul = UE_list->next_ul[UE_id]; + } else { + int previous = prev(UE_list, UE_id, 1); - UE_list->UE_template[pCC_id][UE_id].ul_SR = 0; - UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI; - UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE; - */ - memset (&UE_list->UE_template[pCC_id][UE_id], + if (previous != -1) { + UE_list->next_ul[previous] = UE_list->next_ul[UE_id]; + } + } + + /* Clear all remaining pending transmissions */ + memset(&UE_list->UE_template[pCC_id][UE_id], 0, sizeof(UE_TEMPLATE)); ue_stats = &UE_list->eNB_UE_stats[pCC_id][UE_id]; ue_stats->total_rbs_used = 0; ue_stats->total_rbs_used_retx = 0; - for ( j = 0; j < NB_RB_MAX; j++ ) { + for (int j = 0; j < NB_RB_MAX; j++ ) { ue_stats->num_pdu_tx[j] = 0; ue_stats->num_bytes_tx[j] = 0; } @@ -2287,7 +2291,7 @@ rrc_mac_remove_ue(module_id_t mod_idP, ue_stats->total_num_pdus = 0; ue_stats->total_rbs_used_rx = 0; - for ( j = 0; j < NB_RB_MAX; j++ ) { + for (int j = 0; j < NB_RB_MAX; j++ ) { ue_stats->num_pdu_rx[j] = 0; ue_stats->num_bytes_rx[j] = 0; } @@ -2296,11 +2300,13 @@ rrc_mac_remove_ue(module_id_t mod_idP, ue_stats->total_pdu_bytes_rx = 0; ue_stats->total_num_pdus_rx = 0; ue_stats->total_num_errors_rx = 0; - eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; + + eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; + + eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; // check if this has an RA process active @@ -2342,20 +2348,21 @@ rrc_mac_remove_ue(module_id_t mod_idP, } //------------------------------------------------------------------------------ +/* + * Returns the previous UE_id in the scheduling list in UL or DL + */ int prev(UE_list_t *listP, int nodeP, int ul_flag) //------------------------------------------------------------------------------ { - int j; - if (ul_flag == 0) { if (nodeP == listP->head) { return nodeP; } - for (j = listP->head; j >= 0; j = listP->next[j]) { + for (int j = listP->head; j >= 0; j = listP->next[j]) { if (listP->next[j] == nodeP) { return j; } @@ -2365,7 +2372,7 @@ prev(UE_list_t *listP, return nodeP; } - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { if (listP->next_ul[j] == nodeP) { return j; } @@ -2519,8 +2526,8 @@ UE_is_to_be_scheduled(module_id_t module_idP, if (UE_sched_ctl->ul_failure_timer > 0 || UE_sched_ctl->ul_out_of_sync > 0) return 0; - rnti_t ue_rnti = UE_RNTI(module_idP, - UE_id); + rnti_t ue_rnti = UE_RNTI(module_idP, UE_id); + LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", module_idP, UE_id, @@ -2537,7 +2544,9 @@ UE_is_to_be_scheduled(module_id_t module_idP, module_idP, UE_id, ue_rnti, - UE_template->ul_buffer_info[LCGID0], UE_template->ul_SR); + UE_template->ul_buffer_info[LCGID0], + UE_template->ul_SR); + return 1; } @@ -2906,18 +2915,12 @@ get_nb_subband(int N_RB_DL) return nb_sb; } -/* + +//------------------------------------------------------------------------------ void -init_CCE_table(int module_idP, - int CC_idP) +init_CCE_table(int *CCE_table) +//------------------------------------------------------------------------------ { - memset(RC.mac[module_idP]->CCE_table[CC_idP], - 0, - 800 * sizeof(int)); -} -*/ -void -init_CCE_table(int *CCE_table) { memset(CCE_table, 0, 800 * sizeof(int)); } @@ -3355,7 +3358,7 @@ try_again: } } // for i = 0 ... num_DL_DCIs - // no try to allocate UL DCIs + // now try to allocate UL DCIs for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; i++) { hi_dci0_pduLoop = &hi_dci0_pdu[i]; @@ -4150,18 +4153,25 @@ extract_harq(module_id_t mod_idP, if (pdu[0] == 1) { // ACK sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an ACK, so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; + } else if (pdu[0] == 2 || pdu[0] == 4) { // NAK (treat DTX as NAK) sched_ctl->round[CC_idP][harq_pid]++; // increment round if (sched_ctl->round[CC_idP][harq_pid] == 4) { sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; } if (sched_ctl->round[CC_idP][harq_pid] == 8) { for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)) { - //Msg NACK num to MAC ,remove UE + // Msg NACK num to MAC ,remove UE // add UE info to freeList LOG_I(RRC, "put UE %x into freeList\n", rnti); @@ -4180,6 +4190,9 @@ extract_harq(module_id_t mod_idP, if (num_ack_nak == 2 && sched_ctl->round[CC_idP][harq_pid] < 8 && sched_ctl->tbcnt[CC_idP][harq_pid] == 1 && pdu[0] == 1 && pdu[1] == 1) { sched_ctl->round[CC_idP][harq_pid] = 8; sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an ACK, so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; } if ((num_ack_nak == 2) @@ -4191,6 +4204,9 @@ extract_harq(module_id_t mod_idP, if (sched_ctl->round[CC_idP][harq_pid] == 4) { sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; } } else if (((num_ack_nak == 2) && (sched_ctl->round[CC_idP][harq_pid] < 8) @@ -4206,6 +4222,9 @@ extract_harq(module_id_t mod_idP, if (sched_ctl->round[CC_idP][harq_pid] == 4) { sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->tbcnt[CC_idP][harq_pid] = 0; /* TODO: do we have to set it to 0? */ + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; } } else if ((num_ack_nak == 2) && (sched_ctl->round[CC_idP][harq_pid] < 8) @@ -4216,6 +4235,9 @@ extract_harq(module_id_t mod_idP, if (sched_ctl->round[CC_idP][harq_pid] == 4) { sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; } } else AssertFatal(1 == 0, "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", @@ -5026,26 +5048,39 @@ SR_indication(module_id_t mod_idP, T_INT(rntiP)); int UE_id = find_UE_id(mod_idP, rntiP); UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *UE_scheduling_ctrl = NULL; if (UE_id != -1) { - if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < RRC_CONNECTED) { - LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", + UE_scheduling_ctrl = &(UE_list->UE_sched_ctrl[UE_id]); + + if ((UE_scheduling_ctrl->cdrx_configured == TRUE) && + (UE_scheduling_ctrl->dci0_ongoing_timer > 0) && + (UE_scheduling_ctrl->dci0_ongoing_timer < 8)) { + LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d. \ + The SR is not set do to ongoing DCI0 with CDRX activated\n", mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + } else { + if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < RRC_CONNECTED) { + LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", + mod_idP, + rntiP, + frameP, + subframeP, + UE_id, + cc_idP); + } + UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; + UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); } - - UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; - UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); } else { - // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); - // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n", + LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UE_id) on CC_id %d\n", mod_idP, rntiP, frameP, @@ -5053,7 +5088,7 @@ SR_indication(module_id_t mod_idP, UE_id, cc_idP); } - + return; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 84ae0b0437..4f1f431508 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -121,6 +121,9 @@ rx_sdu(const module_id_t enb_mod_idP, eNB_MAC_INST *mac = NULL; UE_list_t *UE_list = NULL; rrc_eNB_ue_context_t *ue_contextP = NULL; + UE_sched_ctrl *UE_scheduling_control = NULL; + UE_TEMPLATE *UE_template_ptr = NULL; + /* Init */ current_rnti = rntiP; UE_id = find_UE_id(enb_mod_idP, current_rnti); @@ -143,42 +146,47 @@ rx_sdu(const module_id_t enb_mod_idP, } if (UE_id != -1) { + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", enb_mod_idP, harq_pid, CC_idP, frameP, subframeP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + UE_scheduling_control->round_UL[CC_idP][harq_pid], current_rnti, UE_id, ul_cqi); - AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + + AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); if (sduP != NULL) { - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; + UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); /* Update with smoothing: 3/4 of old value and 1/4 of new. * This is the logic that was done in the function * lte_est_timing_advance_pusch, maybe it's not necessary? * maybe it's even not correct at all? */ - UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; - UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; - first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; + UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; + UE_scheduling_control->ul_consecutive_errors = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + first_rb = UE_template_ptr->first_rb_ul[harq_pid]; + + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, current_rnti); } /* Update bytes to schedule */ - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; - if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) { - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; + if (UE_template_ptr->scheduled_ul_bytes < 0) { + UE_template_ptr->scheduled_ul_bytes = 0; } } else { // sduP == NULL => error LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n", @@ -187,44 +195,58 @@ rx_sdu(const module_id_t enb_mod_idP, CC_idP, frameP, subframeP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + UE_scheduling_control->round_UL[CC_idP][harq_pid], ul_cqi, UE_id, current_rnti); if (ul_cqi > 200) { // too high energy pattern - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; + UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; LOG_W(MAC, "[MAC] Too high energy pattern\n"); } - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + if (UE_scheduling_control->round_UL[CC_idP][harq_pid] == 3) { + UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); + UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) { - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + if (UE_scheduling_control->ul_consecutive_errors++ == 10) { + UE_scheduling_control->ul_failure_timer = 1; } /* Update scheduled bytes */ - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; - if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) { - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; + if (UE_template_ptr->scheduled_ul_bytes < 0) { + UE_template_ptr->scheduled_ul_bytes = 0; } if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } } else { - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; + UE_scheduling_control->round_UL[CC_idP][harq_pid]++; } - first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + /* CDRX UL HARQ timers */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + /* Synchronous UL HARQ */ + UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; + /* + * The NACK is programmed in n+4 subframes, so UE will have drxRetransmission running. + * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer. + * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer. + * Start corresponding CDRX ULRetransmission timer. + */ + } + + first_rb = UE_template_ptr->first_rb_ul[harq_pid]; + /* Program NACK for PHICH */ LOG_D(MAC, "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n", current_rnti, harq_pid, first_rb); + nfapi_hi_dci0_request_t *hi_dci0_req = NULL; uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP + sf_ahead_dl) % 10]; @@ -238,9 +260,9 @@ rx_sdu(const module_id_t enb_mod_idP, hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 0); hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; return; } @@ -279,7 +301,7 @@ rx_sdu(const module_id_t enb_mod_idP, if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } else { - // first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; // UE_id = -1 !!!! + // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! ra->msg3_round++; /* Prepare handling of retransmission */ get_Msg3allocret(&mac->common_channels[CC_idP], @@ -337,7 +359,7 @@ rx_sdu(const module_id_t enb_mod_idP, mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; if (UE_id != -1) { - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; } /* Control element */ @@ -353,19 +375,20 @@ rx_sdu(const module_id_t enb_mod_idP, switch (rx_ces[i]) { // implement and process PHR + CRNTI + BSR case POWER_HEADROOM: if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_list->UE_template[CC_idP][UE_id].nb_rb_ul[harq_pid] - 1] / 100); + UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100); - if (UE_list->UE_template[CC_idP][UE_id].phr_info > 40) { - UE_list->UE_template[CC_idP][UE_id].phr_info = 40; + if (UE_template_ptr->phr_info > 40) { + UE_template_ptr->phr_info = 40; } LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].phr_info); - UE_list->UE_template[CC_idP][UE_id].phr_info_configured = 1; - UE_list->UE_sched_ctrl[UE_id].phr_received = 1; + UE_template_ptr->phr_info); + + UE_template_ptr->phr_info_configured = 1; + UE_scheduling_control->phr_received = 1; } payload_ptr += sizeof(POWER_HEADROOM_CMD); @@ -388,26 +411,39 @@ rx_sdu(const module_id_t enb_mod_idP, /* Receiving CRNTI means that the current rnti has to go away */ if (old_UE_id != -1) { if (mac_eNB_get_rrc_status(enb_mod_idP,old_rnti) == RRC_HO_EXECUTION) { - LOG_I(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n", - enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id); + LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n", + enb_mod_idP, + frameP, + subframeP, + CC_idP, + old_rnti, + old_UE_id); + UE_id = old_UE_id; current_rnti = old_rnti; - //clear timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + /* Clear timer */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, old_rnti); + UE_scheduling_control->uplane_inactivity_timer = 0; + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; + + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, + CC_idP, + frameP, + subframeP, + old_rnti); } - - UE_list->UE_template[CC_idP][UE_id].ul_SR = 1; - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1; + UE_template_ptr->ul_SR = 1; + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; UE_list->UE_template[UE_PCCID(enb_mod_idP, UE_id)][UE_id].configured = 1; - cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); + cancel_ra_proc(enb_mod_idP, + CC_idP, + frameP, + current_rnti); } else { /* TODO: if the UE did random access (followed by a MAC uplink with * CRNTI) because none of its scheduling request was granted, then @@ -451,19 +487,21 @@ rx_sdu(const module_id_t enb_mod_idP, ra->rnti = old_rnti; ra->crnti_rrc_mui = rrc_eNB_mui-1; ra->crnti_harq_pid = -1; - /* Clear timer */ - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + /* Clear timer */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + + UE_scheduling_control->uplane_inactivity_timer = 0; + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; + + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti); } - - UE_list->UE_template[CC_idP][UE_id].ul_SR = 1; - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1; + UE_template_ptr->ul_SR = 1; + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; // break; } } @@ -491,20 +529,21 @@ rx_sdu(const module_id_t enb_mod_idP, bsr = payload_ptr[0] & 0x3f; lcgid_updated[lcgid] = 1; /* Update buffer info */ - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + UE_template_ptr->ul_buffer_info[lcgid] = BSR_TABLE[bsr]; + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[LCGID0] + + UE_template_ptr->ul_buffer_info[LCGID1] + + UE_template_ptr->ul_buffer_info[LCGID2] + + UE_template_ptr->ul_buffer_info[LCGID3]; + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); if (UE_id == UE_list->head) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, (payload_ptr[0] & 0x3f)); } - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { + UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; } if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) { @@ -512,8 +551,8 @@ rx_sdu(const module_id_t enb_mod_idP, enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer, - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); + UE_template_ptr->estimated_ul_buffer, + UE_template_ptr->ul_buffer_info[lcgid]); } } else { /* Need error message */ @@ -533,23 +572,25 @@ rx_sdu(const module_id_t enb_mod_idP, lcgid_updated[LCGID2] = 1; lcgid_updated[LCGID3] = 1; /* Update buffer info */ - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + UE_template_ptr->ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; + UE_template_ptr->ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; + UE_template_ptr->ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; + UE_template_ptr->ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; + + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[LCGID0] + + UE_template_ptr->ul_buffer_info[LCGID1] + + UE_template_ptr->ul_buffer_info[LCGID2] + + UE_template_ptr->ul_buffer_info[LCGID3]; + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = %u LCGID2 = %u LCGID3 = %u\n", - enb_mod_idP, - CC_idP, - rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); + enb_mod_idP, + CC_idP, + rx_ces[i], + UE_template_ptr->ul_buffer_info[LCGID0], + UE_template_ptr->ul_buffer_info[LCGID1], + UE_template_ptr->ul_buffer_info[LCGID2], + UE_template_ptr->ul_buffer_info[LCGID3]); if (crnti_rx == 1) { LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received CRNTI.\n", @@ -559,10 +600,10 @@ rx_sdu(const module_id_t enb_mod_idP, } for(int lcgid = 0; lcgid <= LCGID3; lcgid++) { - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + if (UE_template_ptr->ul_buffer_info[lcgid] == 0) { + UE_template_ptr->ul_buffer_creation_time[lcgid] = 0; + } else if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { + UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; } } } @@ -660,6 +701,9 @@ rx_sdu(const module_id_t enb_mod_idP, frameP, ra->rnti, UE_id); + + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); } } else { LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", @@ -713,7 +757,7 @@ rx_sdu(const module_id_t enb_mod_idP, ra->Msg4_subframe = (subframeP + 4) % 10; } - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 0; } // if RA process is active break; @@ -731,19 +775,19 @@ rx_sdu(const module_id_t enb_mod_idP, #endif if (UE_id != -1) { - if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { + if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { /* Adjust buffer occupancy of the correponding logical channel group */ - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[0] + + UE_template_ptr->ul_buffer_info[1] + + UE_template_ptr->ul_buffer_info[2] + + UE_template_ptr->ul_buffer_info[3]; + //UE_template_ptr->estimated_ul_buffer += UE_template_ptr->estimated_ul_buffer / 4; } LOG_D(MAC, @@ -789,21 +833,21 @@ rx_sdu(const module_id_t enb_mod_idP, rx_lengths[i], UE_id, rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); + UE_template_ptr->lcgidmap[rx_lcids[i]], + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]]); - if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { + if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; } else { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; } - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[0] + + UE_template_ptr->ul_buffer_info[1] + + UE_template_ptr->ul_buffer_info[2] + + UE_template_ptr->ul_buffer_info[3]; } if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block @@ -811,7 +855,8 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; /* Clear uplane_inactivity_timer */ - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + UE_scheduling_control->uplane_inactivity_timer = 0; + /* Reset RRC inactivity timer after uplane activity */ ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti); @@ -848,11 +893,26 @@ rx_sdu(const module_id_t enb_mod_idP, payload_ptr += rx_lengths[i]; } + /* CDRX UL HARQ timers */ + if (UE_id != -1) { + if (UE_scheduling_control->cdrx_configured == TRUE) { + /* Synchronous UL HARQ */ + UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; + /* + * The ACK is programmed in n+4 subframes, so UE will have drxRetransmission running. + * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer. + * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer + * Stop corresponding CDRX ULRetransmission timer + */ + } + } + /* Program ACK for PHICH */ LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", current_rnti, harq_pid, first_rb); + nfapi_hi_dci0_request_t *hi_dci0_req; uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; @@ -1245,15 +1305,15 @@ schedule_ulsch(module_id_t module_idP, //----------------------------------------------------------------------------- /* - * Default scheduler for ULSCH (DCI0) - */ +* Schedule the DCI0 for ULSCH +*/ void -schedule_ulsch_rnti(module_id_t module_idP, - int slice_idx, - frame_t frameP, - sub_frame_t subframeP, +schedule_ulsch_rnti(module_id_t module_idP, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, unsigned char sched_subframeP, - uint16_t *first_rb) + uint16_t *first_rb) //----------------------------------------------------------------------------- { rnti_t rnti = -1; @@ -1327,7 +1387,8 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_list->first_rb_offset[CC_id][slice_idx] = cmin(n_rb_ul_tab[CC_id], sli->ul[slice_idx].first_rb); } - /* ULSCH preprocessor: set UE_template-> + /* + * ULSCH preprocessor: set UE_template-> * pre_allocated_nb_rb_ul[slice_idx] * pre_assigned_mcs_ul * pre_allocated_rb_table_index_ul @@ -1343,7 +1404,7 @@ schedule_ulsch_rnti(module_id_t module_idP, if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) { continue; } - + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].rach_resource_type > 0) continue; // don't schedule if Msg5 is not received yet @@ -1397,7 +1458,7 @@ schedule_ulsch_rnti(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer); /* - * If there is information on bsr of DCCH, DTCH or if there is UL_SR, + * If there is information on BSR of DCCH, DTCH or if there is UL_SR, * or if there is a packet to retransmit, or we want to schedule a periodic feedback */ if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) { @@ -1413,7 +1474,8 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_sched_ctrl_ptr->ul_inactivity_timer, UE_sched_ctrl_ptr->ul_failure_timer, UE_sched_ctrl_ptr->cqi_req_timer); - // reset the scheduling request + + /* Reset the scheduling request */ UE_template_ptr->ul_SR = 0; status = mac_eNB_get_rrc_status(module_idP, rnti); @@ -1445,7 +1507,7 @@ schedule_ulsch_rnti(module_id_t module_idP, continue; } - + /* Handle the aperiodic CQI report */ cqi_req = 0; @@ -1542,6 +1604,14 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid]; + /* CDRX */ + if (UE_sched_ctrl_ptr->cdrx_configured) { + UE_sched_ctrl_ptr->drx_inactivity_timer = 1; // reset drx inactivity timer when new transmission + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_sched_ctrl_ptr->drx_inactivity_timer); + UE_sched_ctrl_ptr->dci0_ongoing_timer = 1; // when set the UE_template_ptr->ul_SR cannot be set to 1, + // see definition for more information + } + if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) { rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul; } else { @@ -1677,7 +1747,6 @@ schedule_ulsch_rnti(module_id_t module_idP, 1, // repetition_number (frameP * 10) + subframeP); } - #endif if (dlsch_flag == 1) { @@ -1784,7 +1853,6 @@ schedule_ulsch_rnti(module_id_t module_idP, 0, // n_srs UE_template_ptr->TBS_UL[harq_pid]); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - /* This is a BL/CE UE allocation */ if (UE_template_ptr->rach_resource_type > 0) { fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], @@ -1793,7 +1861,6 @@ schedule_ulsch_rnti(module_id_t module_idP, 1, // repetition_number (frameP * 10) + subframeP); } - #endif if(dlsch_flag == 1) { @@ -1904,7 +1971,9 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, UE_template = &(UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]); /* LTE-M device */ - if (UE_template->rach_resource_type == 0) continue; + if (UE_template->rach_resource_type == 0) { + continue; + } /* Don't schedule if Msg4 is not received yet */ if (UE_template->configured == FALSE) { diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 2b436a0a04..0ac3a32fa8 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -553,6 +553,7 @@ typedef struct { uint16_t serving_num; UE_ULSCH_STATUS status; } eNB_ULSCH_INFO; + /*! \brief temp struct for DLSCH sched */ typedef struct { rnti_t rnti; @@ -561,6 +562,7 @@ typedef struct { uint16_t serving_num; UE_DLSCH_STATUS status; } eNB_DLSCH_INFO; + /*! \brief eNB overall statistics */ typedef struct { /// num BCCH PDU per CC @@ -635,6 +637,7 @@ typedef struct { int missed_deadlines; } eNB_STATS; + /*! \brief eNB statistics for the connected UEs*/ typedef struct { /// CRNTI of UE @@ -778,6 +781,7 @@ typedef struct { } eNB_UE_STATS; /*! \brief eNB template for UE context information */ + typedef struct { /// C-RNTI of UE rnti_t rnti; @@ -998,6 +1002,62 @@ typedef struct { int32_t uplane_inactivity_timer; uint8_t crnti_reconfigurationcomplete_flag; uint8_t cqi_req_flag; + + /* HARQ RRT Timers */ + /// (UL) HARQ RTT timers, especially used for CDRX operations, one timer per cell per harq process (and per user) + uint8_t harq_rtt_timer[NFAPI_CC_MAX][8]; + uint8_t ul_harq_rtt_timer[NFAPI_CC_MAX][8]; // Note: UL HARQ RTT timers are only for asynchronous HARQ processes + uint8_t ul_synchronous_harq_timer[NFAPI_CC_MAX][8]; // These timers are used for UL synchronous HARQ processes + + /* C-DRX related timers */ + /* Note: only valid for FDD and LTE UE when this comment is written (11-01-19)*/ + /// is TRUE if the cqi mask feature is activated by RRC configuration + boolean_t cqi_mask_boolean; + /// is TRUE if the following drx parameters are configured for UE + boolean_t cdrx_configured; + /* + * if TRUE, the eNB has configured the CDRX locally, but is waiting for the UE to acknowledge + * the activation. This is needed, during the RRC configuration process, when the context is + * configured on the eNB side, but not yet on the UE side... + */ + boolean_t cdrx_waiting_ack; + /* + * Is set when a ULSCH scheduling is done and run until the first corresponding transmission is done (4 subframes). + * When set, SR cannot be set for the UE. This allows OAI to avoid concidering a SR as uncompleted if the UE sends + * a SR just after a periodic DCI0 ULSCH scheduling. Without CDRX there is no problem, but with CDRX this case would + * create a lost in timers synchronization. + */ + uint8_t dci0_ongoing_timer; + /// is TRUE if the UE is in "Active Time", hence listening to PDCCH + boolean_t in_active_time; + /// OnDurationTimer + uint16_t on_duration_timer; + uint16_t on_duration_timer_thres; + /// drx-InactivityTimer + uint16_t drx_inactivity_timer; + uint16_t drx_inactivity_timer_thres; + /// is TRUE if UE is currently in short DRX cycle + boolean_t in_short_drx_cycle; + /// drxShortCycleTimer int (1..16) (number of short DRX cycles duration before long DRX cycles) + uint8_t drx_shortCycle_timer_value; + /// shortDRX-Cycle (duration of one short DRX cycle) + uint16_t short_drx_cycle_duration; + /// DRX short cycle timer before switching to long DRX cycle = drx_shortCycle_timer_value * short_drx_cycle_duration + uint16_t drx_shortCycle_timer; + uint16_t drx_shortCycle_timer_thres; + /// is TRUE if UE is currently in long DRX cycle + boolean_t in_long_drx_cycle; + /// longDRX-CycleStartOffset (long DRX cycle timer) + uint16_t drx_longCycle_timer; + uint16_t drx_longCycle_timer_thres; + /// longDRX-CycleStartOffset (offset value) + uint16_t drx_start_offset; + /// DRX retransmission timer, one per DL HARQ process + uint8_t drx_retransmission_timer[8]; + uint8_t drx_retransmission_timer_thres[8]; + /// DRX UL retransmission timer, one per UL HARQ process + /* Not implemented yet */ + /* End of C-DRX related timers */ } UE_sched_ctrl; /*! \brief eNB template for the Random access information */ @@ -1485,6 +1545,7 @@ typedef struct { int16_t bucket_size[MAX_NUM_LCID]; } UE_SCHEDULING_INFO; /*!\brief Top level UE MAC structure */ + typedef struct { uint16_t Node_id; /// RX frame counter diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index e902065ad1..457fb89031 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -1273,11 +1273,15 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]); #endif -/*Slice related functions */ +/* Slice related functions */ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); 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); + /* 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 diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 292eecbb28..e70ed082f9 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -487,21 +487,32 @@ void decode_slice_positioning(module_id_t Mod_idP, } } - -// This fuction sorts the UE in order their dlsch buffer and CQI -void -sort_UEs(module_id_t Mod_idP, - int slice_idx, - int frameP, - sub_frame_t subframeP) +//----------------------------------------------------------------------------- +/* + * This function sorts the UEs in order, depending on their dlsch buffer and CQI + */ +void sort_UEs(module_id_t Mod_idP, + int slice_idx, + int frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- { - int i; int list[MAX_MOBILES_PER_ENB]; int list_size = 0; struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx}; - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + UE_list_t *UE_list = &(RC.mac[Mod_idP]->UE_list); + UE_sched_ctrl *UE_scheduling_control = NULL; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + + UE_scheduling_control = &(UE_list->UE_sched_ctrl[i]); + + /* Check CDRX configuration and if UE is in active time for this subframe */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->in_active_time == FALSE) { + continue; + } + } if (UE_list->active[i] == TRUE && UE_RNTI(Mod_idP, i) != NOT_A_RNTI && @@ -515,8 +526,9 @@ sort_UEs(module_id_t Mod_idP, qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); if (list_size) { - for (i = 0; i < list_size - 1; ++i) + for (int i = 0; i < list_size - 1; ++i) { UE_list->next[list[i]] = list[i + 1]; + } UE_list->next[list[list_size - 1]] = -1; UE_list->head = list[0]; @@ -1666,13 +1678,14 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, uint16_t average_rbs_per_user[NFAPI_CC_MAX]; int16_t total_remaining_rbs[NFAPI_CC_MAX]; uint16_t total_ue_count[NFAPI_CC_MAX]; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - slice_info_t *sli = &RC.mac[module_idP]->slice_info; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + slice_info_t *sli = &eNB->slice_info; UE_TEMPLATE *UE_template = 0; UE_sched_ctrl *ue_sched_ctl; int N_RB_UL = 0; uint16_t available_rbs, first_rb_offset; - rnti_t rntiTable[MAX_MOBILES_PER_ENB]; // Rnti array => Add SSR 12-2018 + rnti_t rntiTable[MAX_MOBILES_PER_ENB]; // sort ues LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); @@ -1725,7 +1738,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<common_channels[CC_id].ul_Bandwidth); + N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); @@ -1802,7 +1815,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; - N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth); first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id]; @@ -2011,20 +2024,34 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) { return 0; } -void -sort_ue_ul(module_id_t module_idP, - int slice_idx, - int sched_frameP, - sub_frame_t sched_subframeP, - rnti_t *rntiTable) +//----------------------------------------------------------------------------- +/* + * This function sorts the UEs in order, depending on their ulsch buffer and CQI + */ +void sort_ue_ul(module_id_t module_idP, + int slice_idx, + int sched_frameP, + sub_frame_t sched_subframeP, + rnti_t *rntiTable) +//----------------------------------------------------------------------------- { - int i; int list[MAX_MOBILES_PER_ENB]; int list_size = 0; struct sort_ue_ul_params params = { module_idP, sched_frameP, sched_subframeP }; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + UE_sched_ctrl *UE_scheduling_control = NULL; + + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + + UE_scheduling_control = &(UE_list->UE_sched_ctrl[i]); + + /* Check CDRX configuration and if UE is in active time for this subframe */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->in_active_time == FALSE) { + continue; + } + } - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { rntiTable[i] = UE_RNTI(module_idP, i); // Valid element and is not the actual CC_id in the list if (UE_list->active[i] == TRUE && @@ -2037,13 +2064,16 @@ sort_ue_ul(module_id_t module_idP, qsort_r(list, list_size, sizeof(int), ue_ul_compare, ¶ms); - if (list_size) { // At mimimum one list element - for (i = 0; i < list_size - 1; i++) + if (list_size) { // At mimimum one list element + + for (int i = 0; i < list_size - 1; i++) { UE_list->next_ul[list[i]] = list[i + 1]; + } UE_list->next_ul[list[list_size - 1]] = -1; UE_list->head_ul = list[0]; - } else { // No element + + } else { // No element UE_list->head_ul = -1; } } diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index fb2baa9511..ad49a16cec 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -114,26 +114,25 @@ void handle_cqi(UL_IND_t *UL_info) { } void handle_harq(UL_IND_t *UL_info) { - int i; - - if (NFAPI_MODE == NFAPI_MODE_PNF && UL_info->harq_ind.harq_indication_body.number_of_harqs>0) { // PNF + if (NFAPI_MODE == NFAPI_MODE_PNF && UL_info->harq_ind.harq_indication_body.number_of_harqs > 0) { // PNF //LOG_D(PHY, "UL_info->harq_ind.harq_indication_body.number_of_harqs:%d Send to VNF\n", UL_info->harq_ind.harq_indication_body.number_of_harqs); int retval = oai_nfapi_harq_indication(&UL_info->harq_ind); - if (retval!=0) { + if (retval != 0) { LOG_E(PHY, "Failed to encode NFAPI HARQ_IND retval:%d\n", retval); } UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; + } else { - for (i=0; iharq_ind.harq_indication_body.number_of_harqs; i++) + for (int i=0; i < UL_info->harq_ind.harq_indication_body.number_of_harqs; i++) harq_indication(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->harq_ind.sfn_sf), NFAPI_SFNSF2SF(UL_info->harq_ind.sfn_sf), &UL_info->harq_ind.harq_indication_body.harq_pdu_list[i]); - UL_info->harq_ind.harq_indication_body.number_of_harqs=0; + UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; } } diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 9dfbeed61e..94a0f175d0 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -38,7 +38,7 @@ #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif //#define RRC_DATA_REQ_DEBUG @@ -53,67 +53,62 @@ mac_rrc_data_req_ue( const frame_t frameP, const rb_id_t Srb_id, const uint8_t Nb_tb, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const uint8_t eNB_index, const uint8_t mbsfn_sync_area ) //-------------------------------------------------------------------------- { - LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); - - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); - LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); + LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + + //TTN (for D2D) + if (Srb_id == SL_DISCOVERY && UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size > 0) { + memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + uint8_t Ret_size=UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size; + LOG_I(RRC,"[UE %d] Sending SL_Discovery, size %d bytes\n",Mod_idP,Ret_size); + UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size = 0; + return(Ret_size); + } - //TTN (for D2D) - if (Srb_id == SL_DISCOVERY && UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size > 0){ - memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); - uint8_t Ret_size=UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size; - LOG_I(RRC,"[UE %d] Sending SL_Discovery, size %d bytes\n",Mod_idP,Ret_size); - UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size = 0; - return(Ret_size); - } #endif - LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { - #if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; - int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); + { + MessageDef *message_p; + int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; + int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); - if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); - ccch_size = sdu_size; - } - - message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); - RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; - RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; - memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size); - RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index; - - itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); + if (ccch_size > sdu_size) { + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); + ccch_size = sdu_size; } -#endif - memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); - uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; - // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1; - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0; - // msg("[RRC][UE %d] Sending rach\n",Mod_id); - return(Ret_size); - } else { - return 0; + message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); + RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; + RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; + memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size); + RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index; + + itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } +#endif + memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); + uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; + // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1; + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0; + // msg("[RRC][UE %d] Sending rach\n",Mod_id); + return(Ret_size); + } else { + return 0; + } return(0); } @@ -127,7 +122,7 @@ mac_rrc_data_ind_ue( const sub_frame_t sub_frameP, const rnti_t rntiP, const rb_id_t srb_idP, - const uint8_t* sduP, + const uint8_t *sduP, const sdu_size_t sdu_lenP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP @@ -136,139 +131,133 @@ mac_rrc_data_ind_ue( { protocol_ctxt_t ctxt; sdu_size_t sdu_size = 0; - /* for no gcc warnings */ (void)sdu_size; - /* int si_window; */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, 0, rntiP, frameP, sub_frameP,eNB_indexP); - if(srb_idP == BCCH) { - LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + if(srb_idP == BCCH) { + LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); + if (sdu_lenP > msg_sdu_size) { + LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = sdu_lenP; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); + memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; + memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_BCCH_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; + RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } +#else + decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP, 0, 0); +#endif + } + + if(srb_idP == PCCH) { + LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP); + } + + if((srb_idP & RAB_OFFSET) == CCCH) { + if (sdu_lenP>0) { + LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); #if defined(ENABLE_ITTI) { MessageDef *message_p; - int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); + int msg_sdu_size = CCCH_SDU_SIZE; if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); sdu_size = msg_sdu_size; } else { - sdu_size = sdu_lenP; + sdu_size = sdu_lenP; } - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); - memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); - RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; - memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size); - RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_BCCH_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; - RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; - + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); + memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; + RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } #else - decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0); + SRB_INFO *Srb_info; + Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; + memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); + Srb_info->Rx_buffer.payload_size = sdu_lenP; + rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); #endif } - - if(srb_idP == PCCH) { - LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); - decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP); - } - if((srb_idP & RAB_OFFSET) == CCCH) { - if (sdu_lenP>0) { - LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = CCCH_SDU_SIZE; - - if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } else { - sdu_size = sdu_lenP; - } - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); - RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; - RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); - } -#else - SRB_INFO *Srb_info; - Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; - memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); - Srb_info->Rx_buffer.payload_size = sdu_lenP; - rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); -#endif - } - } + } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if ((srb_idP & RAB_OFFSET) == MCCH) { - LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", - module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); - + if ((srb_idP & RAB_OFFSET) == MCCH) { + LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", + module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); #if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); - if (sdu_size > msg_sdu_size) { - LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); - RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; - memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE); - memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP); - RRC_MAC_MCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + if (sdu_size > msg_sdu_size) { + LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); + RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; + memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE); + memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP); + RRC_MAC_MCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } #else - decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); + decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); #endif - } - //TTN (for D2D) - if(srb_idP == SL_DISCOVERY) { - LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %d from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); - decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); - } + } + + //TTN (for D2D) + if(srb_idP == SL_DISCOVERY) { + LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %d from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); + decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); + } #endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - return(0); - } //------------------------------------------------------------------------------ uint8_t rrc_data_req_ue( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const pdcp_transmission_mode_t modeP ) //------------------------------------------------------------------------------ @@ -283,20 +272,16 @@ rrc_data_req_ue( ctxt_pP->rnti, muiP, sdu_sizeP); - #if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). uint8_t *message_buffer; - message_buffer = itti_malloc ( ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, sdu_sizeP); - memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; @@ -309,13 +294,11 @@ rrc_data_req_ue( RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; - itti_send_msg_to_task ( TASK_PDCP_UE, ctxt_pP->instance, message_p); return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. - } #else return pdcp_data_req ( @@ -330,34 +313,30 @@ rrc_data_req_ue( #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif - ); + ); #endif } //------------------------------------------------------------------------------ void rrc_data_ind_ue( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const sdu_size_t sdu_sizeP, - const uint8_t* const buffer_pP + const uint8_t *const buffer_pP ) //------------------------------------------------------------------------------ { rb_id_t DCCH_index = Srb_id; - - LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", - ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); - + LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); #if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). uint8_t *message_buffer; - message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; @@ -366,24 +345,20 @@ rrc_data_ind_ue( RRC_DCCH_DATA_IND (message_p).rnti = ctxt_pP->rnti; RRC_DCCH_DATA_IND (message_p).module_id = ctxt_pP->module_id; RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, ctxt_pP->instance, message_p); } #else - -//#warning "LG put 0 to arg4 that is eNB index" - rrc_ue_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - 0); - + //#warning "LG put 0 to arg4 that is eNB index" + rrc_ue_decode_dcch( + ctxt_pP, + DCCH_index, + buffer_pP, + 0); #endif } //-------------------------------------------------------------------------------------------// -void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) -{ +void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { //-------------------------------------------------------------------------------------------// #if defined(ENABLE_ITTI) { @@ -392,7 +367,6 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_IN_SYNC_IND); RRC_MAC_IN_SYNC_IND (message_p).frame = frameP; RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } #else @@ -406,25 +380,22 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) } //-------------------------------------------------------------------------------------------// -void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) -{ +void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { //-------------------------------------------------------------------------------------------// if (UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt>10) LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ", - Mod_idP,frameP,eNB_index, - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active, - UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt, - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, - UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); - + Mod_idP,frameP,eNB_index, + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active, + UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt, + UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, + UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); + #if defined(ENABLE_ITTI) { MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND); RRC_MAC_OUT_OF_SYNC_IND (message_p).frame = frameP; RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } #else @@ -447,16 +418,13 @@ mac_UE_get_rrc_status( } //-------------------------------------------------------------------------------------------// -int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) -{ +int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) { //-------------------------------------------------------------------------------------------// #if defined(ENABLE_ITTI) { MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF); RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } #else diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 53e94ab828..ef43b15584 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -317,6 +317,121 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, return((enc_rval.encoded+7)/8); } +//----------------------------------------------------------------------------- +/* + * 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 *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; + } + + drxConfig = (LTE_DRX_Config_t *) malloc(sizeof(LTE_DRX_Config_t)); + if (drxConfig == NULL) return NULL; + memset(drxConfig, 0, sizeof(LTE_DRX_Config_t)); + + /* Long DRX cycle support is mandatory for CDRX activation */ + if (!ueSupportCdrxLongFlag || configuration == NULL) { + drxConfig->present = LTE_DRX_Config_PR_release; + } else { + drxConfig->present = configuration->radioresourceconfig[CC_id].drx_Config_present; + } + + 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) { + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: + drxConfig->choice.setup.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; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: + drxConfig->choice.setup.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; + break; + default: + break; + } + + /* Short DRX cycle configuration */ + if (!ueSupportCdrxShortFlag || configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer == 0) { + drxConfig->choice.setup.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; + } + } + + return drxConfig; +} uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, int Mod_id,int CC_id @@ -911,7 +1026,7 @@ uint8_t do_SIB23(uint8_t Mod_id, struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int eMTC_configured=configuration->eMTC_configured; + int eMTC_configured = configuration->eMTC_configured; struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib18_part, *sib19_part, *sib21_part; LTE_SL_CommRxPoolList_r12_t *SL_CommRxPoolList; //for SIB18 struct LTE_SL_CommResourcePool_r12 *SL_CommResourcePool; //for SIB18 @@ -2357,6 +2472,7 @@ do_RRCConnectionSetup( dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup; rrcConnectionSetup = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionSetup; + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; // RRCConnectionSetup // Configure SRB1 @@ -2475,30 +2591,34 @@ do_RRCConnectionSetup( physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0]=0x22; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1]=0x34+ue_context_pP->local_uid; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.bits_unused=0; - // CQI ReportConfig - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30; -#else - *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI -#endif - physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB - //physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=NULL; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; - /* - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex = 0; // Icqi/pmi - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present = CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI; // subband CQI - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k=4; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex=NULL; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI=0; + /* CQI ReportConfig */ + // Aperiodic configuration + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = CALLOC(1, sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = LTE_CQI_ReportModeAperiodic_rm30; // HLC CQI, no PMI +#else + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI +#endif + + physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB (int -1...6) + + // Periodic configuration + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1, sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; + /* + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex = 0; // Icqi/pmi + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present = CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI; // subband CQI + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k = 4; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex = NULL; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI = 0; */ //soundingRS-UL-ConfigDedicated - if (rrc->srs_enable[CC_id]==1) { + if (rrc->srs_enable[CC_id] == 1) { physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = LTE_SoundingRS_UL_ConfigDedicated_PR_setup; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth = LTE_SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0; @@ -2667,22 +2787,33 @@ do_RRCConnectionSetup( rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = CALLOC(1,sizeof(struct LTE_RadioResourceConfigDedicated__mac_MainConfig)); rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; - LTE_MAC_MainConfig_t *mac_MainConfig = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->choice.explicitValue; + + /* MAC MainConfig */ + mac_MainConfig = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->choice.explicitValue; + + //* ul_SCH_Config *// mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); long *maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; long *periodicBSR_Timer = CALLOC(1, sizeof(long)); - *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; - mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_infinity + + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; // max number of UL HARQ transmission mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120 // regular BSR timer mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + + //* timeAlignmentTimerDedicated *// mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; + + //* DRX Config *// mac_MainConfig->drx_Config = NULL; + + //* PHR Config *// mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; - mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // 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_sf20; // 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_dB1; // Value dB1 =1 dB, dB3 = 3 dB if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { @@ -2703,11 +2834,7 @@ do_RRCConnectionSetup( LOG_D(RRC,"RRCConnectionSetup Encoded %zd bits (%zd bytes) \n", enc_rval.encoded,(enc_rval.encoded+7)/8); - // FREEMEM(SRB_list); - // free(SRB1_config); - // free(SRB1_rlc_config); - // free(SRB1_lchan_config); - // free(SRB1_ul_SpecificParameters); + return((enc_rval.encoded+7)/8); } @@ -3422,9 +3549,12 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t* const #endif //------------------------------------------------------------------------------ -uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, - uint8_t *buffer, - uint8_t Transaction_id, +/* + * Copy the different Information Elements in the RRC structure + */ +uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, LTE_DRB_ToAddModList_t *DRB_list, LTE_DRB_ToReleaseList_t *DRB_list2, @@ -3437,7 +3567,7 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx LTE_MAC_MainConfig_t *mac_MainConfig, LTE_MeasGapConfig_t *measGapConfig, LTE_MobilityControlInfo_t *mobilityInfo, - LTE_SecurityConfigHO_t *securityConfigHO, + LTE_SecurityConfigHO_t *securityConfigHO, struct LTE_MeasConfig__speedStatePars *speedStatePars, LTE_RSRP_Range_t *rsrp, LTE_C_RNTI_t *cba_rnti, @@ -3446,7 +3576,7 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx LTE_SL_CommConfig_r12_t *sl_CommConfig, LTE_SL_DiscConfig_r12_t *sl_DiscConfig #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , LTE_SCellToAddMod_r10_t *SCell_config + , LTE_SCellToAddMod_r10_t *SCell_config #endif ) //------------------------------------------------------------------------------ @@ -3458,7 +3588,8 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; rrcConnectionReconfiguration = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration; - // RRCConnectionReconfiguration + + /* RRC Connection Reconfiguration */ rrcConnectionReconfiguration->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReconfiguration->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1; rrcConnectionReconfiguration->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8 ; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index eb9572f4d2..6e3fa6dd60 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -70,6 +70,15 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich #endif ); +/** +\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); + /** \brief Generate configuration for SIB1 (eNB). @param carrier pointer to Carrier information diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 4b7e765241..50ae019323 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -140,9 +140,9 @@ static uint8_t check_trigger_meas_event( LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); -uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, - SL_TRIGGER_t mode); + static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); + uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, + SL_TRIGGER_t mode); #endif diff --git a/openair2/RRC/LTE/rrc_UE_ral.c b/openair2/RRC/LTE/rrc_UE_ral.c index c972d280d5..d7ace8c242 100644 --- a/openair2/RRC/LTE/rrc_UE_ral.c +++ b/openair2/RRC/LTE/rrc_UE_ral.c @@ -46,8 +46,7 @@ int rrc_ue_ral_delete_all_thresholds_type(unsigned int mod_idP, ral_link_param_t rrc_ral_threshold_key_t *keys = NULL; unsigned int num_keys = 0; int return_code = 0; - - rc = obj_hashtable_get_keys(UE_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&keys, &num_keys); + rc = obj_hashtable_get_keys(UE_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&keys, &num_keys); if (rc == HASH_TABLE_OK) { key = keys; @@ -82,10 +81,9 @@ int rrc_ue_ral_delete_threshold(unsigned int mod_idP, ral_link_param_type_t *par { hashtable_rc_t rc; rrc_ral_threshold_key_t ref_key; - memcpy(&ref_key.link_param_type, param_type_pP, sizeof(ral_link_param_type_t)); memcpy(&ref_key.threshold, threshold_pP, sizeof(ral_threshold_t)); - rc = obj_hashtable_remove (UE_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&ref_key, sizeof(rrc_ral_threshold_key_t)); + rc = obj_hashtable_remove (UE_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&ref_key, sizeof(rrc_ral_threshold_key_t)); if (rc == HASH_TABLE_OK) { return 0; @@ -106,135 +104,131 @@ int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageD MessageDef *message_p = NULL; unsigned int ix_param = 0; unsigned int ix_thresholds = 0; - DevAssert(msg_pP != NULL); - LOG_I(RRC, "[UE %d] Received %s\n", mod_idP, ITTI_MSG_NAME (msg_pP)); configure_threshold_req_p = &RRC_RAL_CONFIGURE_THRESHOLD_REQ(msg_pP); - transaction_id = configure_threshold_req_p->transaction_id; for (ix_param = 0; ix_param < configure_threshold_req_p->num_link_cfg_params; ix_param++) { link_cfg_param_p = &configure_threshold_req_p->link_cfg_params[ix_param]; switch (link_cfg_param_p->th_action) { - case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: - case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: - switch (link_cfg_param_p->link_param_type.choice) { + case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: + case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: + switch (link_cfg_param_p->link_param_type.choice) { + case RAL_LINK_PARAM_TYPE_CHOICE_GEN: + switch (link_cfg_param_p->link_param_type._union.link_param_gen) { + case RAL_LINK_PARAM_GEN_DATA_RATE: + case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: + case RAL_LINK_PARAM_GEN_SINR: + case RAL_LINK_PARAM_GEN_THROUGHPUT: + case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - switch (link_cfg_param_p->link_param_type._union.link_param_gen) { - case RAL_LINK_PARAM_GEN_DATA_RATE: - case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: - case RAL_LINK_PARAM_GEN_SINR: - case RAL_LINK_PARAM_GEN_THROUGHPUT: - case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); + return -1; + } - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); - return -1; - } + break; - break; + case RAL_LINK_PARAM_TYPE_CHOICE_QOS: + switch (link_cfg_param_p->link_param_type._union.link_param_qos) { + case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: + case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: + case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - switch (link_cfg_param_p->link_param_type._union.link_param_qos) { - case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: - case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: - case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); + return -1; + } - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); - return -1; - } + break; - break; + case RAL_LINK_PARAM_TYPE_CHOICE_LTE: + switch (link_cfg_param_p->link_param_type._union.link_param_lte) { + // group by dest task id + case RAL_LINK_PARAM_LTE_UE_RSRP: + case RAL_LINK_PARAM_LTE_UE_RSRQ: + case RAL_LINK_PARAM_LTE_UE_CQI: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - switch (link_cfg_param_p->link_param_type._union.link_param_lte) { - // group by dest task id - case RAL_LINK_PARAM_LTE_UE_RSRP: - case RAL_LINK_PARAM_LTE_UE_RSRQ: - case RAL_LINK_PARAM_LTE_UE_CQI: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; + case RAL_LINK_PARAM_LTE_AVAILABLE_BW: + case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: + case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: + case RAL_LINK_PARAM_LTE_PACKET_DELAY: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_LTE_AVAILABLE_BW: - case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: - case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: - case RAL_LINK_PARAM_LTE_PACKET_DELAY: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: - case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: - case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: - case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: - case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: + case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: + case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: + case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: + case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: + case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: #warning "TO DO MIH LTE LINK PARAMS IN RRC UE" - break; + break; - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); - return -1; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); + return -1; + } + + break; + + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + return -1; } + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + } + + break; + + case RAL_TH_ACTION_CANCEL_THRESHOLD: + + // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): + // When “Cancel threshold” is selected and no thresholds are specified, then all + // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. + if (link_cfg_param_p->num_thresholds == 0) { + rrc_ue_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); + } else { + // + // When “Cancel threshold” is selected and thresholds are specified only those + // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was + // specified are cancelled. + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + rrc_ue_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); + } + } + + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ with RAL_TH_ACTION_CANCEL_THRESHOLD\n"); break; default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); return -1; - } - - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - } - - break; - - case RAL_TH_ACTION_CANCEL_THRESHOLD: - - // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): - // When “Cancel threshold” is selected and no thresholds are specified, then all - // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. - if (link_cfg_param_p->num_thresholds == 0) { - rrc_ue_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); - } else { - // - // When “Cancel threshold” is selected and thresholds are specified only those - // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was - // specified are cancelled. - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - rrc_ue_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); - } - } - - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ with RAL_TH_ACTION_CANCEL_THRESHOLD\n"); - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); - return -1; } } diff --git a/openair2/RRC/LTE/rrc_common.c b/openair2/RRC/LTE/rrc_common.c index cf0196441e..1744719308 100644 --- a/openair2/RRC/LTE/rrc_common.c +++ b/openair2/RRC/LTE/rrc_common.c @@ -55,9 +55,7 @@ rrc_init_global_param( ) //----------------------------------------------------------------------------- { - rrc_rlc_register_rrc (rrc_data_ind, NULL); //register with rlc - DCCH_LCHAN_DESC.transport_block_size = 4; DCCH_LCHAN_DESC.max_transport_blocks = 16; DCCH_LCHAN_DESC.Delay_class = 1; @@ -67,13 +65,11 @@ rrc_init_global_param( DTCH_UL_LCHAN_DESC.transport_block_size = 52; DTCH_UL_LCHAN_DESC.max_transport_blocks = 20; DTCH_UL_LCHAN_DESC.Delay_class = 1; - Rlc_info_um.rlc_mode = RLC_MODE_UM; Rlc_info_um.rlc.rlc_um_info.timer_reordering = 5; Rlc_info_um.rlc.rlc_um_info.sn_field_length = 10; Rlc_info_um.rlc.rlc_um_info.is_mXch = 0; //Rlc_info_um.rlc.rlc_um_info.sdu_discard_mode=16; - Rlc_info_am_config.rlc_mode = RLC_MODE_AM; Rlc_info_am_config.rlc.rlc_am_info.max_retx_threshold = 50; Rlc_info_am_config.rlc.rlc_am_info.poll_pdu = 8; @@ -81,20 +77,18 @@ rrc_init_global_param( Rlc_info_am_config.rlc.rlc_am_info.t_poll_retransmit = 15; Rlc_info_am_config.rlc.rlc_am_info.t_reordering = 50; Rlc_info_am_config.rlc.rlc_am_info.t_status_prohibit = 10; - return 0; } //----------------------------------------------------------------------------- void rrc_config_buffer( - SRB_INFO* Srb_info, + SRB_INFO *Srb_info, uint8_t Lchan_type, uint8_t Role ) //----------------------------------------------------------------------------- { - Srb_info->Rx_buffer.payload_size = 0; Srb_info->Tx_buffer.payload_size = 0; } @@ -200,7 +194,7 @@ static band_freq bands[] = { { BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL }, { BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL }, { BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL }, - /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL }, + /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL }, { BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL }, { BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL }, { BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL }, @@ -278,17 +272,17 @@ static earfcn earfcn_table[] = { { 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 }, { 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 }, }; - -int freq_to_arfcn10(int band, unsigned long freq) -{ - int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); + +int freq_to_arfcn10(int band, unsigned long freq) { + int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); int i; - - for (i = 0; i < N; i++) if (bands[i].band == band) break; + + for (i = 0; i < N; i++) if (bands[i].band == band) break; + if (i == N) return -1; - + if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq)) return -1; - + return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off; } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 9cbef536fc..1da374dd42 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -200,6 +200,8 @@ void *send_UE_status_notification(void *); /* for ImsiMobileIdentity_t */ #include "MobileIdentity.h" +#include "LTE_DRX-Config.h" + /* correct Rel(8|10)/Rel14 differences * the code is in favor of Rel14, those defines do the translation */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index f330399901..2f765e0030 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1118,14 +1118,18 @@ rrc_eNB_process_RRCConnectionSetupComplete( ) //----------------------------------------------------------------------------- { - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; - ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity timer when UE goes into RRC_CONNECTED + + T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); if (EPC_MODE_ENABLED == 1) { // Forward message to S1AP layer @@ -1272,129 +1276,145 @@ rrc_eNB_generate_RRCConnectionReject( } //----------------------------------------------------------------------------- +/* + * Generate a RCC Connection Reestablishment after requested + */ void rrc_eNB_generate_RRCConnectionReestablishment( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - const int CC_id -) + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const int CC_id) //----------------------------------------------------------------------------- { - LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; - LTE_SRB_ToAddModList_t **SRB_configList; - LTE_SRB_ToAddMod_t *SRB1_config; - int cnt; - T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + int UE_id = -1; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; + LTE_SRB_ToAddModList_t **SRB_configList; + LTE_SRB_ToAddMod_t *SRB1_config = NULL; + rrc_eNB_carrier_data_t *carrier = NULL; + eNB_RRC_UE_t *ue_context = NULL; - eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + module_id_t module_id = ctxt_pP->module_id; + uint16_t rnti = ctxt_pP->rnti; - SRB_configList = &ue_p->SRB_configList; + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, + T_INT(module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(rnti)); - ue_p->Srb0.Tx_buffer.payload_size = - do_RRCConnectionReestablishment(ctxt_pP, - ue_context_pP, - CC_id, - (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, - (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), - SRB_configList, - &ue_context_pP->ue_context.physicalConfigDedicated); - LOG_DUMPMSG(RRC,DEBUG_RRC, - (char *)(ue_p->Srb0.Tx_buffer.Payload), - ue_p->Srb0.Tx_buffer.payload_size, - "[MSG] RRCConnectionReestablishment\n" - ); - // configure SRB1 for UE + SRB_configList = &(ue_context_pP->ue_context.SRB_configList); + carrier = &(RC.rrc[ctxt_pP->module_id]->carrier[CC_id]); + ue_context = &(ue_context_pP->ue_context); + ue_context->Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishment(ctxt_pP, + ue_context_pP, + CC_id, + (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, + (uint8_t) carrier->p_eNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2 + rrc_eNB_get_next_transaction_identifier(module_id), + SRB_configList, + &(ue_context->physicalConfigDedicated)); + + LOG_DUMPMSG(RRC, DEBUG_RRC, + (char *)(ue_context->Srb0.Tx_buffer.Payload), + ue_context->Srb0.Tx_buffer.payload_size, + "[MSG] RRCConnectionReestablishment \n"); + + /* Configure SRB1 for UE */ if (*SRB_configList != NULL) { - for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { + for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { SRB1_config = (*SRB_configList)->list.array[cnt]; if (SRB1_config->logicalChannelConfig) { - if (SRB1_config->logicalChannelConfig->present == - LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; + if (SRB1_config->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &(SRB1_config->logicalChannelConfig->choice.explicitValue); } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue); } } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue); } - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { - rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + rrc_mac_config_req_eNB(module_id, + ue_context->primaryCC_id, + 0, + 0, + 0, + 0, + 0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif - ctxt_pP->rnti, + rnti, (LTE_BCCH_BCH_Message_t *) NULL, (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct LTE_PhysicalConfigDedicated * ) ue_context_pP->ue_context.physicalConfigDedicated, + (struct LTE_PhysicalConfigDedicated * ) ue_context->physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, + ue_context->mac_MainConfig, 1, SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, + ue_context->measGapConfig, (LTE_TDD_Config_t *) NULL, NULL, (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + ,(LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif - ); + ); break; } - } - } - } + } // if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) + } // for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) + } // if (*SRB_configList != NULL) MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_RRC_UE, - ue_p->Srb0.Tx_buffer.Header, - ue_p->Srb0.Tx_buffer.payload_size, + ue_context->Srb0.Tx_buffer.Header, + ue_context->Srb0.Tx_buffer.payload_size, MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishment UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - ue_p->Srb0.Tx_buffer.payload_size); + ue_context->rnti, + ue_context->Srb0.Tx_buffer.payload_size); - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); - if(UE_id != -1){ - // activate release timer, if RRCComplete not received after 100 frames, remove UE - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; - // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000; - } else{ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rnti); - } + ue_context->Srb0.Tx_buffer.payload_size); + + UE_id = find_UE_id(module_id, rnti); + + if (UE_id != -1) { + /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */ + RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; + /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */ + RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100; + } else { + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + rnti); } - // activate release timer, if RRCComplete not received after 100 frames, remove UE + + /* Activate release timer, if RRCComplete not received after 100 frames, remove UE */ ue_context_pP->ue_context.ue_reestablishment_timer = 1; - // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered + /* Remove UE after 100 frames after LTE_RRCConnectionReestablishmentReject is triggered */ ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000; } @@ -2717,19 +2737,22 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ buffer, PDCP_TRANSMISSION_MODE_CONTROL); } + //----------------------------------------------------------------------------- -void -rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - const uint8_t ho_state - ) +/* + * Generate the basic (first) RRC Connection Reconfiguration (non BR UE) + */ +void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const uint8_t ho_state) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE]; - uint16_t size; - int i; - // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + int i; + + /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */ + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; struct LTE_SRB_ToAddMod *SRB2_config = NULL; struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; @@ -2737,7 +2760,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters = NULL; LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; struct LTE_DRB_ToAddMod *DRB_config = NULL; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; @@ -2747,7 +2770,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; LTE_DRB_ToAddModList_t **DRB_configList = &ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; + LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; LTE_MAC_MainConfig_t *mac_MainConfig = NULL; LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; LTE_MeasObjectToAddMod_t *MeasObj = NULL; @@ -2756,27 +2779,31 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; LTE_MeasIdToAddModList_t *MeasId_list = NULL; LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - long *sr_ProhibitTimer_r9 = NULL; - // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); - //uint8_t sCellIndexToAdd = 0; + long *sr_ProhibitTimer_r9 = NULL; #endif - long *logicalchannelgroup, *logicalchannelgroup_drb; - long *maxHARQ_Tx, *periodicBSR_Timer; + + long *logicalchannelgroup = NULL; + long *logicalchannelgroup_drb = NULL; + long *maxHARQ_Tx = NULL; + long *periodicBSR_Timer = NULL; LTE_RSRP_Range_t *rsrp = NULL; struct LTE_MeasConfig__speedStatePars *Sparams = NULL; LTE_QuantityConfig_t *quantityConfig = NULL; - //LTE_CellsToAddMod_t *CellToAdd = NULL; - //LTE_CellsToAddModList_t *CellsToAddModList = NULL; - struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList + *dedicatedInfoNASList = NULL; LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; - /* for no gcc warnings */ - (void)dedicatedInfoNas; + + /* For no gcc warnings */ + (void) dedicatedInfoNas; LTE_C_RNTI_t *cba_RNTI = NULL; int x2_enabled; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, -#ifdef CBA - //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; + 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; cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t)); cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); @@ -2784,27 +2811,33 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons cba_RNTI->size = 2; cba_RNTI->bits_unused = 0; - // associate UEs to the CBa groups as a function of their UE id + /* Associate UEs to the CBA groups as a function of their UE id */ if (rrc_inst->num_active_cba_groups) { cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; cba_RNTI->buf[1] = 0xff; - LOG_D(RRC, - "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", - enb_mod_idP, frameP, + LOG_D(RRC, "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", + enb_mod_idP, + frameP, rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups], ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP); } else { cba_RNTI->buf[0] = 0x0; cba_RNTI->buf[1] = 0x0; - LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP); + LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", + enb_mod_idP, + frameP, + ue_mod_idP); } - #endif - T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // Configure SRB2 - /// SRB2 - SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); + + /* Configure SRB2 */ + SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[xid]); if (*SRB_configList2) { free(*SRB_configList2); @@ -2829,22 +2862,19 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs - SRB2_ul_SpecificParameters->prioritisedBitRate = - LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - SRB2_ul_SpecificParameters->bucketSizeDuration = - LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - // LCG for CCCH and DCCH is 0 as defined in 36331 + SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + /* LCG for CCCH and DCCH is 0 as defined in 36331 */ logicalchannelgroup = CALLOC(1, sizeof(long)); *logicalchannelgroup = 0; SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; - // this list has the configuration for SRB1 and SRB2 - ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); - // this list has only the configuration for SRB2 - ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); // this list has the configuration for SRB1 and SRB2 + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); // this list has only the configuration for SRB2 - // Configure DRB - //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); + /* Configure DRB */ // list for all the configured DRB if (*DRB_configList) { free(*DRB_configList); @@ -2852,8 +2882,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); memset(*DRB_configList, 0, sizeof(**DRB_configList)); - // list for the configured DRB for a this xid - DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + + DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; // list for the configured DRB for a this xid if (*DRB_configList2) { free(*DRB_configList2); @@ -2861,17 +2891,17 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); - /// DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 - // DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32 // NN: this is the 1st DRB for this ue, so set it to 1 DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; + #ifdef RRC_DEFAULT_RAB_IS_AM DRB_rlc_config->present = LTE_RLC_Config_PR_am; DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; @@ -2884,21 +2914,25 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + #ifdef CBA - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5;//T_Reordering_ms25; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5; //T_Reordering_ms25; #else DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; #endif + #endif + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; - /* avoid gcc warnings */ + /* Avoid gcc warnings */ (void)PDCP_rlc_AM; (void)PDCP_rlc_UM; + #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; @@ -2908,52 +2942,92 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; #endif + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; - DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - DRB_ul_SpecificParameters->bucketSizeDuration = - LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; // LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) logicalchannelgroup_drb = CALLOC(1, sizeof(long)); *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); - //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); + + /* MAC Main Config */ + // The different parts of MAC main config are set below mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + + /* BSR reconfiguration */ periodicBSR_Timer = CALLOC(1, sizeof(long)); - *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; //LTE_PeriodicBSR_Timer_r12_infinity; // LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_sf20 mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120 mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; - mac_MainConfig->drx_Config = NULL; + + /* PHR reconfiguration */ mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; - mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB + 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 + + /* 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; + } + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); - *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2 = 2*SR mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; - //sps_RA_ConfigList_rlola = NULL; #endif - //change the transmission mode for the primary component carrier - //TODO: add codebook subset restriction here - //TODO: change TM for secondary CC in SCelltoaddmodlist + // change the transmission mode for the primary component carrier + // TODO: add codebook subset restriction here + // TODO: change TM for secondary CC in SCelltoaddmodlist if (*physicalConfigDedicated) { if ((*physicalConfigDedicated)->antennaInfo) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode; @@ -3000,17 +3074,20 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } - if ((*physicalConfigDedicated)->cqi_ReportConfig) { - if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) { - //feedback mode needs to be set as well - //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable - printf("setting cqi reporting mode to rm31\n"); + /* CSI RRC Reconfiguration */ + if ((*physicalConfigDedicated)->cqi_ReportConfig != NULL) { + if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + + // feedback mode needs to be set as well + // TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + LOG_I(RRC, "Setting cqi reporting mode to rm31 (hardcoded)\n"); + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportModeAperiodic_rm31; // HLC CQI, single PMI #else - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, single PMI #endif } } else { @@ -3224,30 +3301,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; -#if 0 - LOG_I(RRC, - "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", - ctxt_pP->module_id, ctxt_pP->frame); - // store the information in an intermediate structure for Hanodver management - //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); - ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(LTE_SRB_ToAddModList_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(LTE_DRB_ToAddModList_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList; - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = - CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); - memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void *)mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = - CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t)); - memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); -#endif - //} + /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -3268,7 +3322,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; } - /* TODO should test if e RAB are Ok before! */ + + /* TODO should test if e RAB are OK before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); @@ -3283,38 +3338,35 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons x2_enabled = is_x2ap_enabled(); memset(buffer, 0, RRC_BUF_SIZE); + size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, - xid, //Transaction_id, - (LTE_SRB_ToAddModList_t *)*SRB_configList2, // SRB_configList - (LTE_DRB_ToAddModList_t *)*DRB_configList, - (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, - (struct LTE_SPS_Config *)NULL, // *sps_Config, - (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated, - //#ifdef EXMIMO_IOT - // NULL, NULL, NULL,NULL, - //#else - x2_enabled ? (LTE_MeasObjectToAddModList_t *)MeasObj_list : NULL, - x2_enabled ? (LTE_ReportConfigToAddModList_t *)ReportConfig_list : NULL, - x2_enabled ? (LTE_QuantityConfig_t *)quantityConfig : NULL, - x2_enabled ? (LTE_MeasIdToAddModList_t *)MeasId_list : NULL, - //#endif - (LTE_MAC_MainConfig_t *)mac_MainConfig, - (LTE_MeasGapConfig_t *)NULL, - (LTE_MobilityControlInfo_t *)NULL, - (LTE_SecurityConfigHO_t *)NULL, - (struct LTE_MeasConfig__speedStatePars *)Sparams, - (LTE_RSRP_Range_t *)rsrp, - (LTE_C_RNTI_t *)cba_RNTI, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t *)NULL, - (LTE_SL_DiscConfig_r12_t *)NULL + xid, // Transaction_id, + (LTE_SRB_ToAddModList_t *) *SRB_configList2, // SRB_configList + (LTE_DRB_ToAddModList_t *) *DRB_configList, + (LTE_DRB_ToReleaseList_t *) NULL, // DRB2_list, + (struct LTE_SPS_Config *) NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated *) *physicalConfigDedicated, + x2_enabled ? (LTE_MeasObjectToAddModList_t *) MeasObj_list : NULL, + x2_enabled ? (LTE_ReportConfigToAddModList_t *) ReportConfig_list : NULL, + x2_enabled ? (LTE_QuantityConfig_t *) quantityConfig : NULL, + x2_enabled ? (LTE_MeasIdToAddModList_t *) MeasId_list : NULL, + (LTE_MAC_MainConfig_t *) mac_MainConfig, + (LTE_MeasGapConfig_t *) NULL, + (LTE_MobilityControlInfo_t *) NULL, + (LTE_SecurityConfigHO_t *) NULL, + (struct LTE_MeasConfig__speedStatePars *) Sparams, + (LTE_RSRP_Range_t *) rsrp, + (LTE_C_RNTI_t *) cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *) dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *) NULL, + (LTE_SL_DiscConfig_r12_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t *)NULL + , (LTE_SCellToAddMod_r10_t *) NULL #endif ); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, - "[MSG] RRC Connection Reconfiguration\n"); + + LOG_DUMPMSG(RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Connection Reconfiguration\n"); /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { @@ -3325,30 +3377,38 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons } } - LOG_I(RRC, - "[eNB %d] Frame %d, Hello there! Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, - "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - buffer, - size, - MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - rrc_eNB_mui, - size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + size, + ue_context_pP->ue_context.rnti); + + LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + ctxt_pP->module_id, + DCCH); + + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + size); + + rrc_data_req(ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- @@ -3635,13 +3695,15 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } - if ((*physicalConfigDedicated)->cqi_ReportConfig) { - if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) { - //feedback mode needs to be set as well - //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable - printf("setting cqi reporting mode to rm31\n"); + /* CSI Configuration through RRC */ + if ((*physicalConfigDedicated)->cqi_ReportConfig != NULL) { + if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + LOG_I(RRC, "Setting cqi aperiodic reporting mode to rm31 (hardcoded)\n"); + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; #else @@ -5378,88 +5440,99 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc //----------------------------------------------------------------------------- /* -* TODO: * add function description -* * format the function correctly +* Process the RRC Connection Reconfiguration Complete from the UE */ void rrc_eNB_process_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *ue_context_pP, + rrc_eNB_ue_context_t *ue_context_pP, const uint8_t xid ) //----------------------------------------------------------------------------- { - int i, drb_id; + int drb_id; int oip_ifup = 0; int dest_ip_offset = 0; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; + LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + 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; - LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; - 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; - T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer + + /* CDRX: activated if ack was expected */ + int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + UE_sched_ctrl *UE_scheduling_control = &(RC.mac[ctxt_pP->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; + LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + } + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); /* Derive the keys from kenb */ if (DRB_configList != NULL) { derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, &kUPenc); + ue_context_pP->ue_context.kenb, + &kUPenc); } derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kenb, &kRRCint); - // Refresh SRBs/DRBs - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_PDCP_ENB, - NULL, - 0, - MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti); - rrc_pdcp_config_asn1_req( - ctxt_pP, - SRB_configList, //NULL, //LG-RK 14/05/2014 SRB_configList, - DRB_configList, - // (LTE_DRB_ToReleaseList_t *) NULL, - DRB_Release_configList2, - /*RC.rrc[ctxt_pP->module_id]->ciphering_algorithm[ue_mod_idP] | - (RC.rrc[ctxt_pP->module_id]->integrity_algorithm[ue_mod_idP] << 4), - */ - 0xff, // already configured during the securitymodecommand - kRRCenc, - kRRCint, - kUPenc -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL -#endif - ,NULL); - // Refresh SRBs/DRBs - rrc_rlc_config_asn1_req( - ctxt_pP, - SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList, - DRB_configList, - // (LTE_DRB_ToReleaseList_t *) NULL - DRB_Release_configList2 -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL - , 0, 0 -#endif - ); + ue_context_pP->ue_context.kenb, + &kRRCenc); - // set the SRB active in Ue context + derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, + ue_context_pP->ue_context.kenb, + &kRRCint); + + /* Refresh SRBs/DRBs */ + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti); + + rrc_pdcp_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2, + 0xff, // already configured during the securitymodecommand + kRRCenc, + kRRCint, + kUPenc +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL +#endif + , NULL); + + /* Refresh SRBs/DRBs */ + rrc_rlc_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2 +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL, + 0, + 0 +#endif + ); + + /* Set the SRB active in UE context */ if (SRB_configList != NULL) { - for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { - if (SRB_configList->list.array[i]->srb_Identity == 1 ) { - ue_context_pP->ue_context.Srb1.Active=1; - } else if (SRB_configList->list.array[i]->srb_Identity == 2 ) { - ue_context_pP->ue_context.Srb2.Active=1; - ue_context_pP->ue_context.Srb2.Srb_info.Srb_id=2; + for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { + if (SRB_configList->list.array[i]->srb_Identity == 1) { + ue_context_pP->ue_context.Srb1.Active = 1; + } else if (SRB_configList->list.array[i]->srb_Identity == 2) { + ue_context_pP->ue_context.Srb2.Active = 1; + ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; LOG_I(RRC,"[eNB %d] Frame %d CC %d : SRB2 is now active\n", ctxt_pP->module_id, ctxt_pP->frame, @@ -5477,22 +5550,21 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.SRB_configList2[xid] = NULL; } - // Loop through DRBs and establish if necessary - + /* Loop through DRBs and establish if necessary */ if (DRB_configList != NULL) { - for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) + for (int i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) if (DRB_configList->list.array[i]) { drb_id = (int)DRB_configList->list.array[i]->drb_Identity; - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", + + LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)DRB_configList->list.array[i]->drb_Identity, (int)*DRB_configList->list.array[i]->logicalChannelIdentity); - // for pre-ci tests - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", + + /* For pre-ci tests */ + LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid], @@ -5500,45 +5572,37 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (int)*DRB_configList->list.array[i]->logicalChannelIdentity); if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) { - /* - rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_ADD, - (ue_mod_idP * NB_RB_MAX) + *DRB_configList->list.array[i]->logicalChannelIdentity,UNDEF_SECURITY_MODE); - rrc_rlc_config_req(ctxt_pP->module_id,frameP,1,CONFIG_ACTION_ADD, - (ue_mod_idP * NB_RB_MAX) + (int)*RC.rrc[ctxt_pP->module_id]->DRB_config[ue_mod_idP][i]->logicalChannelIdentity, - RADIO_ACCESS_BEARER,Rlc_info_um); - */ ue_context_pP->ue_context.DRB_active[drb_id] = 1; - LOG_D(RRC, - "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", + LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) { - LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", - ctxt_pP->module_id, - ctxt_pP->module_id); - oip_ifup = nas_config( - ctxt_pP->module_id, // interface index - ctxt_pP->module_id + 1, // thrid octet - ctxt_pP->module_id + 1, // fourth octet - "oai"); + LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", + ctxt_pP->module_id, + ctxt_pP->module_id); - if (oip_ifup == 0) { // interface is up --> send a config the DRB - module_id_t ue_module_id; - dest_ip_offset = 8; - LOG_I(OIP, - "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", - ctxt_pP->module_id, ctxt_pP->module_id, - (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity)); - ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; - rb_conf_ipv4(0, //add - ue_module_id, //cx - ctxt_pP->module_id, //inst - (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB - 0, //dscp - ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr - ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr - LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n", - ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); + oip_ifup = nas_config(ctxt_pP->module_id, // interface index + ctxt_pP->module_id + 1, // third octet + ctxt_pP->module_id + 1, // fourth octet + "oai"); + + if (oip_ifup == 0) { // interface is up --> send a config the DRB + module_id_t ue_module_id; + dest_ip_offset = 8; + LOG_I(OIP, + "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", + ctxt_pP->module_id, ctxt_pP->module_id, + (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity)); + ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; + rb_conf_ipv4(0, //add + ue_module_id, //cx + ctxt_pP->module_id, //inst + (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB + 0, //dscp + ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr + ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr + LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n", + ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); } /* oip_ifup */ } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/ @@ -5550,67 +5614,14 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity; } - if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { - rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, -#endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#endif - ue_context_pP->ue_context.physicalConfigDedicated, -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, -#endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - DRB2LCHAN[i], - DRB_configList->list.array[i]->logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_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 - /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, - (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); - */ - 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); - } - } - - ue_context_pP->ue_context.DRB_active[drb_id] = 0; - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_mac_config_req_eNB(ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + 0, + 0, + 0, + 0, + 0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif @@ -5623,7 +5634,70 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + DRB2LCHAN[i], + DRB_configList->list.array[i]->logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL +#endif + ); + } + } else { // end if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) // 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 + /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, + (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); + */ + 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); + } + } + + ue_context_pP->ue_context.DRB_active[drb_id] = 0; + + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0, + 0, + 0, + 0, + 0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + ue_context_pP->ue_context.physicalConfigDedicated, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *) NULL, #endif (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, @@ -5633,25 +5707,32 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_TDD_Config_t *) NULL, NULL, (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, NULL + 0, + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , + 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif - ); + ); } - } - } - } + } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) + } // end if (DRB_configList->list.array[i]) + } // end for (int i = 0; i < DRB_configList->list.count; i++) + free(DRB_configList); ue_context_pP->ue_context.DRB_configList2[xid] = NULL; - } + } // end if DRB_configList != NULL if(DRB_Release_configList2 != NULL) { - for (i = 0; i < DRB_Release_configList2->list.count; i++) { + for (int i = 0; i < DRB_Release_configList2->list.count; i++) { if (DRB_Release_configList2->list.array[i]) { drb_id_p = DRB_Release_configList2->list.array[i]; drb_id = *drb_id_p; @@ -5668,10 +5749,12 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( } //----------------------------------------------------------------------------- -void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - const int CC_id - ) +void +rrc_eNB_generate_RRCConnectionSetup( + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const int CC_id +) //----------------------------------------------------------------------------- { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -5680,27 +5763,30 @@ void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; LTE_SRB_ToAddModList_t **SRB_configList; LTE_SRB_ToAddMod_t *SRB1_config; - int cnt; - MessageDef *message_p; + + MessageDef *message_p; - T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + T(T_ENB_RRC_CONNECTION_SETUP, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - SRB_configList = &ue_p->SRB_configList; + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (is_mtc) { ue_p->Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup_BR(ctxt_pP, - ue_context_pP, - CC_id, - (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, - (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), - SRB_configList, - &ue_context_pP->ue_context.physicalConfigDedicated); + ue_context_pP, + CC_id, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), + SRB_configList, + &ue_context_pP->ue_context.physicalConfigDedicated); } else #endif { @@ -5714,10 +5800,10 @@ void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, SRB_configList, &ue_context_pP->ue_context.physicalConfigDedicated); } - LOG_DUMPMSG(RRC,DEBUG_RRC, - (char *)(ue_p->Srb0.Tx_buffer.Payload), - ue_p->Srb0.Tx_buffer.payload_size, - "[MSG] RRC Connection Setup\n"); + LOG_DUMPMSG(RRC,DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRC Connection Setup\n"); // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE switch (RC.rrc[ctxt_pP->module_id]->node_type){ @@ -5749,66 +5835,66 @@ void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, case ngran_ng_eNB : case ngran_gNB : - if (*SRB_configList != NULL) { - for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { - if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { - SRB1_config = (*SRB_configList)->list.array[cnt]; + if (*SRB_configList != NULL) { + for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { + if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { + SRB1_config = (*SRB_configList)->list.array[cnt]; - if (SRB1_config->logicalChannelConfig) { - if (SRB1_config->logicalChannelConfig->present == - LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; - } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } + if (SRB1_config->logicalChannelConfig) { + if (SRB1_config->logicalChannelConfig->present == + LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - if (RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) { - rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + if (RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); } } } - break; - default : + break; + default : LOG_W(RRC, "Unknown node type %d\n", RC.rrc[ctxt_pP->module_id]->node_type); } @@ -5828,11 +5914,13 @@ void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_p->Srb0.Tx_buffer.payload_size); - //ue_context_pP->ue_context.ue_release_timer_thres=100; // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres=1000; + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; + + /* init timers */ + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; } } @@ -7500,7 +7588,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) pthread_mutex_unlock(&rrc_release_freelist); if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { - ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer + ue_context_p->ue_context.ue_rrc_inactivity_timer++; if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.c b/openair2/RRC/LTE/rrc_eNB_UE_context.c index 646939b8dc..197aedae51 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.c +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.c @@ -41,7 +41,7 @@ //------------------------------------------------------------------------------ void uid_linear_allocator_init( - uid_allocator_t* const uid_pP + uid_allocator_t *const uid_pP ) //------------------------------------------------------------------------------ { @@ -51,14 +51,14 @@ uid_linear_allocator_init( //------------------------------------------------------------------------------ uid_t uid_linear_allocator_new( - eNB_RRC_INST* const rrc_instance_pP + eNB_RRC_INST *const rrc_instance_pP ) //------------------------------------------------------------------------------ { unsigned int i; unsigned int bit_index = 1; uid_t uid = 0; - uid_allocator_t* uia_p = &rrc_instance_pP->uid_allocator; + uid_allocator_t *uia_p = &rrc_instance_pP->uid_allocator; for (i=0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { if (uia_p->bitmap[i] != UINT_MAX) { @@ -82,7 +82,7 @@ uid_linear_allocator_new( //------------------------------------------------------------------------------ void uid_linear_allocator_free( - eNB_RRC_INST* rrc_instance_pP, + eNB_RRC_INST *rrc_instance_pP, uid_t uidP ) //------------------------------------------------------------------------------ @@ -99,7 +99,7 @@ uid_linear_allocator_free( //------------------------------------------------------------------------------ int rrc_eNB_compare_ue_rnti_id( - struct rrc_eNB_ue_context_s* c1_pP, struct rrc_eNB_ue_context_s* c2_pP) + struct rrc_eNB_ue_context_s *c1_pP, struct rrc_eNB_ue_context_s *c2_pP) //------------------------------------------------------------------------------ { if (c1_pP->ue_id_rnti > c2_pP->ue_id_rnti) { @@ -120,14 +120,14 @@ RB_GENERATE(rrc_ue_tree_s, rrc_eNB_ue_context_s, entries, //------------------------------------------------------------------------------ -struct rrc_eNB_ue_context_s* +struct rrc_eNB_ue_context_s * rrc_eNB_allocate_new_UE_context( - eNB_RRC_INST* rrc_instance_pP + eNB_RRC_INST *rrc_instance_pP ) //------------------------------------------------------------------------------ { - struct rrc_eNB_ue_context_s* new_p; - new_p = (struct rrc_eNB_ue_context_s* )malloc(sizeof(struct rrc_eNB_ue_context_s)); + struct rrc_eNB_ue_context_s *new_p; + new_p = (struct rrc_eNB_ue_context_s * )malloc(sizeof(struct rrc_eNB_ue_context_s)); if (new_p == NULL) { LOG_E(RRC, "Cannot allocate new ue context\n"); @@ -136,18 +136,20 @@ rrc_eNB_allocate_new_UE_context( memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s)); new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP); + for(int i = 0; i < NB_RB_MAX; i++) { - new_p->ue_context.e_rab[i].xid = -1; - new_p->ue_context.modify_e_rab[i].xid = -1; + new_p->ue_context.e_rab[i].xid = -1; + new_p->ue_context.modify_e_rab[i].xid = -1; } + return new_p; } //------------------------------------------------------------------------------ -struct rrc_eNB_ue_context_s* +struct rrc_eNB_ue_context_s * rrc_eNB_get_ue_context( - eNB_RRC_INST* rrc_instance_pP, + eNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) //------------------------------------------------------------------------------ { @@ -157,6 +159,7 @@ rrc_eNB_get_ue_context( temp.ue_id_rnti = rntiP; struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); + if ( ue_context_p != NULL) { return ue_context_p; } else { @@ -172,9 +175,9 @@ rrc_eNB_get_ue_context( //------------------------------------------------------------------------------ void rrc_eNB_remove_ue_context( - const protocol_ctxt_t* const ctxt_pP, - eNB_RRC_INST* rrc_instance_pP, - struct rrc_eNB_ue_context_s* ue_context_pP) + const protocol_ctxt_t *const ctxt_pP, + eNB_RRC_INST *rrc_instance_pP, + struct rrc_eNB_ue_context_s *ue_context_pP) //------------------------------------------------------------------------------ { if (rrc_instance_pP == NULL) { @@ -190,12 +193,10 @@ void rrc_eNB_remove_ue_context( } RB_REMOVE(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); - MSC_LOG_EVENT( MSC_RRC_ENB, "0 Removed UE %"PRIx16" ", ue_context_pP->ue_context.rnti); - rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP); uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid); free(ue_context_pP); diff --git a/openair2/RRC/LTE/rrc_eNB_ral.c b/openair2/RRC/LTE/rrc_eNB_ral.c index db20eb4a28..4820e84dc0 100644 --- a/openair2/RRC/LTE/rrc_eNB_ral.c +++ b/openair2/RRC/LTE/rrc_eNB_ral.c @@ -46,8 +46,7 @@ int rrc_enb_ral_delete_all_thresholds_type(unsigned int mod_idP, ral_link_param_ rrc_ral_threshold_key_t *keys = NULL; unsigned int num_keys = 0; int return_code = 0; - - rc = obj_hashtable_get_keys(eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&keys, &num_keys); + rc = obj_hashtable_get_keys(eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&keys, &num_keys); if (rc == HASH_TABLE_OK) { key = keys; @@ -82,10 +81,9 @@ int rrc_enb_ral_delete_threshold(unsigned int mod_idP, ral_link_param_type_t *pa { hashtable_rc_t rc; rrc_ral_threshold_key_t ref_key; - memcpy(&ref_key.link_param_type, param_type_pP, sizeof(ral_link_param_type_t)); memcpy(&ref_key.threshold, threshold_pP, sizeof(ral_threshold_t)); - rc = obj_hashtable_remove (eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&ref_key, sizeof(rrc_ral_threshold_key_t)); + rc = obj_hashtable_remove (eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&ref_key, sizeof(rrc_ral_threshold_key_t)); if (rc == HASH_TABLE_OK) { return 0; @@ -106,134 +104,130 @@ int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, Message MessageDef *message_p = NULL; unsigned int ix_param = 0; unsigned int ix_thresholds = 0; - DevAssert(msg_pP != NULL); - LOG_I(RRC, "[eNB %d] Received %s\n", mod_idP, ITTI_MSG_NAME (msg_pP)); configure_threshold_req_p = &RRC_RAL_CONFIGURE_THRESHOLD_REQ(msg_pP); - transaction_id = configure_threshold_req_p->transaction_id; for (ix_param = 0; ix_param < configure_threshold_req_p->num_link_cfg_params; ix_param++) { link_cfg_param_p = &configure_threshold_req_p->link_cfg_params[ix_param]; switch (link_cfg_param_p->th_action) { - case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: - case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: - switch (link_cfg_param_p->link_param_type.choice) { + case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: + case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: + switch (link_cfg_param_p->link_param_type.choice) { + case RAL_LINK_PARAM_TYPE_CHOICE_GEN: + switch (link_cfg_param_p->link_param_type._union.link_param_gen) { + case RAL_LINK_PARAM_GEN_DATA_RATE: + case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: + case RAL_LINK_PARAM_GEN_SINR: + case RAL_LINK_PARAM_GEN_THROUGHPUT: + case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - switch (link_cfg_param_p->link_param_type._union.link_param_gen) { - case RAL_LINK_PARAM_GEN_DATA_RATE: - case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: - case RAL_LINK_PARAM_GEN_SINR: - case RAL_LINK_PARAM_GEN_THROUGHPUT: - case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); + return -1; + } - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); - return -1; - } + break; - break; + case RAL_LINK_PARAM_TYPE_CHOICE_QOS: + switch (link_cfg_param_p->link_param_type._union.link_param_qos) { + case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: + case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: + case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - switch (link_cfg_param_p->link_param_type._union.link_param_qos) { - case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: - case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: - case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); + return -1; + } - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); - return -1; - } + break; - break; + case RAL_LINK_PARAM_TYPE_CHOICE_LTE: + switch (link_cfg_param_p->link_param_type._union.link_param_lte) { + // group by dest task id + case RAL_LINK_PARAM_LTE_UE_RSRP: + case RAL_LINK_PARAM_LTE_UE_RSRQ: + case RAL_LINK_PARAM_LTE_UE_CQI: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - switch (link_cfg_param_p->link_param_type._union.link_param_lte) { - // group by dest task id - case RAL_LINK_PARAM_LTE_UE_RSRP: - case RAL_LINK_PARAM_LTE_UE_RSRQ: - case RAL_LINK_PARAM_LTE_UE_CQI: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; + case RAL_LINK_PARAM_LTE_AVAILABLE_BW: + case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: + case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: + case RAL_LINK_PARAM_LTE_PACKET_DELAY: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; - case RAL_LINK_PARAM_LTE_AVAILABLE_BW: - case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: - case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: - case RAL_LINK_PARAM_LTE_PACKET_DELAY: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: - case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: - case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: - case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: - case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: + case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: + case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: + case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: + case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: + case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: #warning "TO DO MIH LTE LINK PARAMS IN RRC ENB" - break; + break; - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); - return -1; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); + return -1; + } + + break; + + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + return -1; + } + + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + } + + break; + + case RAL_TH_ACTION_CANCEL_THRESHOLD: + + // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): + // When “Cancel threshold” is selected and no thresholds are specified, then all + // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. + if (link_cfg_param_p->num_thresholds == 0) { + rrc_enb_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); + } else { + // + // When “Cancel threshold” is selected and thresholds are specified only those + // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was + // specified are cancelled. + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + rrc_enb_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); + } } break; default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); return -1; - } - - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - } - - break; - - case RAL_TH_ACTION_CANCEL_THRESHOLD: - - // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): - // When “Cancel threshold” is selected and no thresholds are specified, then all - // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. - if (link_cfg_param_p->num_thresholds == 0) { - rrc_enb_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); - } else { - // - // When “Cancel threshold” is selected and thresholds are specified only those - // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was - // specified are cancelled. - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - rrc_enb_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); - } - } - - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); - return -1; } } diff --git a/openair2/RRC/LTE/rrc_rrm_interface.c b/openair2/RRC/LTE/rrc_rrm_interface.c index 9f4270be89..fe15dae46d 100644 --- a/openair2/RRC/LTE/rrc_rrm_interface.c +++ b/openair2/RRC/LTE/rrc_rrm_interface.c @@ -44,18 +44,18 @@ */ #ifndef RRC_RRM_FIFOS_XFACE -#include -#include -#include -#include -#include + #include + #include + #include + #include + #include -#include -#include + #include + #include #else -#include + #include #endif @@ -78,12 +78,11 @@ \return The return value is a socket handle */ int open_socket( - sock_rrm_t *s , ///< socket descriptor + sock_rrm_t *s, ///< socket descriptor char *path_local, ///< local socket path if unix socket - char *path_dest , ///< host Socket path if unix socket + char *path_dest, ///< host Socket path if unix socket int rrm_inst ///< instance of the rrm entity -) -{ +) { /* Unix socket */ int socket_fd ; int len ; @@ -109,8 +108,6 @@ int open_socket( s->un_dest_addr.sun_family = AF_UNIX; sprintf(s->un_dest_addr.sun_path,"%s%d", path_dest, rrm_inst ); msg("Dest %s\n",s->un_dest_addr.sun_path); - - s->s = socket_fd ; return socket_fd ; } @@ -121,8 +118,7 @@ int open_socket( */ void close_socket( sock_rrm_t *sock ///< the socket handle -) -{ +) { shutdown(sock->s, SHUT_RDWR); close(sock->s); } @@ -134,10 +130,9 @@ void close_socket( */ char BUFF[2048]; int send_msg_sock( - sock_rrm_t *s ,///< socket descriptor + sock_rrm_t *s, ///< socket descriptor msg_t *smsg ///< the message to send -) -{ +) { /* Unix socket */ int ret = 0 ; // char *buf = NULL; @@ -156,13 +151,10 @@ int send_msg_sock( //buf = RRM_MALLOC(char, taille); //if (buf ==NULL) //return -1 ; - - memcpy( BUFF , &(smsg->head) , sizeof(msg_head_t) ) ; + memcpy( BUFF, &(smsg->head), sizeof(msg_head_t) ) ; memcpy( BUFF+sizeof(msg_head_t), smsg->data, smsg->head.size ) ; - iov.iov_base = (void *)BUFF; iov.iov_len = taille ; - msghd.msg_name = (void *)&(s->un_dest_addr); msghd.msg_namelen = sizeof(s->un_dest_addr); msghd.msg_iov = &iov; @@ -179,7 +171,6 @@ int send_msg_sock( //RRM_FREE(buf) ; //RRM_FREE(msg->data) ; //RRM_FREE(msg) ; - return ret ; } @@ -191,8 +182,7 @@ int send_msg_sock( */ char *recv_msg( sock_rrm_t *s ///< socket descriptor -) -{ +) { /* Unix socket */ char *buf = NULL; char *smsg = NULL; @@ -201,9 +191,7 @@ char *recv_msg( int size_msg ; msg_head_t *head ; int ret ; - int taille = SIZE_MAX_PAYLOAD ; - buf = RRM_CALLOC( char,taille); if ( buf == NULL ) { @@ -218,8 +206,7 @@ char *recv_msg( msghd.msg_iovlen = 1; msghd.msg_control = NULL ; msghd.msg_controllen= 0 ; - - ret = recvmsg(s->s, &msghd , 0 ) ; + ret = recvmsg(s->s, &msghd, 0 ) ; if ( ret <= 0 ) { // non-blocking socket @@ -236,22 +223,19 @@ char *recv_msg( head = (msg_head_t *) buf ; size_msg = sizeof(msg_head_t) + head->size ; - - smsg = RRM_CALLOC(char , size_msg ) ; + smsg = RRM_CALLOC(char, size_msg ) ; if ( smsg != NULL ) { - memcpy( smsg , buf , size_msg ) ; + memcpy( smsg, buf, size_msg ) ; } RRM_FREE( buf ) ; - return smsg ; } #else //XFACE -int send_msg_fifo(int *s, msg_t *fmsg) -{ +int send_msg_fifo(int *s, msg_t *fmsg) { int ret = 0, ret1; int taille = sizeof(msg_head_t) ; msg("write on fifos %d, msg %p\n",*s,fmsg); @@ -261,9 +245,7 @@ int send_msg_fifo(int *s, msg_t *fmsg) } // envoi le header - - - ret1 = rtf_put (*s,(char*) &(fmsg->head) , taille); + ret1 = rtf_put (*s,(char *) &(fmsg->head), taille); if(ret1 <0) { msg("rtf_put H ERR %d\n",ret1); @@ -275,7 +257,7 @@ int send_msg_fifo(int *s, msg_t *fmsg) // envoi les datas si elles sont definis if ( fmsg->data != NULL ) { - ret1 += rtf_put (*s,(char*) fmsg->data, fmsg->head.size); + ret1 += rtf_put (*s,(char *) fmsg->data, fmsg->head.size); if(ret1 <0) { msg("rtf_put D ERR %d\n",ret1); @@ -290,7 +272,6 @@ int send_msg_fifo(int *s, msg_t *fmsg) #endif //XFACE -int send_msg(void *s, msg_t *smsg) -{ +int send_msg(void *s, msg_t *smsg) { send_msg_sock((sock_rrm_t *)s, smsg); } diff --git a/openair2/RRC/LTE/rrm_2_rrc_msg.c b/openair2/RRC/LTE/rrm_2_rrc_msg.c index 3ed3a9d859..79cdc74e2b 100644 --- a/openair2/RRC/LTE/rrm_2_rrc_msg.c +++ b/openair2/RRC/LTE/rrm_2_rrc_msg.c @@ -51,26 +51,22 @@ //#include "openair_rrc_utils.h" //#include "openair_rrc_main.h" #ifdef PHY_EMUL -#include "SIMULATION/simulation_defs.h" -extern EMULATION_VARS *Emul_vars; -extern CH_MAC_INST *CH_mac_inst; -extern UE_MAC_INST *UE_mac_inst; + #include "SIMULATION/simulation_defs.h" + extern EMULATION_VARS *Emul_vars; + extern CH_MAC_INST *CH_mac_inst; + extern UE_MAC_INST *UE_mac_inst; #endif /******************************************************************************/ -void fn_rrc (void) -{ +void fn_rrc (void) { /******************************************************************************/ - msg_head_t *Header ; char *Data; - L2_ID Mac_id; while(1) { - Header = (msg_head_t *) recv_msg(&S_rrc) ; if(Header==NULL) { @@ -86,118 +82,107 @@ void fn_rrc (void) msg("Got MSG of Type %d on Inst %d\n",Header->msg_type,Header->inst); switch ( Header->msg_type ) { - case RRM_INIT_CH_REQ: { - rrm_init_ch_req_t *p = (rrm_init_ch_req_t *) Data; - msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_CH_REQ\n",Header->inst); - rrc_init_ch_req(Header->inst,p); - break; - } + case RRM_INIT_CH_REQ: { + rrm_init_ch_req_t *p = (rrm_init_ch_req_t *) Data; + msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_CH_REQ\n",Header->inst); + rrc_init_ch_req(Header->inst,p); + break; + } - case RRCI_INIT_MR_REQ: { - rrci_init_mr_req_t *p = (rrci_init_mr_req_t *) Data; - msg( "[RRM]>[RRC][Inst %d]:RRCI_INIT_MR_REQ\n",Header->inst); - rrc_init_mr_req(Header->inst,p); - break; - } + case RRCI_INIT_MR_REQ: { + rrci_init_mr_req_t *p = (rrci_init_mr_req_t *) Data; + msg( "[RRM]>[RRC][Inst %d]:RRCI_INIT_MR_REQ\n",Header->inst); + rrc_init_mr_req(Header->inst,p); + break; + } - case RRM_RB_ESTABLISH_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_establish_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_ESTABLISH_REQ, size %d\n",Header->inst,sizeof(rrm_rb_establish_req_t)); - rrc_config_req(Header->inst,(void*)Data,Header->msg_type,Header->Trans_id); - break ; - } + case RRM_RB_ESTABLISH_REQ: { + send_msg((void *)&S_rrc,msg_rrc_rb_establish_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_RB_ESTABLISH_REQ, size %d\n",Header->inst,sizeof(rrm_rb_establish_req_t)); + rrc_config_req(Header->inst,(void *)Data,Header->msg_type,Header->Trans_id); + break ; + } - case RRM_RB_MODIFY_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_modify_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_MODIFY_REQ\n",Header->inst); - rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); - } + case RRM_RB_MODIFY_REQ: { + send_msg((void *)&S_rrc,msg_rrc_rb_modify_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_RB_MODIFY_REQ\n",Header->inst); + rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); + } - case RRM_RB_RELEASE_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_release_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_RELEASE_REQ\n",Header->inst); - rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); - } + case RRM_RB_RELEASE_REQ: { + send_msg((void *)&S_rrc,msg_rrc_rb_release_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_RB_RELEASE_REQ\n",Header->inst); + rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); + } - case RRCI_CX_ESTABLISH_RESP: { - rrci_cx_establish_resp_t *p = (rrci_cx_establish_resp_t *) Data; - unsigned char CH_index,i; - msg( "[RRCI]>[RRC][Inst %d]:RRCI_CX_ESTABLISH_RESP\n",Header->inst); + case RRCI_CX_ESTABLISH_RESP: { + rrci_cx_establish_resp_t *p = (rrci_cx_establish_resp_t *) Data; + unsigned char CH_index,i; + msg( "[RRCI]>[RRC][Inst %d]:RRCI_CX_ESTABLISH_RESP\n",Header->inst); - for(i=0; iinst-NB_CH_INST].Info[i].CH_mac_id,&p->L2_id,sizeof(L2_ID))) { - CH_index=i; - break; + for(i=0; iinst-NB_CH_INST].Info[i].CH_mac_id,&p->L2_id,sizeof(L2_ID))) { + CH_index=i; + break; + } + + if(i==NB_SIG_CNX_UE) { + msg("[RRC] FATAL: CH_INDEX NOT FOUND\n"); + return; } - if(i==NB_SIG_CNX_UE) { - msg("[RRC] FATAL: CH_INDEX NOT FOUND\n"); - return; + UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr_type=p->L3_info_t; + + if(p->L3_info_t == IPv4_ADDR) { + memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,4); + } else { + memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,16); + } } + break ; - UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr_type=p->L3_info_t; - - if(p->L3_info_t == IPv4_ADDR) { - memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,4); + case RRM_SENSING_MEAS_REQ: { + // rrm_sensing_meas_req_t *p = (rrm_sensing_meas_req_t *) sock_msg ; + send_msg((void *)&S_rrc,msg_rrc_sensing_meas_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_REQ\n",Header->inst); + // rrc_meas_req(header->inst,p,RRC_MEAS_ADD); } + break ; - else { - memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,16); + case RRM_SENSING_MEAS_RESP: { + msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_RESP\n",Header->inst); + //rrm_rrc_meas_resp(header->inst,header->Trans_id); } + break ; + + case RRM_SCAN_ORD: + msg( "[RRM]>[RRC][Inst %d]:RRM_SCAN_ORD\n",Header->inst); + //memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); + //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; + ///send over air + break; + + case RRM_INIT_SCAN_REQ: + msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_SCAN_REQ\n",Header->inst); + memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); + CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; + ///send over air + break; + + case RRM_END_SCAN_REQ: + msg( "[RRM]>[RRC][Inst %d]:RRM_END_SCAN_REQ\n",Header->inst); + memcpy(&Mac_id.L2_id[0],Data,sizeof(L2_ID)); + unsigned char UE_index=Mac_id.L2_id[0]-NB_CH_MAX+1; + UE_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload[0]=100; + msg("SRB_ID %d\n",CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id); + Mac_rlc_xface->rrc_rlc_data_req(0,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id,0,0,1,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload); + //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; + ///send over air + break; + + default : + msg("[L3_xface]WARNING: msg unknown %d\n",Header->msg_type) ; } - break ; - - case RRM_SENSING_MEAS_REQ: { - // rrm_sensing_meas_req_t *p = (rrm_sensing_meas_req_t *) sock_msg ; - send_msg((void *)&S_rrc,msg_rrc_sensing_meas_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_REQ\n",Header->inst); - // rrc_meas_req(header->inst,p,RRC_MEAS_ADD); - } - break ; - - - case RRM_SENSING_MEAS_RESP: { - msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_RESP\n",Header->inst); - //rrm_rrc_meas_resp(header->inst,header->Trans_id); - } - break ; - - - case RRM_SCAN_ORD: - msg( "[RRM]>[RRC][Inst %d]:RRM_SCAN_ORD\n",Header->inst); - //memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); - //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air - - break; - - case RRM_INIT_SCAN_REQ: - msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_SCAN_REQ\n",Header->inst); - memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); - CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air - - break; - - case RRM_END_SCAN_REQ: - - msg( "[RRM]>[RRC][Inst %d]:RRM_END_SCAN_REQ\n",Header->inst); - memcpy(&Mac_id.L2_id[0],Data,sizeof(L2_ID)); - unsigned char UE_index=Mac_id.L2_id[0]-NB_CH_MAX+1; - - - UE_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload[0]=100; - msg("SRB_ID %d\n",CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id); - Mac_rlc_xface->rrc_rlc_data_req(0,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id,0,0,1,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload); - //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air - - break; - - default : - msg("[L3_xface]WARNING: msg unknown %d\n",Header->msg_type) ; - } - } } diff --git a/openair2/RRC/LTE/utils.c b/openair2/RRC/LTE/utils.c index bbf97046bf..08637e0e67 100644 --- a/openair2/RRC/LTE/utils.c +++ b/openair2/RRC/LTE/utils.c @@ -34,8 +34,7 @@ ________________________________________________________________*/ //------------------------------------------------------------------------------------------------------------------// -uint16_t find_free_dtch_position(uint8_t Mod_id, uint16_t UE_CH_index) -{ +uint16_t find_free_dtch_position(uint8_t Mod_id, uint16_t UE_CH_index) { uint16_t i,j; if(UE_CH_index==0) { @@ -45,22 +44,18 @@ uint16_t find_free_dtch_position(uint8_t Mod_id, uint16_t UE_CH_index) } for(i=j; imacphy_exit("NO FREE DTCH LCHAN, exit"); - return 0; } //-------------------------------------------------------------------------------------------// -uint8_t rrc_find_free_ue_index(uint8_t Mod_id) -{ +uint8_t rrc_find_free_ue_index(uint8_t Mod_id) { //-------------------------------------------------------------------------------------------// uint16_t i; @@ -78,8 +73,7 @@ uint8_t rrc_find_free_ue_index(uint8_t Mod_id) //-------------------------------------------------------------------------------------------// -unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) -{ +unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) { //-------------------------------------------------------------------------------------------// unsigned char i; /* @@ -90,8 +84,7 @@ unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) */ } //-------------------------------------------------------------------------------------------// -uint8_t rrc_is_node_isolated(uint8_t Mod_id) -{ +uint8_t rrc_is_node_isolated(uint8_t Mod_id) { //-------------------------------------------------------------------------------------------// /*uint8_t i; for(i=0;iHeader->Rv_tb_idx=0; // Rrc_buffer->W_idx=0;