From 0f57529b48b55d96c304ca44f988d714de6695c4 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 15 Jan 2021 10:05:28 +0100 Subject: [PATCH 01/43] fixing benetel4g driver by setting ru->has_ctrl_prt =1 and thus starting the RU control thread, which is required for the 4G RRU. In the future we should revisit this and harmonize with the 5G version. --- targets/RT/USER/lte-ru.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 56c2cb23dd..368fd78f9e 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2986,6 +2986,7 @@ void RCconfig_RU(void) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt =1; LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } @@ -3039,6 +3040,7 @@ else { RC.ru[j]->if_south = REMOTE_IF4p5; RC.ru[j]->function = NGFI_RAU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt = 1; if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; else RC.ru[j]->is_slave=0; From a5b5d6f9b0b8c77b15aaa0a5b6f8235496e57fc1 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 22 Jan 2021 10:25:38 +0100 Subject: [PATCH 02/43] fixing RRC power levels at 5G side to avoid saturation --- common/utils/T/T_defs.h | 4 ++-- common/utils/T/T_messages.txt | 4 ++++ executables/nr-gnb.c | 6 ++++++ .../PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 4 ++++ openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 4 ++++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 7 +++++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 7 ++++--- targets/ARCH/ETHERNET/benetel/5g/benetel.c | 8 ++++++-- .../PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf | 12 ++++++------ .../PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 13 +++++++++---- 10 files changed, 52 insertions(+), 17 deletions(-) diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 7b5304b1cb..11c816f002 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ /* let's have 100 RBs functional for the basic simulator */ # define T_BUFFER_MAX (1024*64*2) #else -# define T_BUFFER_MAX (1024*64) +# define T_BUFFER_MAX (1024*64*2) #endif /* size of the local cache for messages (must be pow(2,something)) */ @@ -52,7 +52,7 @@ /* we don't need much space for the basic simulator */ # define T_CACHE_SIZE 1024 #else -# define T_CACHE_SIZE (8192 * 2) +# define T_CACHE_SIZE (8192) #endif /* maximum number of bytes a message can contain */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 06ee5bf12b..bad6444e13 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,3 +1,7 @@ +ID = BENETEL + GROUP = ALL + FORMAT = int,frame : int,slot : buffer,rxdataF + #general logs ID = ENB_MASTER_TICK DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index be9261a117..7966c5b6ce 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -1001,7 +1001,13 @@ void init_eNB_afterRU(void) { for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i]; +#if 0 +printf("before %p\n", gNB->common_vars.rxdataF[aa]); +#endif gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; +#if 0 +printf("after %p\n", gNB->common_vars.rxdataF[aa]); +#endif } } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..d2baa40451 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -67,6 +67,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; +#if 0 +printf("nr_pusch_channel_estimation rxdataF %p\n", &rxdataF[0][0]); +#endif + nushift = (p>>1)&1; gNB->frame_parms.nushift = nushift; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 7e6becb4a8..25c9fee832 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -250,6 +250,10 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, uint8_t is_dmrs_re; start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; +#if 0 +printf("frame_parms->first_carrier_offset in nr_ulsch_extract_rbs_single %d\n", frame_parms->first_carrier_offset); +printf("rxdataF in nr_ulsch_extract_rbs_single %p\n", &rxdataF[0][0]); +#endif nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; #ifdef __AVX2__ int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6b5c1a9b22..d67d7c8efa 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -551,6 +551,11 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB_I0_measurements(gNB); + // measure enegry in SS=10 L=4, nb_rb = 18, first_rb = 0 (corresponds to msg3) + int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; + int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18); + LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF); + for (int i=0;ipucch[i]; if (pucch) { @@ -646,6 +651,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } #endif +T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14)); + uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b92ee1dba3..468a43a0c7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -334,7 +334,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; - LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n", gnb_mod_idP, harq_pid, CC_idP, @@ -342,7 +342,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, slotP, current_rnti, UE_id, - ul_cqi); + ul_cqi, + sduP); // if not missed detection (10dB threshold for now) if (UE_scheduling_control->ul_rssi < (100+rssi)) { @@ -627,7 +628,7 @@ void nr_schedule_ulsch(module_id_t module_id, if (cur_harq->round == 0) { UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size; } else { - LOG_W(MAC, + LOG_D(MAC, "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", frame, slot, diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 2f60e7dc49..ab9f970931 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -228,11 +228,15 @@ next: fp = ru->nr_frame_parms; for (symbol = 0; symbol < 14; symbol++) { int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); + int16_t *p = (int16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); + p[i] = (int16_t)(ntohs(p[i])) / 16; } rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; +#if 0 +if (*slot == 0 && symbol == 0) +printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); +#endif #if 1 memcpy(rxdata + 2048 - 1272/2, &s->buffers.ul[*slot][symbol*1272*4], diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 49b4e4441e..aab3876d96 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -230,12 +230,12 @@ RUs = ( local_if_name = "dpdk"; sdr_addrs = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1"; #sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2"; - remote_address = "127.0.0.2"; - local_address = "127.0.0.1"; - local_portc = 50000; - remote_portc = 50000; - local_portd = 50001; - remote_portd = 50001; + #remote_address = "127.0.0.2"; + #local_address = "127.0.0.1"; + #local_portc = 50000; + #remote_portc = 50000; + #local_portd = 50001; + #remote_portd = 50001; local_rf = "no" tr_preference = "raw_if4p5" nb_tx = 1 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 037de199df..251a76f36e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + #pusch_TargetSNRx10 = 200; + #pucch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -103,7 +105,8 @@ gNBs = prach_msg1_FrequencyStart = 74; zeroCorrelationZoneConfig = 13; #preambleReceivedTargetPower = -118; - preambleReceivedTargetPower = -104; + #preambleReceivedTargetPower = -104; + preambleReceivedTargetPower = -108; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -149,14 +152,16 @@ gNBs = initialULBWPstartSymbolAndLength_2 = 52; msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; + #p0_NominalWithGrant =-90; + p0_NominalWithGrant =-108; # pucch-ConfigCommon setup : # pucchGroupHopping # 0 = neither, 1= group hopping, 2=sequence hopping pucchGroupHopping = 0; hoppingId = 40; - p0_nominal = -90; + #p0_nominal = -90; + p0_nominal = -108; # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; @@ -189,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); From 857f9179f35216e36ca16ed08cde193e81a418bc Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 1 Feb 2021 10:08:59 +0100 Subject: [PATCH 03/43] shifting also the TX 4 bits to the left to exploit dynamic range. adapted ssb_block_power but proper calibration still necessary. --- targets/ARCH/ETHERNET/benetel/5g/benetel.c | 2 +- targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index ab9f970931..75706f591d 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -317,7 +317,7 @@ void benetel_fh_if4p5_south_out(RU_t *ru, int i; uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); + p[i] = htons(p[i]<<4); } } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 251a76f36e..ba44e989b9 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -194,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = -25; + ssPBCH_BlockPower = -10; } ); From a9f57407c70fc290910cf6f9b9cfad962e5f1a4d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 3 Feb 2021 17:07:18 +0100 Subject: [PATCH 04/43] benetel 4g: support two antennas --- targets/ARCH/ETHERNET/benetel/4g/benetel.c | 76 ++++++++++--------- .../ARCH/ETHERNET/benetel/4g/dpdk_driver.c | 36 +++------ targets/ARCH/ETHERNET/benetel/4g/low.c | 41 +++++----- targets/ARCH/ETHERNET/benetel/4g/low.h | 7 +- targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c | 3 +- .../ARCH/ETHERNET/benetel/4g/shared_buffers.c | 9 ++- .../ARCH/ETHERNET/benetel/4g/shared_buffers.h | 9 ++- 7 files changed, 91 insertions(+), 90 deletions(-) diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c index 76855111e1..d3b72463b4 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -163,8 +163,8 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 7; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + cap->nb_rx[0] = device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -194,11 +194,12 @@ void benetel_fh_if4p5_south_in(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *subframe); next: - while (!(s->buffers.ul_busy[*subframe] == 0x3fff || + while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff && + s->buffers.ul_busy[1][*subframe] == 0x3fff) || s->buffers.prach_busy[*subframe] == 1)) wait_ul_buffer(&s->buffers, *subframe); if (s->buffers.prach_busy[*subframe] == 1) { @@ -217,24 +218,27 @@ next: eNB = eNB_list[0]; fp = &eNB->frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(rxdata + 2048 - 600, - &s->buffers.ul[*subframe][symbol*1200*4], - 600 * 4); - memcpy(rxdata, - &s->buffers.ul[*subframe][symbol*1200*4] + 600*4, - 600 * 4); + memcpy(rxdata + 2048 - 600, + &s->buffers.ul[antenna][*subframe][symbol*1200*4], + 600 * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4, + 600 * 4); #endif + } } - s->buffers.ul_busy[*subframe] = 0; + s->buffers.ul_busy[0][*subframe] = 0; + s->buffers.ul_busy[1][*subframe] = 0; signal_ul_buffer(&s->buffers, *subframe); unlock_ul_buffer(&s->buffers, *subframe); @@ -272,45 +276,49 @@ void benetel_fh_if4p5_south_out(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); lock_dl_buffer(&s->buffers, subframe); - if (s->buffers.dl_busy[subframe]) { + if (s->buffers.dl_busy[0][subframe] || + s->buffers.dl_busy[1][subframe]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe); unlock_dl_buffer(&s->buffers, subframe); return; } eNB = eNB_list[0]; fp = &eNB->frame_parms; - if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_tti != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[subframe][symbol*1200*4], - txdata + 2048 - 600, - 600 * 4); - memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4, - txdata + 1, - 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4], + txdata + 2048 - 600, + 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4, + txdata + 1, + 600 * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[subframe] = 0x3fff; + s->buffers.dl_busy[0][subframe] = 0x3fff; + s->buffers.dl_busy[1][subframe] = 0x3fff; unlock_dl_buffer(&s->buffers, subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx); diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c index 42953d1d4a..2b6ef37e6f 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -233,19 +233,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) { p.frame = FRAME; p.subframe = SUBFRAME >> 4; p.slot = 0; /* unused */ p.symbol = SYMBOL; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 4800); store_ul(bs, &p); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1) { + int a = ANT_NUM; int tx_frame = FRAME; int tx_subframe = SUBFRAME >> 4; int tx_symbol = SYMBOL + 5; @@ -266,33 +267,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) SUBFRAME = tx_subframe << 4; SYMBOL = tx_symbol; - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ lock_dl_buffer(bs->buffers, tx_subframe); - if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__, + if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n", + __FUNCTION__, + a, tx_subframe, tx_symbol); memset(IQ_ptr, 0, 1200 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4, + memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4, 1200*4); } - bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, tx_subframe); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 4800); - } - - // U-PLANE UL ANT_1 PROCESSING - else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1) - { - -// ANT_NUM = 0x01; - SYMBOL = (SYMBOL + 5) % 14; - PAYLOAD_2 = 0xc8; - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 4800); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c index 038592d596..14783a700b 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low.c @@ -27,37 +27,36 @@ void store_ul(benetel_t *bs, ul_packet_t *ul) { - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->subframe != bs->next_subframe || - ul->symbol != bs->next_symbol) { - printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->subframe != bs->next_subframe[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol, + a, + bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a], ul->frame, ul->subframe, ul->symbol); exit(1); } - lock_ul_buffer(bs->buffers, bs->next_subframe); - if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) { + lock_ul_buffer(bs->buffers, bs->next_subframe[a]); + if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) { printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__, - bs->next_subframe, bs->next_symbol); + bs->next_subframe[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4, + memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4, ul->iq, 1200*4); - bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_subframe); - unlock_ul_buffer(bs->buffers, bs->next_subframe); + bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_subframe[a]); + unlock_ul_buffer(bs->buffers, bs->next_subframe[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_subframe = (bs->next_subframe + 1) % 10; - if (bs->next_subframe == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10; + if (bs->next_subframe[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h index 5e75d9181e..e74bf89163 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.h +++ b/targets/ARCH/ETHERNET/benetel/4g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_subframe; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_subframe[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c index ecff473010..edf62a67e0 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c index 492a15dfc3..380cbabc73 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c @@ -44,9 +44,12 @@ void init_buffers(shared_buffers *s) /* in FDD the eNB's first transmitted DL subframe is 4 but the device * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int subframe) diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h index 1d5040b95b..ed174265c5 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h @@ -26,10 +26,11 @@ #include typedef struct { - unsigned char dl[10][14*1200*4]; - unsigned char ul[10][14*1200*4]; - uint16_t dl_busy[10]; - uint16_t ul_busy[10]; + /* [2] is for two antennas */ + unsigned char dl[2][10][14*1200*4]; + unsigned char ul[2][10][14*1200*4]; + uint16_t dl_busy[2][10]; + uint16_t ul_busy[2][10]; pthread_mutex_t m_ul[10]; pthread_cond_t c_ul[10]; From b7ea4e0f6da205c0c7af52b956efa76d14ca1763 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 5 Feb 2021 16:36:18 +0100 Subject: [PATCH 05/43] benetel 5g: support for two antennas --- targets/ARCH/ETHERNET/benetel/5g/benetel.c | 77 +++++++++++-------- .../ARCH/ETHERNET/benetel/5g/dpdk_driver.c | 76 +++++++----------- targets/ARCH/ETHERNET/benetel/5g/low.c | 76 +++++++++--------- targets/ARCH/ETHERNET/benetel/5g/low.h | 7 +- targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c | 3 +- .../ARCH/ETHERNET/benetel/5g/shared_buffers.c | 15 ++-- .../ARCH/ETHERNET/benetel/5g/shared_buffers.h | 9 ++- 7 files changed, 129 insertions(+), 134 deletions(-) diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 75706f591d..cededa968e 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -162,8 +162,9 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 78; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + /* TODO: hardcoded to 1 for the moment, get the real value somehow... */ + cap->nb_rx[0] = 1; //device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = 1; //device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -201,12 +202,13 @@ void benetel_fh_if4p5_south_in(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *slot); #if 1 next: - while (!(s->buffers.ul_busy[*slot] == 0x3fff || + while (!((s->buffers.ul_busy[0][*slot] == 0x3fff && + s->buffers.ul_busy[1][*slot] == 0x3fff) || s->buffers.prach_busy[*slot] == 1)) wait_ul_buffer(&s->buffers, *slot); if (s->buffers.prach_busy[*slot] == 1) { @@ -226,28 +228,31 @@ next: #endif fp = ru->nr_frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - int16_t *p = (int16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = (int16_t)(ntohs(p[i])) / 16; - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + int16_t *p = (int16_t *)(&s->buffers.ul[antenna][*slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = (int16_t)(ntohs(p[i])) / 16; + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; #if 0 if (*slot == 0 && symbol == 0) printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); #endif #if 1 - memcpy(rxdata + 2048 - 1272/2, - &s->buffers.ul[*slot][symbol*1272*4], - (1272/2) * 4); - memcpy(rxdata, - &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4, - (1272/2) * 4); + memcpy(rxdata + 2048 - 1272/2, + &s->buffers.ul[antenna][*slot][symbol*1272*4], + (1272/2) * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*slot][symbol*1272*4] + (1272/2)*4, + (1272/2) * 4); #endif + } } - s->buffers.ul_busy[*slot] = 0; + s->buffers.ul_busy[0][*slot] = 0; + s->buffers.ul_busy[1][*slot] = 0; signal_ul_buffer(&s->buffers, *slot); unlock_ul_buffer(&s->buffers, *slot); @@ -285,43 +290,47 @@ void benetel_fh_if4p5_south_out(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp); lock_dl_buffer(&s->buffers, slot); - if (s->buffers.dl_busy[slot]) { + if (s->buffers.dl_busy[0][slot] || + s->buffers.dl_busy[1][slot]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot); unlock_dl_buffer(&s->buffers, slot); return; } fp = ru->nr_frame_parms; - if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_gNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_slot != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[slot][symbol*1272*4], - txdata + 2048 - (1272/2), - (1272/2) * 4); - memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4, - txdata, - (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4], + txdata + 2048 - (1272/2), + (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4] + (1272/2)*4, + txdata, + (1272/2) * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]<<4); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[slot] = 0x3fff; + s->buffers.dl_busy[0][slot] = 0x3fff; + s->buffers.dl_busy[1][slot] = 0x3fff; unlock_dl_buffer(&s->buffers, slot); } diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c index dd50603ec5..88f4ecb4cd 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -243,21 +243,22 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4) { int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); p.frame = FRAME; p.slot = subframe * 2 + slot; p.symbol = SYMBOL & 0x3f; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 5088); store_ul(bs, &p); // if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && dl_start == 1) { + int a = ANT_NUM & 0x01; int frame = FRAME; int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); @@ -282,66 +283,45 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } } - ANT_NUM = 0x00; - // Mask the symbol bits from UL packet received and apply the shift. SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14; - ANT_NUM = 0x00; + ANT_NUM = a; SUBFRAME = sf; + if (a == 1) + slot_id_ctrl++; + // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; + if (slot_id_ctrl > 13) { + SYMBOL = SYMBOL | 0b01000000; + + if (a == 1) { + if (slot_id_ctrl > 27) { + slot_id_ctrl = 0; + sf = sf + 0x10; + + if (sf > 0x90){ + sf = 0; + } + } + } } - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ oai_slot = tx_subframe * 2 + tx_slot; lock_dl_buffer(bs->buffers, oai_slot); - if (!(bs->buffers->dl_busy[oai_slot] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sl.symbol %d.%d)\n", __FUNCTION__, - oai_slot, tx_symbol); + if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__, + a, oai_slot, tx_symbol); memset(IQ_ptr, 0, 1272 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, + memcpy(IQ_ptr, bs->buffers->dl[a][oai_slot] + tx_symbol * 1272*4, 1272*4); } //printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf); - bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][oai_slot] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, oai_slot); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 5088); - } - - // U-PLANE UL ANT_1 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x01 && dl_start == 1) - { - - // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) +10) % 14; - - ANT_NUM = 0x01; - SUBFRAME = sf; - - slot_id_ctrl++; - - // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; - - if(slot_id_ctrl > 27){ - slot_id_ctrl = 0; - sf = sf + 0x10; - - if (sf >0x90){ - sf = 0; - } - } - } - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 5088); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c index 52c9f24127..b34d69784f 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -35,63 +35,61 @@ printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - o old = t; #endif - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, + a, bs->expected_benetel_frame[a], bs->next_slot[a], bs->next_symbol[a], ul->frame, ul->slot, ul->symbol); } /* fill missing data with 0s */ - while (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - lock_ul_buffer(bs->buffers, bs->next_slot); - if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { - printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - bs->next_slot, bs->next_symbol); + while (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memset(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, 0, 1272*4); - bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_slot); - unlock_ul_buffer(bs->buffers, bs->next_slot); + bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_slot = (bs->next_slot + 1) % 20; - if (bs->next_slot == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } - lock_ul_buffer(bs->buffers, bs->next_slot); - if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { - printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - bs->next_slot, bs->next_symbol); + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memcpy(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, ul->iq, 1272*4); - bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_slot); - unlock_ul_buffer(bs->buffers, bs->next_slot); + bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_slot = (bs->next_slot + 1) % 20; - if (bs->next_slot == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/targets/ARCH/ETHERNET/benetel/5g/low.h index 5e1daee9d1..659819296a 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.h +++ b/targets/ARCH/ETHERNET/benetel/5g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_slot; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_slot[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c index 5e26f6782e..b26df07723 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c index b9da10b380..a302400eb4 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c @@ -45,11 +45,16 @@ void init_buffers(shared_buffers *s) * needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend * they are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; - s->dl_busy[4] = 0x3fff; - s->dl_busy[5] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[0][4] = 0x3fff; + s->dl_busy[0][5] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; + s->dl_busy[1][4] = 0x3fff; + s->dl_busy[1][5] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int slot) diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h index ca7dbd9c8f..9d51b8138d 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h @@ -26,10 +26,11 @@ #include typedef struct { - unsigned char dl[20][14*1272*4]; - unsigned char ul[20][14*1272*4]; - uint16_t dl_busy[20]; - uint16_t ul_busy[20]; + /* [2] is for two antennas */ + unsigned char dl[2][20][14*1272*4]; + unsigned char ul[2][20][14*1272*4]; + uint16_t dl_busy[2][20]; + uint16_t ul_busy[2][20]; pthread_mutex_t m_ul[20]; pthread_cond_t c_ul[20]; From 3efdb2775ee404c429186fa30f8d7fca04db7a08 Mon Sep 17 00:00:00 2001 From: dir Date: Thu, 28 Jan 2021 17:20:38 +0200 Subject: [PATCH 06/43] NR SCFDMA changes for higher RB sizes (RB Sizes until 100Mhz) --- openair1/PHY/MODULATION/nr_modulation.c | 105 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 117 ++- openair1/PHY/TOOLS/oai_dfts.c | 945 +++++++++++++++++- openair1/PHY/TOOLS/tools_defs.h | 41 +- 4 files changed, 1162 insertions(+), 46 deletions(-) diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 0a7088ba39..ed9a859fb6 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -325,10 +325,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) { -#if defined(__x86_64__) || defined(__i386__) - __m128i dft_in128[1][1200], dft_out128[1][1200]; +#if defined(__x86_64__) || +defined(__i386__) + __m128i dft_in128[1][3240], dft_out128[1][3240]; #elif defined(__arm__) - int16x8_t dft_in128[1][1200], dft_out128[1][1200]; + int16x8_t dft_in128[1][3240], dft_out128[1][3240]; #endif uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0]; @@ -340,8 +340,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) int16x8_t norm128; #endif - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - dft_in0[ip] = d[i]; + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { + dft_in0[ip] = d[i]; + } } switch (Msc_PUSCH) { @@ -480,7 +482,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) break; case 972: - dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_972,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); break; case 1080: @@ -494,11 +496,98 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) case 1200: dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); break; + + case 1296: + dft(DFT_1296,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1440: + dft(DFT_1440,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1500: + dft(DFT_1500,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1536: + //dft(DFT_1536,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_1536,(int16_t*)d, (int16_t*)z, 1); + break; + + case 1620: + dft(DFT_1620,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1728: + dft(DFT_1728,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1800: + dft(DFT_1800,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1920: + dft(DFT_1920,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1944: + dft(DFT_1944,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2160: + dft(DFT_2160,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2304: + dft(DFT_2304,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2400: + dft(DFT_2400,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2592: + dft(DFT_2592,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2700: + dft(DFT_2700,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2880: + dft(DFT_2880,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2916: + dft(DFT_2916,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 3000: + dft(DFT_3000,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 3072: + //dft(DFT_3072,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_3072,(int16_t*)d, (int16_t*)z, 1); + break; + + case 3240: + dft(DFT_3240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + default: + // should not be reached + LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH ); + return; + } - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - z[i] = dft_out0[ip]; + + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + z[i] = dft_out0[ip]; } + } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 7e6becb4a8..42d6cfad7a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) { #if defined(__x86_64__) || defined(__i386__) - __m128i idft_in128[1][1200], idft_out128[1][1200]; + __m128i idft_in128[1][3240], idft_out128[1][3240]; __m128i norm128; #elif defined(__arm__) - int16x8_t idft_in128[1][1200], idft_out128[1][1200]; + int16x8_t idft_in128[1][3240], idft_out128[1][3240]; int16x8_t norm128; #endif int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0]; @@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); - // conjugate input - for (i = 0; i < (Msc_PUSCH>>2); i++) { + if ((Msc_PUSCH % 1536) > 0) { + // conjugate input + for (i = 0; i < (Msc_PUSCH>>2); i++) { #if defined(__x86_64__)||defined(__i386__) - *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); + *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); #elif defined(__arm__) - *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); + *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); #endif + } + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + ((uint32_t*)idft_in0)[ip+0] = z[i]; } - for (i=0,ip=0; i 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + z[i] = ((uint32_t*)idft_out0)[ip]; - - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - z[i] = ((int32_t*)idft_out0)[ip]; - } - - // conjugate output - for (i = 0; i < (Msc_PUSCH>>2); i++) { + // conjugate output + for (i = 0; i < (Msc_PUSCH>>2); i++) { #if defined(__x86_64__) || defined(__i386__) - ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); + ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); #elif defined(__arm__) - *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); + *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); #endif + } } #if defined(__x86_64__) || defined(__i386__) @@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) } + void nr_ulsch_extract_rbs_single(int32_t **rxdataF, NR_gNB_PUSCH *pusch_vars, unsigned char symbol, diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c index e4e85f7ba9..6569f7eab5 100644 --- a/openair1/PHY/TOOLS/oai_dfts.c +++ b/openair1/PHY/TOOLS/oai_dfts.c @@ -5952,8 +5952,6 @@ void idft32768(int16_t *x,int16_t *y,unsigned char scale) #endif - - int16_t twa1536[1024],twb1536[1024]; // 512 x 3 @@ -9471,6 +9469,919 @@ void dft1200(int16_t *x,int16_t *y,unsigned char scale_flag) } + +static int16_t twa1296[431*2*4]; +static int16_t twb1296[431*2*4]; + +void dft1296(int16_t *x,int16_t *y,unsigned char scale_flag) //432 * 3 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1296[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1296[0]; + simd_q15_t x2128[1296];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1296];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<432; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+432] = x128[j+1]; + x2128[i+864] = x128[j+2]; + } + + dft432((int16_t *)x2128,(int16_t *)ytmp128,1); + dft432((int16_t *)(x2128+432),(int16_t *)(ytmp128+432),1); + dft432((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1); + + bfly3_tw1(ytmp128,ytmp128+432,ytmp128+864,y128,y128+432,y128+864); + + for (i=1,j=0; i<432; i++,j++) { + bfly3(ytmp128+i, + ytmp128+432+i, + ytmp128+864+i, + y128+i, + y128+432+i, + y128+864+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1296; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + + +static int16_t twa1440[479*2*4]; +static int16_t twb1440[479*2*4]; + +void dft1440(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1440[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1440[0]; + simd_q15_t x2128[1440];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1440];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<480; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+480] = x128[j+1]; + x2128[i+960] = x128[j+2]; + } + + dft480((int16_t *)x2128,(int16_t *)ytmp128,1); + dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1); + dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + + bfly3_tw1(ytmp128,ytmp128+480,ytmp128+960,y128,y128+480,y128+960); + + for (i=1,j=0; i<480; i++,j++) { + bfly3(ytmp128+i, + ytmp128+480+i, + ytmp128+960+i, + y128+i, + y128+480+i, + y128+960+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1440; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1500[2392]__attribute__((aligned(32))); +static int16_t twb1500[2392]__attribute__((aligned(32))); +static int16_t twc1500[2392]__attribute__((aligned(32))); +static int16_t twd1500[2392]__attribute__((aligned(32))); + +void dft1500(int16_t *x,int16_t *y,unsigned char scale_flag) +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1500[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1500[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc1500[0]; + simd_q15_t *twd128=(simd_q15_t *)&twd1500[0]; + simd_q15_t x2128[1500];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1500];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<300; i++,j+=5) { + x2128[i] = x128[j]; + x2128[i+300] = x128[j+1]; + x2128[i+600] = x128[j+2]; + x2128[i+900] = x128[j+3]; + x2128[i+1200] = x128[j+4]; + } + + dft300((int16_t *)x2128,(int16_t *)ytmp128,1); + dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1); + dft300((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft300((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1); + dft300((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + + bfly5_tw1(ytmp128,ytmp128+300,ytmp128+600,ytmp128+900,ytmp128+1200,y128,y128+300,y128+600,y128+900,y128+1200); + + for (i=1,j=0; i<300; i++,j++) { + bfly5(ytmp128+i, + ytmp128+300+i, + ytmp128+600+i, + ytmp128+900+i, + ytmp128+1200+i, + y128+i, + y128+300+i, + y128+600+i, + y128+900+i, + y128+1200+i, + twa128+j, + twb128+j, + twc128+j, + twd128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[15]); + + for (i=0; i<1500; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +} + +static int16_t twa1620[539*2*4]; +static int16_t twb1620[539*2*4]; + +void dft1620(int16_t *x,int16_t *y,unsigned char scale_flag) // 540 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1620[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1620[0]; + simd_q15_t x2128[1620];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1620];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<540; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+540] = x128[j+1]; + x2128[i+1080] = x128[j+2]; + } + + dft540((int16_t *)x2128,(int16_t *)ytmp128,1); + dft540((int16_t *)(x2128+540),(int16_t *)(ytmp128+540),1); + dft540((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1); + + bfly3_tw1(ytmp128,ytmp128+540,ytmp128+1080,y128,y128+540,y128+1080); + + for (i=1,j=0; i<540; i++,j++) { + bfly3(ytmp128+i, + ytmp128+540+i, + ytmp128+1080+i, + y128+i, + y128+540+i, + y128+1080+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1620; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1728[575*2*4]; +static int16_t twb1728[575*2*4]; + +void dft1728(int16_t *x,int16_t *y,unsigned char scale_flag) // 576 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1728[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1728[0]; + simd_q15_t x2128[1728];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1728];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<576; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+576] = x128[j+1]; + x2128[i+1152] = x128[j+2]; + } + + dft576((int16_t *)x2128,(int16_t *)ytmp128,1); + dft576((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1); + dft576((int16_t *)(x2128+1152),(int16_t *)(ytmp128+1152),1); + + bfly3_tw1(ytmp128,ytmp128+576,ytmp128+1152,y128,y128+576,y128+1152); + + for (i=1,j=0; i<576; i++,j++) { + bfly3(ytmp128+i, + ytmp128+576+i, + ytmp128+1152+i, + y128+i, + y128+576+i, + y128+1152+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1728; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1800[599*2*4]; +static int16_t twb1800[599*2*4]; + +void dft1800(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1800[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1800[0]; + simd_q15_t x2128[1800];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1800];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<600; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + + bfly3_tw1(ytmp128,ytmp128+600,ytmp128+1200,y128,y128+600,y128+1200); + + for (i=1,j=0; i<600; i++,j++) { + bfly3(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + y128+i, + y128+600+i, + y128+1200+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1800; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1920[479*2*4]; +static int16_t twb1920[479*2*4]; +static int16_t twc1920[479*2*4]; + +void dft1920(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 4 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1920[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1920[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc1920[0]; + simd_q15_t x2128[1920];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1920];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<480; i++,j+=4) { + x2128[i] = x128[j]; + x2128[i+480] = x128[j+1]; + x2128[i+960] = x128[j+2]; + x2128[i+1440] = x128[j+3]; + } + + dft480((int16_t *)x2128,(int16_t *)ytmp128,1); + dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1); + dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + dft480((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1); + + bfly4_tw1(ytmp128,ytmp128+480,ytmp128+960,ytmp128+1440,y128,y128+480,y128+960,y128+1440); + + for (i=1,j=0; i<480; i++,j++) { + bfly4(ytmp128+i, + ytmp128+480+i, + ytmp128+960+i, + ytmp128+1440+i, + y128+i, + y128+480+i, + y128+960+i, + y128+1440+i, + twa128+j, + twb128+j, + twc128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[13]); + for (i=0; i<1920; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1944[647*2*4]; +static int16_t twb1944[647*2*4]; + +void dft1944(int16_t *x,int16_t *y,unsigned char scale_flag) // 648 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1944[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1944[0]; + simd_q15_t x2128[1944];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1944];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<648; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+648] = x128[j+1]; + x2128[i+1296] = x128[j+2]; + } + + dft648((int16_t *)x2128,(int16_t *)ytmp128,1); + dft648((int16_t *)(x2128+648),(int16_t *)(ytmp128+648),1); + dft648((int16_t *)(x2128+1296),(int16_t *)(ytmp128+1296),1); + + bfly3_tw1(ytmp128,ytmp128+648,ytmp128+1296,y128,y128+648,y128+1296); + + for (i=1,j=0; i<648; i++,j++) { + bfly3(ytmp128+i, + ytmp128+648+i, + ytmp128+1296+i, + y128+i, + y128+648+i, + y128+1296+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1944; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2160[719*2*4]; +static int16_t twb2160[719*2*4]; + +void dft2160(int16_t *x,int16_t *y,unsigned char scale_flag) // 720 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2160[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2160[0]; + simd_q15_t x2128[2160];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2160];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<720; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+720] = x128[j+1]; + x2128[i+1440] = x128[j+2]; + } + + dft720((int16_t *)x2128,(int16_t *)ytmp128,1); + dft720((int16_t *)(x2128+720),(int16_t *)(ytmp128+720),1); + dft720((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1); + + bfly3_tw1(ytmp128,ytmp128+720,ytmp128+1440,y128,y128+720,y128+1440); + + for (i=1,j=0; i<720; i++,j++) { + bfly3(ytmp128+i, + ytmp128+720+i, + ytmp128+1440+i, + y128+i, + y128+720+i, + y128+1440+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2160; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2304[767*2*4]; +static int16_t twb2304[767*2*4]; + +void dft2304(int16_t *x,int16_t *y,unsigned char scale_flag) // 768 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2304[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2304[0]; + simd_q15_t x2128[2304];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2304];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<768; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+768] = x128[j+1]; + x2128[i+1536] = x128[j+2]; + } + + dft768((int16_t *)x2128,(int16_t *)ytmp128,1); + dft768((int16_t *)(x2128+768),(int16_t *)(ytmp128+768),1); + dft768((int16_t *)(x2128+1536),(int16_t *)(ytmp128+1536),1); + + bfly3_tw1(ytmp128,ytmp128+768,ytmp128+1536,y128,y128+768,y128+1536); + + for (i=1,j=0; i<768; i++,j++) { + bfly3(ytmp128+i, + ytmp128+768+i, + ytmp128+1536+i, + y128+i, + y128+768+i, + y128+1536+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2304; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2400[599*2*4]; +static int16_t twb2400[599*2*4]; +static int16_t twc2400[599*2*4]; + +void dft2400(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 4 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2400[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2400[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc2400[0]; + simd_q15_t x2128[2400];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2400];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<600; i++,j+=4) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + x2128[i+1800] = x128[j+3]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + + bfly4_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,y128,y128+600,y128+1200,y128+1800); + + for (i=1,j=0; i<600; i++,j++) { + bfly4(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + ytmp128+1800+i, + y128+i, + y128+600+i, + y128+1200+i, + y128+1800+i, + twa128+j, + twb128+j, + twc128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[13]); + for (i=0; i<2400; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2592[863*2*4]; +static int16_t twb2592[863*2*4]; + +void dft2592(int16_t *x,int16_t *y,unsigned char scale_flag) // 864 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2592[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2592[0]; + simd_q15_t x2128[2592];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2592];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<864; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+864] = x128[j+1]; + x2128[i+1728] = x128[j+2]; + } + + dft864((int16_t *)x2128,(int16_t *)ytmp128,1); + dft864((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1); + dft864((int16_t *)(x2128+1728),(int16_t *)(ytmp128+1728),1); + + bfly3_tw1(ytmp128,ytmp128+864,ytmp128+1728,y128,y128+864,y128+1728); + + for (i=1,j=0; i<864; i++,j++) { + bfly3(ytmp128+i, + ytmp128+864+i, + ytmp128+1728+i, + y128+i, + y128+864+i, + y128+1728+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2592; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2700[899*2*4]; +static int16_t twb2700[899*2*4]; + +void dft2700(int16_t *x,int16_t *y,unsigned char scale_flag) // 900 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2700[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2700[0]; + simd_q15_t x2128[2700];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2700];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<900; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+900] = x128[j+1]; + x2128[i+1800] = x128[j+2]; + } + + dft900((int16_t *)x2128,(int16_t *)ytmp128,1); + dft900((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1); + dft900((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + + bfly3_tw1(ytmp128,ytmp128+900,ytmp128+1800,y128,y128+900,y128+1800); + + for (i=1,j=0; i<900; i++,j++) { + bfly3(ytmp128+i, + ytmp128+900+i, + ytmp128+1800+i, + y128+i, + y128+900+i, + y128+1800+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2700; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2880[959*2*4]; +static int16_t twb2880[959*2*4]; + +void dft2880(int16_t *x,int16_t *y,unsigned char scale_flag) // 960 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2880[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2880[0]; + simd_q15_t x2128[2880];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2880];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<960; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+960] = x128[j+1]; + x2128[i+1920] = x128[j+2]; + } + + dft960((int16_t *)x2128,(int16_t *)ytmp128,1); + dft960((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + dft960((int16_t *)(x2128+1920),(int16_t *)(ytmp128+1920),1); + + bfly3_tw1(ytmp128,ytmp128+960,ytmp128+1920,y128,y128+960,y128+1920); + + for (i=1,j=0; i<960; i++,j++) { + bfly3(ytmp128+i, + ytmp128+960+i, + ytmp128+1920+i, + y128+i, + y128+960+i, + y128+1920+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2880; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2916[971*2*4]; +static int16_t twb2916[971*2*4]; + +void dft2916(int16_t *x,int16_t *y,unsigned char scale_flag) // 972 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2916[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2916[0]; + simd_q15_t x2128[2916];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2916];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<972; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+972] = x128[j+1]; + x2128[i+1944] = x128[j+2]; + } + + dft972((int16_t *)x2128,(int16_t *)ytmp128,1); + dft972((int16_t *)(x2128+972),(int16_t *)(ytmp128+972),1); + dft972((int16_t *)(x2128+1944),(int16_t *)(ytmp128+1944),1); + + bfly3_tw1(ytmp128,ytmp128+972,ytmp128+1944,y128,y128+972,y128+1944); + + for (i=1,j=0; i<972; i++,j++) { + bfly3(ytmp128+i, + ytmp128+972+i, + ytmp128+1944+i, + y128+i, + y128+972+i, + y128+1944+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2916; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa3000[599*8]__attribute__((aligned(32))); +static int16_t twb3000[599*8]__attribute__((aligned(32))); +static int16_t twc3000[599*8]__attribute__((aligned(32))); +static int16_t twd3000[599*8]__attribute__((aligned(32))); + +void dft3000(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 * 5 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa3000[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb3000[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc3000[0]; + simd_q15_t *twd128=(simd_q15_t *)&twd3000[0]; + simd_q15_t x2128[3000];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[3000];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<600; i++,j+=5) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + x2128[i+1800] = x128[j+3]; + x2128[i+2400] = x128[j+4]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + dft600((int16_t *)(x2128+2400),(int16_t *)(ytmp128+2400),1); + + bfly5_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,ytmp128+2400,y128,y128+600,y128+1200,y128+1800,y128+2400); + + for (i=1,j=0; i<600; i++,j++) { + bfly5(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + ytmp128+1800+i, + ytmp128+2400+i, + y128+i, + y128+600+i, + y128+1200+i, + y128+1800+i, + y128+2400+i, + twa128+j, + twb128+j, + twc128+j, + twd128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[15]); + + for (i=0; i<3000; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +} + +static int16_t twa3240[1079*2*4]; +static int16_t twb3240[1079*2*4]; + +void dft3240(int16_t *x,int16_t *y,unsigned char scale_flag) // 1080 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa3240[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb3240[0]; + simd_q15_t x2128[3240];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[3240];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<1080; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+1080] = x128[j+1]; + x2128[i+2160] = x128[j+2]; + } + + dft1080((int16_t *)x2128,(int16_t *)ytmp128,1); + dft1080((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1); + dft1080((int16_t *)(x2128+2160),(int16_t *)(ytmp128+2160),1); + + bfly3_tw1(ytmp128,ytmp128+1080,ytmp128+2160,y128,y128+1080,y128+2160); + + for (i=1,j=0; i<1080; i++,j++) { + bfly3(ytmp128+i, + ytmp128+1080+i, + ytmp128+2160+i, + y128+i, + y128+1080+i, + y128+2160+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<3240; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + void init_rad4(int N,int16_t *tw) { int16_t *twa = tw; @@ -9492,7 +10403,7 @@ void init_rad4_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc) { int i,j; for (i=1;i<(N/4);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); @@ -9525,7 +10436,7 @@ void init_rad2_rep(int N,int16_t *twa) { int i,j; for (i=1;i<(N/2);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); for (j=1;j<4;j++) { ((int32_t*)twa)[j]=((int32_t*)twa)[0]; @@ -9551,7 +10462,7 @@ void init_rad3_rep(int N,int16_t *twa,int16_t *twb) { int i,j; for (i=1;i<(N/3);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); @@ -9569,7 +10480,7 @@ void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) { int i,j; for (i=1;i<(N/5);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); @@ -9586,7 +10497,7 @@ void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) { twa+=8; twb+=8; twc+=8; - twd+=8; + twd+=8; } } /*----------------------------------------------------------------*/ @@ -9600,7 +10511,7 @@ int dfts_autoinit(void) init_rad2(8192,tw8192); init_rad4(16384,tw16384); init_rad2(32768,tw32768); - + init_rad3(1536,twa1536,twb1536); init_rad3(3072,twa3072,twb3072); init_rad3(6144,twa6144,twb6144); @@ -9645,6 +10556,24 @@ int dfts_autoinit(void) init_rad3_rep(1080,twa1080,twb1080); init_rad4_rep(1152,twa1152,twb1152,twc1152); init_rad4_rep(1200,twa1200,twb1200,twc1200); + init_rad3_rep(1296,twa1296,twb1296); + init_rad3_rep(1440,twa1440,twb1440); + init_rad5_rep(1500,twa1500,twb1500,twc1500,twd1500); + init_rad3_rep(1620,twa1620,twb1620); + init_rad3_rep(1728,twa1728,twb1728); + init_rad3_rep(1800,twa1800,twb1800); + init_rad4_rep(1920,twa1920,twb1920, twc1920); + init_rad3_rep(1944,twa1944,twb1944); + init_rad3_rep(2160,twa2160,twb2160); + init_rad3_rep(2304,twa2304,twb2304); + init_rad4_rep(2400,twa2400,twb2400,twc2400); + init_rad3_rep(2592,twa2592,twb2592); + init_rad3_rep(2700,twa2700,twb2700); + init_rad3_rep(2880,twa2880,twb2880); + init_rad3_rep(2916,twa2916,twb2916); + init_rad5_rep(3000,twa3000,twb3000,twc3000,twd3000); + init_rad3_rep(3240,twa3240,twb3240); + return 0; } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 12467e1fdc..db7ac3d813 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -226,9 +226,26 @@ void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag); +void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag); void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag); void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag); +void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag); void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag); void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag); void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag); @@ -283,21 +300,25 @@ typedef enum DFT_size_idx { DFT_108, DFT_120, DFT_128, DFT_144, DFT_180, DFT_192, DFT_216, DFT_240, DFT_256, DFT_288, DFT_300, DFT_324, DFT_360, DFT_384, DFT_432, DFT_480, DFT_512, DFT_540, DFT_576, DFT_600, DFT_648, DFT_720, DFT_768, DFT_864, - DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1536, - DFT_2048, DFT_3072, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, DFT_18432, - DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, + DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1296, + DFT_1440, DFT_1500, DFT_1536, DFT_1620, DFT_1728, DFT_1800, DFT_1920, DFT_1944, + DFT_2048, DFT_2160, DFT_2304, DFT_2400, DFT_2592, DFT_2700, DFT_2880, DFT_2916, + DFT_3000, DFT_3072, DFT_3240, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, + DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, DFT_SIZE_IDXTABLESIZE } dft_size_idx_t; #ifdef OAIDFTS_MAIN adftfunc_t dft_ftab[]={ dft12, dft24, dft36, dft48, dft60, dft72, dft96, - dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, + dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, dft256, dft288, dft300, dft324, dft360, dft384, dft432, dft480, dft512, dft540, dft576, dft600, dft648, dft720, dft768, dft864, - dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1536, - dft2048, dft3072, dft4096, dft6144, dft8192, dft9216, dft12288, dft18432, - dft24576, dft36864, dft49152, dft73728, dft98304 + dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1296, + dft1440, dft1500, dft1536, dft1620, dft1728, dft1800, dft1920, dft1944, + dft2048, dft2160, dft2304, dft2400, dft2592, dft2700, dft2880, dft2916, + dft3000, dft3072, dft3240, dft4096, dft6144, dft8192, dft9216, dft12288, + dft18432, dft24576, dft36864, dft49152, dft73728, dft98304 }; #endif @@ -309,9 +330,9 @@ typedef enum idft_size_idx { } idft_size_idx_t; #ifdef OAIDFTS_MAIN aidftfunc_t idft_ftab[]={ - idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, - idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, - idft73728, idft98304 + idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, + idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, + idft73728, idft98304 }; #endif From 12517f02e2794cf87379fb98e61a737cfba6c937 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 9 Feb 2021 11:10:58 +0100 Subject: [PATCH 07/43] Reverting shifting the TX 4 bits to the left to exploit dynamic range. adapted ssb_block_power to measured value This partially reverts commit 857f9179f35216e36ca16ed08cde193e81a418bc. Conflicts: targets/ARCH/ETHERNET/benetel/5g/benetel.c --- targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index ba44e989b9..940d619a51 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -194,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = -10; + ssPBCH_BlockPower = -35; } ); From d2aa1326166b2fb806a7cd66d1637e858fe2fea0 Mon Sep 17 00:00:00 2001 From: dir Date: Tue, 9 Feb 2021 15:16:40 +0200 Subject: [PATCH 08/43] Msg3_transformprecoder value initialised to TRANSFORM PRECODING DISABLED --- openair2/GNB_APP/gnb_config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index d830e51f4d..5b6f624ede 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -162,6 +162,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); + // 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED. + *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon)); From cfebcd19bd5910b24047057cb4825b08e5769f0b Mon Sep 17 00:00:00 2001 From: dir Date: Tue, 9 Feb 2021 17:32:51 +0200 Subject: [PATCH 09/43] Corrections to 217RBs, 273RB configuration files. RFSIM works with these changes --- .../CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 11 ++++++++--- .../CONF/gnb.band78.tm1.273PRB.usrpn300.conf | 9 +++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 0659641607..40361aaf4e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -33,7 +33,7 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) - absoluteFrequencySSB = 642364; + absoluteFrequencySSB = 642016;#642364; dl_frequencyBand = 78; # this is 3600 MHz dl_absoluteFrequencyPointA = 640000; @@ -130,16 +130,21 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; #2; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6; #2; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 0a6268f8a8..a899845cb8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -130,16 +130,21 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6;#2; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6;#2; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; From 13086925c981ba8dcc9da3c80d57526e0011c299 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 10 Feb 2021 11:21:40 +0100 Subject: [PATCH 10/43] Add tests for 80 and 100 MHz SC-FDMA to nr_ulsim autotests for CI --- cmake_targets/autotests/test_case_list.xml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 6d3424b420..089d0503fd 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1292,7 +1292,9 @@ (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols), (Test9: SC-FDMA, 50 PRBs), (Test10: SC-FDMA, 75 PRBs), - (Test11: SC-FDMA, 3 DMRS) + (Test11: SC-FDMA, 216 PRBs), + (Test12: SC-FDMA, 273 PRBs), + (Test13: SC-FDMA, 3 DMRS) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1307,10 +1309,13 @@ -n100 -s5 -T 2 1 2 -U 2 0 2 -n100 -s5 -T 2 2 2 -U 2 1 2 -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 - -n100 -s20 -Z - -n100 -s20 -Z -r75 - -n100 -s20 -Z -U 2 0 2 - nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 + -n100 -s2 -Z + -n100 -s2 -Z -r75 + -n100 -s2 -Z -r216 -R217 + -n100 -s2 -Z -r270 -R273 + -n100 -s2 -Z -U 2 0 2 + + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 From 2c5bd9fa8c9c3acb418978c6a9c3756f951827e9 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Wed, 10 Feb 2021 17:49:14 +0100 Subject: [PATCH 11/43] improve rfsim --- executables/nr-uesoftmodem.c | 5 +- openair2/NETWORK_DRIVER/UE_IP/device.c | 4 ++ targets/ARCH/COMMON/common_lib.h | 28 ++------- targets/ARCH/rfsimulator/simulator.c | 86 ++++++++++++-------------- 4 files changed, 54 insertions(+), 69 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 87cd157948..5d651344d6 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -557,11 +557,14 @@ int main( int argc, char **argv ) { init_NR_UE_threads(1); - config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); printf("UE threads created by %ld\n", gettid()); // wait for end of program printf("TYPE TO TERMINATE\n"); + // Sleep a while before checking all parameters have been used + // Some are used directly in external threads, asynchronously + sleep(20); + config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); while(true) sleep(3600); diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 32f9442747..e3c0f92ec7 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -302,7 +302,11 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) { } //--------------------------------------------------------------------------- +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) void ue_ip_tx_timeout(struct net_device *dev_pP) { +#else +void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int x) { +#endif //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. ue_ip_priv_t *priv_p = netdev_priv(dev_pP); diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 85ee80ea7c..93e9ffb52f 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -105,9 +105,10 @@ typedef enum { ADRV9371_ZC706_DEV, /*!\brief device is UEDv2 */ UEDv2_DEV, + RFSIMULATOR, MAX_RF_DEV_TYPE } dev_type_t; -#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"} +#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2", "RFSIMULATOR"} /*!\brief transport protocol types */ typedef enum { @@ -491,15 +492,11 @@ struct openair0_device_t { typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); /* type of transport init function, implemented in shared lib */ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); -#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record -#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record -#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record +#define UE_MAGICDL 0xA5A5A5A5A5A5A5A5 // UE DL FDD record +#define UE_MAGICUL 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record -#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record -#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record -#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record +#define ENB_MAGICDL 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record +#define ENB_MAGICUL 0x5B5B5B5B5B5B5B5B // eNB UL FDD record #define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) @@ -516,19 +513,6 @@ typedef struct { uint32_t option_flag; // Option flag } samplesBlockHeader_t; -#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record -#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record -#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record - -#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record -#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record -#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record -#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record - -#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) - - #ifdef __cplusplus extern "C" { diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 79bf3dd077..c8a9e977b7 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -76,15 +76,16 @@ extern RAN_CONTEXT_t RC; /* configuration parameters for the rfsimulator device */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define RFSIMULATOR_PARAMS_DESC {\ - {"serveraddr", "\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ - {"serverport", "\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ - {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ - {"IQfile", "\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ - {"modelname", "\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ - {"ploss", "\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ - {"forgetfact", "\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ - {"offset", "\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ +#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED +#define RFSIMULATOR_PARAMS_DESC { \ + {"serveraddr", "\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ + {"serverport", "\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ + {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ + {"IQfile", "\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ + {"modelname", "\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ + {"ploss", "\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ + {"forgetfact", "\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ + {"offset", "\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ }; @@ -137,7 +138,7 @@ typedef struct { } rfsimulator_state_t; -void allocCirBuf(rfsimulator_state_t *bridge, int sock) { +static void allocCirBuf(rfsimulator_state_t *bridge, int sock) { buffer_t *ptr=&bridge->buf[sock]; AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); @@ -195,7 +196,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { } } -void removeCirBuf(rfsimulator_state_t *bridge, int sock) { +static void removeCirBuf(rfsimulator_state_t *bridge, int sock) { AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); close(sock); free(bridge->buf[sock].circularBuf); @@ -206,12 +207,12 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->buf[sock].conn_sock=-1; } -void socketError(rfsimulator_state_t *bridge, int sock) { +static void socketError(rfsimulator_state_t *bridge, int sock) { if (bridge->buf[sock].conn_sock!=-1) { LOG_W(HW,"Lost socket \n"); removeCirBuf(bridge, sock); - if (bridge->typeStamp==UE_MAGICDL_FDD) + if (bridge->typeStamp==UE_MAGICDL) exit(1); } } @@ -229,7 +230,7 @@ enum blocking_t { blocking }; -void setblocking(int sock, enum blocking_t active) { +static void setblocking(int sock, enum blocking_t active) { int opts; AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,""); @@ -243,7 +244,7 @@ void setblocking(int sock, enum blocking_t active) { static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps); -void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { +static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if (t->saveIQfile != -1) { if (write(t->saveIQfile, _buf, count) != count ) LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno)); @@ -277,7 +278,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { } } -void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { +static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { char *saveF=NULL; char *modelname=NULL; paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC; @@ -312,9 +313,9 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 || strncasecmp(rfsimulator->ip,"server",3) == 0 ) - rfsimulator->typeStamp = ENB_MAGICDL_FDD; + rfsimulator->typeStamp = ENB_MAGICDL; else - rfsimulator->typeStamp = UE_MAGICDL_FDD; + rfsimulator->typeStamp = UE_MAGICDL; } static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { @@ -358,9 +359,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, return CMDSTATUS_FOUND; } -int server_start(openair0_device *device) { +static int startServer(openair0_device *device) { rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; - t->typeStamp=ENB_MAGICDL_FDD; + t->typeStamp=ENB_MAGICDL; AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); int enable = 1; AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); @@ -381,9 +382,9 @@ sin_addr: return 0; } -int start_ue(openair0_device *device) { +static int startClient(openair0_device *device) { rfsimulator_state_t *t = device->priv; - t->typeStamp=UE_MAGICDL_FDD; + t->typeStamp=UE_MAGICDL; int sock; AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); struct sockaddr_in addr = { @@ -458,7 +459,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp return nsamps; } -int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { +static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false); } @@ -534,8 +535,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi // check the header and start block transfer if ( b->headerMode==true && b->remainToTransfer==0) { - AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) || - (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol"); + AssertFatal( (t->typeStamp == UE_MAGICDL && b->th.magic==ENB_MAGICDL) || + (t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol"); b->headerMode=false; if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS @@ -606,7 +607,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi return nfds>0; } -int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { +static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { if (nbAnt != 1) { LOG_W(HW, "rfsimulator: only 1 antenna tested\n"); } @@ -748,31 +749,24 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo signal_energy(samplesVoid[0], nsamps)); return nsamps; } -int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { - abort(); + +static int rfsimulator_get_stats(openair0_device *device) { return 0; } -int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) { - abort(); +static int rfsimulator_reset_stats(openair0_device *device) { return 0; } -int rfsimulator_get_stats(openair0_device *device) { +static void rfsimulator_end(openair0_device *device) {} +static int rfsimulator_stop(openair0_device *device) { return 0; } -int rfsimulator_reset_stats(openair0_device *device) { +static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; } -void rfsimulator_end(openair0_device *device) {} -int rfsimulator_stop(openair0_device *device) { +static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } -int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { - return 0; -} -int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { - return 0; -} -int rfsimulator_write_init(openair0_device *device) { +static int rfsimulator_write_init(openair0_device *device) { return 0; } __attribute__((__visibility__("default"))) @@ -782,10 +776,10 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); rfsimulator_readconfig(rfsimulator); pthread_mutex_init(&Sockmutex, NULL); - LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE"); - device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ? - server_start : - start_ue; + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side"); + device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ? + startServer : + startClient; device->trx_get_stats_func = rfsimulator_get_stats; device->trx_reset_stats_func = rfsimulator_reset_stats; device->trx_end_func = rfsimulator_end; @@ -795,7 +789,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_write_func = rfsimulator_write; device->trx_read_func = rfsimulator_read; /* let's pretend to be a b2x0 */ - device->type = USRP_B200_DEV; + device->type = RFSIMULATOR; device->openair0_cfg=&openair0_cfg[0]; device->priv = rfsimulator; device->trx_write_init = rfsimulator_write_init; From b3e21ad87beb1e3d9c0d9f0516cd3489ebdf70d6 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Wed, 10 Feb 2021 17:58:10 +0100 Subject: [PATCH 12/43] only a printf --- targets/ARCH/rfsimulator/simulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index c8a9e977b7..cd35c46a15 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -484,7 +484,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); setblocking(conn_sock, notBlocking); allocCirBuf(t, conn_sock); - LOG_I(HW,"A ue connected, sending the current time\n"); + LOG_I(HW,"A client connected, sending the current time\n"); struct complex16 v= {0}; void *samplesVoid[t->tx_num_channels]; From eaadda1f5d59de614f0980ae9afd1c9b14773414 Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 16:39:04 +0100 Subject: [PATCH 13/43] Update FAPI nfapi_nr_tx_precoding_and_beamforming_t --- nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 12748b7a9e..31ac912edf 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -619,8 +619,10 @@ typedef struct { uint16_t prgSize; /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 uint8_t digBFInterfaces; + // Depends on numPRGs uint16_t PMIdx[275]; - uint16_t *beamIdx[275]; + // Depends on digBFInterfaces + uint16_t beamIdx[256]; } nfapi_nr_tx_precoding_and_beamforming_t; //table 3-37 From 4dacea921cc80ca9487c9c879d267d0fe6b610d2 Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 16:41:25 +0100 Subject: [PATCH 14/43] New UE: check for free RA and copy preamble list --- openair2/LAYER2/NR_MAC_gNB/config.c | 30 ++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 6aa906b82b..8f28424ddb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -400,21 +400,37 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup); LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti); } else if (add_ue == 1 && !get_softmodem_params()->phy_test) { - /* TODO: should check for free RA process */ const int CC_id = 0; - NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0]; - ra->state = RA_IDLE; + NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id]; + uint8_t ra_index = 0; + /* checking for free RA process */ + for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) { + if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break; + } + if (ra_index == NR_NB_RA_PROC_MAX) { + LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti); + return -1; + } + NR_RA_t *ra = &cc->ra[ra_index]; ra->secondaryCellGroup = secondaryCellGroup; if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) { if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) { ra->cfra = true; ra->rnti = rnti; - struct NR_CFRA cfra = *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; - uint8_t num_preamble = cfra.resources.choice.ssb->ssb_ResourceList.list.count; + struct NR_CFRA *cfra = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; + uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count; ra->preambles.num_preambles = num_preamble; ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); - for (int i = 0; i < num_preamble; i++) - ra->preambles.preamble_list[i] = cfra.resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + for(int i=0; inum_active_ssb; i++) { + for(int j=0; jssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ssb) { + // one dedicated preamble for each beam + ra->preambles.preamble_list[i] = + cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + break; + } + } + } } } LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti); From baba8d69be3c6cdcae65826c235ead045b6de708 Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 16:43:03 +0100 Subject: [PATCH 15/43] nr_initiate_ra_proc(): check in all RA processes, check beam_index --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index b914e80d23..61f3a5d23b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -439,7 +439,8 @@ void nr_initiate_ra_proc(module_id_t module_idP, gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_RA_t *ra = &cc->ra[0]; + for(int i=0; ira[i]; uint16_t ra_rnti; @@ -450,23 +451,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, else ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); - - // if the preamble received correspond to one of the listed - // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries - int pr_found=0; - for (int i = 0; i < ra->preambles.num_preambles; i++) { - if (preamble_index == ra->preambles.preamble_list[i]) { - pr_found=1; - break; - } - } - - if (!pr_found) { - LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", - module_idP, preamble_index); - - return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc - } // This should be handled differently when we use the initialBWP for RA ra->bwp_id=1; NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; @@ -479,10 +463,20 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, - slotP, - preamble_index, - freq_index, - symbol); + slotP, + preamble_index, + freq_index, + symbol); + int pr_found=0; + if (preamble_index == ra->preambles.preamble_list[beam_index]) { + pr_found=1; + } + if (!pr_found) { + LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", + module_idP, preamble_index); + return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc + } + int loop = 0; LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); ra->state = Msg2; @@ -536,6 +530,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, return; } + } LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); From 054934c4f81229bc07b341a1dd34fc0a7df90ecc Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 16:44:31 +0100 Subject: [PATCH 16/43] Do nr_schedule_RA() for all RA processes --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 61f3a5d23b..df7f0cb46a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -536,37 +536,31 @@ void nr_initiate_ra_proc(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ - - //uint8_t i = 0; - int CC_id = 0; +void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; start_meas(&mac->schedule_ra); - -// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { -// for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - -// NR_RA_t *ra = &cc->ra[i]; - NR_RA_t *ra = &cc->ra[0]; - - LOG_D(MAC,"RA[state:%d]\n",ra->state); - switch (ra->state){ - case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP); - break; - case Msg4: - //generate_Msg4(module_idP, CC_id, frameP, slotP); - break; - case WAIT_Msg4_ACK: - //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); - break; - default: - break; + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + LOG_D(MAC, "RA[state:%d]\n", ra->state); + switch (ra->state) { + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP); + break; + case Msg4: + // generate_Msg4(module_idP, CC_id, frameP, slotP); + break; + case WAIT_Msg4_ACK: + // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); + break; + default: + break; + } + } } -// } -// } stop_meas(&mac->schedule_ra); } From 68b4a6bf28bd9984ca44b836a1689eaeddc939e5 Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Fri, 23 Oct 2020 15:10:45 +0530 Subject: [PATCH 17/43] Fixing association period --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index df7f0cb46a..2f716c61cf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -181,25 +181,28 @@ void find_SSB_and_RO_available(module_id_t module_idP) { } } - for(int i = 1; (1 << (i-1)) <= max_association_period;i++) { + cc->total_prach_occasions_per_config_period = total_RA_occasions; + for(int i=1; (1 << (i-1)) < max_association_period; i++) { + cc->max_association_period = (1 <<(i-1)); + total_RA_occasions = total_RA_occasions * cc->max_association_period; if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) { repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb); break; } - else { - total_RA_occasions = total_RA_occasions * i; - cc->max_association_period = i; - } } - if(cc->max_association_period == 0) - cc->max_association_period = 1; unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO); cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion; cc->num_active_ssb = num_active_ssb; - LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n", - cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn); + LOG_I(MAC, + "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n", + cc->total_prach_occasions, + cc->num_active_ssb, + unused_RA_occasion, + cc->max_association_period, + N_RA_sfn, + cc->total_prach_occasions_per_config_period); } void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) From 25a520e4fae8a135b315318c0f0314fa85af27cf Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 15:54:16 +0100 Subject: [PATCH 18/43] find_SSB_and_RO_available() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 32 +++++++++++++++++++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 ++ 2 files changed, 34 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 2f716c61cf..535fad5685 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -151,6 +151,38 @@ void find_SSB_and_RO_available(module_id_t module_idP) { uint8_t num_active_ssb = 0; uint8_t max_association_period = 1; + struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB; + + switch (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present); + break; + } + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; else diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index bca974a00f..8206052896 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -215,6 +215,8 @@ typedef struct { uint8_t max_association_period; //SSB index uint8_t ssb_index[MAX_NUM_OF_SSB]; + //CB preambles for each SSB + uint8_t cb_preambles_per_ssb; } NR_COMMON_channels_t; From 66ffa08a3dac7d199d702446fdb235be451014b6 Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 17:07:11 +0100 Subject: [PATCH 19/43] Handle individual RAs in nr_generate_Msg2() and nr_add_msg3() * add the RA process to handle to command parameters * Do not create the RAR_pdu into an intermediate array, but directly into the nFAPI TX_req * Slightly restructure nr_generate_Msg2() to first make AssertFatal() checks, then proceed allocating --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 70 ++++++++----------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 4 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 - 4 files changed, 34 insertions(+), 48 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 535fad5685..35f6d35136 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -583,7 +583,7 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) LOG_D(MAC, "RA[state:%d]\n", ra->state); switch (ra->state) { case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP); + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); break; case Msg4: // generate_Msg4(module_idP, CC_id, frameP, slotP); @@ -656,12 +656,11 @@ void nr_get_Msg3alloc(module_id_t module_id, ra->msg3_first_rb = rbStart; } -void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ - +void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_RA_t *ra = &cc->ra[0]; if (ra->state == RA_IDLE) { LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -776,27 +775,25 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t pusch_pdu->nrOfLayers = 1)>>3; // calling function to fill rar message - nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu); - + nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); } -// WIP -// todo: -// - fix me -// - get msg3 alloc (see nr_process_rar) -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP) +void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { - int mcsIndex; int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; - NR_RA_t *ra = &cc->ra[CC_id]; NR_SearchSpace_t *ss = ra->ra_ss; + // This code from this point on will not work on initialBWP or CORESET0 + AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n"); + + AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti); + AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + uint16_t RA_rnti = ra->RA_rnti; long locationAndBandwidth; @@ -804,7 +801,7 @@ void nr_generate_Msg2(module_id_t module_idP, // get the BW of the PDCCH for PDCCH size and RAR PDSCH size NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int dci10_bw; + int dci10_bw = 0; if (ra->coreset0_configured == 1) { AssertFatal(1==0,"This is a standalone condition\n"); @@ -817,7 +814,10 @@ void nr_generate_Msg2(module_id_t module_idP, if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - // Checking if the DCI allocation is feasible in current subframe + // Checking if the DCI allocation is feasible in current subframe: we might + // need to need up to two (PDCCH + PDSCH) messages, so check that we can + // always allocate both (this might be an overestimation, since the PDCCH + // message might already exist) if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti); return; @@ -840,8 +840,6 @@ void nr_generate_Msg2(module_id_t module_idP, return; } - nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; - /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not * exist, create it. This is especially important if we have multiple RAs, * and the DLSCH has to reuse them, so we need to mark them */ @@ -868,14 +866,6 @@ void nr_generate_Msg2(module_id_t module_idP, LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); - // This code from this point on will not work on initialBWP or CORESET0 - AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n"); - - AssertFatal(ra->secondaryCellGroup, - "no secondaryCellGroup for RNTI %04x\n", - ra->crnti); - AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); @@ -998,17 +988,8 @@ void nr_generate_Msg2(module_id_t module_idP, dci10_bw, ra->bwp_id); - // Program UL processing for Msg3 - nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra); - LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); - nr_add_msg3(module_idP, CC_id, frameP, slotP); - ra->state = WAIT_Msg3; - LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); - - x_Overhead = 0; - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling); - // DL TX request + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; @@ -1016,11 +997,20 @@ void nr_generate_Msg2(module_id_t module_idP, nr_mac->TX_req[CC_id].SFN = frameP; nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].Slot = slotP; - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + + // Program UL processing for Msg3 + nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra); + LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); + ra->state = WAIT_Msg3; + LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + + x_Overhead = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling); T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */, - T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length)); + T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); /* mark the corresponding RBs as used */ uint16_t *vrb_map = cc[CC_id].vrb_map; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 8dbe8728f3..1e98280222 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -245,7 +245,9 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, TX_req->PDU_index = nr_mac->pdu_index[CC_id]++; TX_req->num_TLV = 1; TX_req->TLVs[0].length = 8; - memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length); + // why do we copy from RAR_pdu here? Shouldn't we fill some more or less + // meaningful data, e.g., padding + random data? + //memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length); nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].SFN=frameP; nr_mac->TX_req[CC_id].Slot=slotP; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 26d29f9412..3502a11580 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -346,11 +346,7 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); - -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP); +void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_process_mac_pdu( module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 8206052896..63587d58a4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -194,8 +194,6 @@ typedef struct { uint32_t PCCH_alloc_pdu; /// Outgoing PCCH pdu for PHY PCCH_PDU PCCH_pdu; - /// Outgoing RAR pdu for PHY - RAR_PDU RAR_pdu; /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels From bf81ea19d310d6a98e5bba05d991d9cf91aeda4c Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 17:07:53 +0100 Subject: [PATCH 20/43] Check cfra in nr_initiate_ra_proc() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 35f6d35136..fa5cacfba4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -502,6 +502,9 @@ void nr_initiate_ra_proc(module_id_t module_idP, preamble_index, freq_index, symbol); + + // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries + if (ra->cfra) { int pr_found=0; if (preamble_index == ra->preambles.preamble_list[beam_index]) { pr_found=1; @@ -511,7 +514,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, module_idP, preamble_index); return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc } - + } int loop = 0; LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); ra->state = Msg2; From 13e719d74a31e35d82ff46d2f34e8c577988de2d Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 17:12:13 +0100 Subject: [PATCH 21/43] fixes nr_initiate_ra_proc() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index fa5cacfba4..99a17566ce 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -474,9 +474,23 @@ void nr_initiate_ra_proc(module_id_t module_idP, gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - for(int i=0; iuplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) + total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + + if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/ + num_ssb_per_RO -= 3; + total_RApreambles = total_RApreambles/num_ssb_per_RO ; + } + + for(int i=0; ira[i]; + if (ra->state == RA_IDLE) { + if((preamble_index < total_RApreambles) && (preamble_index > cc->cb_preambles_per_ssb) && (!ra->cfra)) continue; + uint16_t ra_rnti; // ra_rnti from 5.1.3 in 38.321 @@ -494,8 +508,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index); - if (ra->state == RA_IDLE) { - uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, @@ -505,14 +517,11 @@ void nr_initiate_ra_proc(module_id_t module_idP, // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries if (ra->cfra) { - int pr_found=0; - if (preamble_index == ra->preambles.preamble_list[beam_index]) { - pr_found=1; - } - if (!pr_found) { + // if the preamble received correspond to one of the listed + if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", module_idP, preamble_index); - return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc + continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc } } int loop = 0; From 37d112f5118ffda01f4117bf4e1d7a7d8a8976fe Mon Sep 17 00:00:00 2001 From: "kn.raju" Date: Thu, 11 Feb 2021 17:08:51 +0100 Subject: [PATCH 22/43] Check that resources are free for Msg2/RAR --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 99a17566ce..cdb9035695 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -825,6 +825,19 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + uint16_t *vrb_map = cc[CC_id].vrb_map; + int rbStart = 0, rbSize = 6; + for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) { + if (vrb_map[rbStart + i]) { + rbStart += i; + i = 0; + } + } + if (rbStart > (dci10_bw - rbSize)) { + LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + return; + } + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; // Checking if the DCI allocation is feasible in current subframe: we might // need to need up to two (PDCCH + PDSCH) messages, so check that we can @@ -924,8 +937,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = 0; - pdsch_pdu_rel15->rbSize = 6; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) { @@ -1025,9 +1038,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); /* mark the corresponding RBs as used */ - uint16_t *vrb_map = cc[CC_id].vrb_map; - for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) - vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1; + for (int rb = 0; rb < rbSize; rb++) + vrb_map[rb + rbStart] = 1; } } From 0d5f1dfea0014438ab7c09c1cd21588e79d8de56 Mon Sep 17 00:00:00 2001 From: guhan Date: Fri, 12 Feb 2021 19:49:42 +0530 Subject: [PATCH 23/43] Fixed the index issue --- openair2/LAYER2/NR_MAC_gNB/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 8f28424ddb..05ab77735c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -423,10 +423,10 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); for(int i=0; inum_active_ssb; i++) { for(int j=0; jssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ssb) { + if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { // one dedicated preamble for each beam ra->preambles.preamble_list[i] = - cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex; break; } } From 0b4335accc3f38f3fc37559ac86b1882f84cee4e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 8 Feb 2021 10:17:34 +0100 Subject: [PATCH 24/43] NSA: some work on security (for PDCP) - compute correct kgNB - propagate properly NR security capabilities of an UE (involves: rrc, s1ap, x2ap) --- openair2/COMMON/s1ap_messages_types.h | 8 ++++++++ openair2/COMMON/x2ap_messages_types.h | 2 +- openair2/RRC/LTE/rrc_defs.h | 10 ++++++++++ openair2/RRC/LTE/rrc_eNB.c | 9 +++++++++ openair2/RRC/LTE/rrc_eNB_S1AP.c | 9 +++++++++ openair2/UTIL/OSA/osa_defs.h | 2 ++ openair2/UTIL/OSA/osa_key_deriver.c | 24 ++++++++++++++++++++++++ openair3/S1AP/s1ap_eNB_handlers.c | 18 ++++++++++++++++-- 8 files changed, 79 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index f6b4f3c4e2..bd0788d2d0 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -155,6 +155,11 @@ typedef struct security_capabilities_s { uint16_t integrity_algorithms; } security_capabilities_t; +typedef struct nr_security_capabilities_s { + uint16_t encryption_algorithms; + uint16_t integrity_algorithms; +} nr_security_capabilities_t; + /* Provides the establishment cause for the RRC connection request as provided * by the upper layers. W.r.t. the cause value names: highPriorityAccess * concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for @@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s { uint8_t nb_of_e_rabs; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; + + /* NR Security algorithms (if any, set to 0 if not present) */ + nr_security_capabilities_t nr_security_capabilities; } s1ap_initial_context_setup_req_t; typedef struct tai_plmn_identity_s { diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 0c55764d6e..f4911c47dc 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { /* used for RRC->X2AP in source eNB */ int rnti; - security_capabilities_t security_capabilities; + nr_security_capabilities_t security_capabilities; /* SgNB Security Key */ uint8_t kgnb[32]; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 7602e9ca64..4f55f94121 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -546,6 +546,13 @@ typedef struct rrc_gummei_s { uint16_t mme_group_id; } rrc_gummei_t; +typedef struct { + uint16_t ciphering_algorithms; + uint16_t integrity_algorithms; + uint16_t sk_counter; + uint8_t kgNB[32]; +} lte_rrc_nr_security_t; + typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; LTE_SCellToAddMod_r10_t sCell_config[2]; @@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s { security_capabilities_t security_capabilities; + /* security capabilities and settings for an UE in ENDC mode */ + lte_rrc_nr_security_t nr_security; + int next_hop_chain_count; uint8_t next_security_key[SECURITY_KEY_LENGTH]; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 6d39fb2221..2d9d53a441 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4665,11 +4665,20 @@ rrc_eNB_process_MeasurementReport( msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ); memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t)); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; + + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms; + + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32); + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId; + //For the moment we have a single E-RAB which will be the one to be added to the gNB //Not sure how to select bearers to be added if there are multiple. X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 320004a361..d34b4164a2 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char } } + ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms; + ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms; + /* let's initialize sk_counter to 0 */ + ue_context_p->ue_context.nr_security.sk_counter = 0; + /* let's compute kgNB */ + derive_skgNB(ue_context_p->ue_context.kenb, + ue_context_p->ue_context.nr_security.sk_counter, + ue_context_p->ue_context.nr_security.kgNB); + // in case, send the S1SP initial context response if it is not sent with the attach complete message if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index 304dd07042..6334658683 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -53,6 +53,8 @@ typedef enum { //int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); +int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); + int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, const uint8_t key[32], uint8_t **out); int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index 71c7793fa0..159ee7f159 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) return 0; } */ + +int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) +{ + uint8_t *out; + uint8_t s[5]; + + /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ + s[0] = 0x1c; + + /* put sk_counter */ + s[1] = (sk_counter >> 8) & 0xff; + s[2] = sk_counter & 0xff; + + /* put length of sk_counter (2) */ + s[3] = 0x00; + s[4] = 0x02; + + kdf(s, 5, keNB, 32, &out, 32); + + memcpy(skgNB, out, 32); + free(out); + + return 0; +} diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 7c233d9e14..370d34868b 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ } else {/* ie != NULL */ return -1; } + /* id-SecurityKey : Copy the security key */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_SecurityKey, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else {/* ie != NULL */ return -1; } + /* id-NRUESecurityCapabilities */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false); + if (ie != NULL) { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms); + } else { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0; + } + + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + return 0; } From ef90d77b0e252bbce8b7fdda791f694116292f86 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 Feb 2021 20:53:36 +0100 Subject: [PATCH 25/43] Reformat nr_initiate_ra_proc() [no other changes] --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 178 ++++++++++-------- 1 file changed, 97 insertions(+), 81 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index cdb9035695..9439181044 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -484,99 +484,115 @@ void nr_initiate_ra_proc(module_id_t module_idP, num_ssb_per_RO -= 3; total_RApreambles = total_RApreambles/num_ssb_per_RO ; } - - for(int i=0; ira[i]; - if (ra->state == RA_IDLE) { - if((preamble_index < total_RApreambles) && (preamble_index > cc->cb_preambles_per_ssb) && (!ra->cfra)) continue; - - uint16_t ra_rnti; + if (ra->state == RA_IDLE) { + if ((preamble_index < total_RApreambles) && (preamble_index > cc->cb_preambles_per_ssb) && (!ra->cfra)) + continue; - // ra_rnti from 5.1.3 in 38.321 - // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) - ra_rnti=1+symbol+(9/*slotP*/*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); - else - ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); + uint16_t ra_rnti; - // This should be handled differently when we use the initialBWP for RA - ra->bwp_id=1; - NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + // ra_rnti from 5.1.3 in 38.321 + // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present + == NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) + ra_rnti = 1 + symbol + (9 /*slotP*/ * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); + else + ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + // This should be handled differently when we use the initialBWP for RA + ra->bwp_id = 1; + NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ->list.array[ra->bwp_id - 1]; - LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - uint8_t beam_index = ssb_index_from_prach(module_idP, - frameP, - slotP, - preamble_index, - freq_index, - symbol); + LOG_I(MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", + module_idP, + CC_id, + frameP, + slotP, + preamble_index); - // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries - if (ra->cfra) { - // if the preamble received correspond to one of the listed - if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { - LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", - module_idP, preamble_index); - continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc - } - } - int loop = 0; - LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); - ra->state = Msg2; - ra->timing_offset = timing_offset; - ra->preamble_slot = slotP; + uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - AssertFatal(commonSearchSpaceList->list.count>0, - "common SearchSpace list has 0 elements\n"); - // Common searchspace list - for (int i=0;ilist.count;i++) { - ss=commonSearchSpaceList->list.array[i]; - if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) - ra->ra_ss=ss; - } - - // retrieving ra pdcch monitoring period and offset - find_monitoring_periodicity_offset_common(ra->ra_ss, - &monitoring_slot_period, - &monitoring_offset); - - nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb); - - ra->Msg2_frame = msg2_frame; - ra->Msg2_slot = msg2_slot; - - LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - if (!ra->cfra) { - do { - ra->rnti = (taus() % 65518) + 1; - loop++; + // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries + if (ra->cfra) { + // if the preamble received correspond to one of the listed + if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { + LOG_E( + MAC, + "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", + module_idP, + preamble_index); + continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc + } } - while (loop != 100 && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519)); - if (loop == 100) { - LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); - abort(); + int loop = 0; + LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); + ra->state = Msg2; + ra->timing_offset = timing_offset; + ra->preamble_slot = slotP; + + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + // Common searchspace list + for (int i = 0; i < commonSearchSpaceList->list.count; i++) { + ss = commonSearchSpaceList->list.array[i]; + if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) + ra->ra_ss = ss; } + + // retrieving ra pdcch monitoring period and offset + find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + + nr_schedule_msg2(frameP, + slotP, + &msg2_frame, + &msg2_slot, + scc, + monitoring_slot_period, + monitoring_offset, + beam_index, + cc->num_active_ssb); + + ra->Msg2_frame = msg2_frame; + ra->Msg2_slot = msg2_slot; + + LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + if (!ra->cfra) { + do { + ra->rnti = (taus() % 65518) + 1; + loop++; + } while (loop != 100 + && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) + && ra->rnti >= 1 && ra->rnti <= 65519)); + if (loop == 100) { + LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } + } + ra->RA_rnti = ra_rnti; + ra->preamble_index = preamble_index; + ra->beam_id = beam_index; + + LOG_I(MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB " + "index %u\n", + module_idP, + CC_id, + frameP, + ra->Msg2_frame, + ra->Msg2_slot, + ra->RA_rnti, + cc->ssb_index[beam_index]); + + return; } - ra->RA_rnti = ra_rnti; - ra->preamble_index = preamble_index; - ra->beam_id = beam_index; - - LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n", - module_idP, - CC_id, - frameP, - ra->Msg2_frame, - ra->Msg2_slot, - ra->RA_rnti, - cc->ssb_index[beam_index]); - - return; - } } LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); From 10e021e96df3a60f671e43275460774b249995b8 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 10 Feb 2021 16:52:56 +0100 Subject: [PATCH 26/43] NSA: first draft of nea2 security for gNB The code is forced to use nea2, no matter what the UE supports. After 2^18 PDCP packets, it will fail to work (we don't use HFN yet). These limitations will be fixed in later commits. The existing security function was not reused, because it does too much memory allocation and initializes the security context at each ciphering. So here comes nr_pdcp_security_nea2_cipher(). And also the ciphering is done inplace. To be changed if necessary. --- cmake_targets/CMakeLists.txt | 1 + openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c | 31 ++++++++- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h | 28 +++++++- .../LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c | 15 +++++ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 40 ++++++++---- .../LAYER2/nr_pdcp/nr_pdcp_security_nea2.c | 65 +++++++++++++++++++ .../LAYER2/nr_pdcp/nr_pdcp_security_nea2.h | 33 ++++++++++ openair2/RRC/LTE/rrc_eNB.c | 4 +- openair2/RRC/NR/rrc_gNB.c | 5 +- openair2/RRC/NR/rrc_gNB_nsa.c | 37 +++++++++-- openair2/RRC/NR_UE/rrc_UE.c | 5 +- 11 files changed, 238 insertions(+), 26 deletions(-) create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 22e0e480eb..9c3945e571 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index f3d4b16130..ffc669a461 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -22,11 +22,12 @@ #include "nr_pdcp_entity.h" #include "nr_pdcp_entity_drb_am.h" +#include "nr_pdcp_security_nea2.h" #include "LOG/log.h" nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -38,7 +39,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb( } nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -47,7 +48,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_pdu_data, int sn_size, int t_reordering, - int discard_timer) + int discard_timer, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_drb_am_t *ret; @@ -76,5 +81,25 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1; + if (ciphering_key != NULL && ciphering_algorithm != 0) { + if (ciphering_algorithm != 2) { + LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n"); + exit(1); + } + ret->common.has_ciphering = 1; + ret->common.ciphering_algorithm = ciphering_algorithm; + memcpy(ret->common.ciphering_key, ciphering_key, 16); + + ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key); + ret->common.cipher = nr_pdcp_security_nea2_cipher; + ret->common.free_security = nr_pdcp_security_nea2_free_security; + } + ret->common.is_gnb = is_gnb; + + if (integrity_key != NULL) { + printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + return (nr_pdcp_entity_t *)ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index ce5dd300e9..58d79835ec 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -42,10 +42,28 @@ typedef struct nr_pdcp_entity_t { int tx_hfn; int next_nr_pdcp_tx_sn; int maximum_nr_pdcp_sn; + + /* security */ + int has_ciphering; + int has_integrity; + int ciphering_algorithm; + int integrity_algorithm; + unsigned char ciphering_key[16]; + unsigned char integrity_key[16]; + void *security_context; + void (*cipher)(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction); + void (*free_security)(void *security_context); + /* security algorithms need to know uplink/downlink information + * which is reverse for gnb and ue, so we need to know if this + * pdcp entity is for a gnb or an ue + */ + int is_gnb; } nr_pdcp_entity_t; nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -54,7 +72,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb( void *deliver_pdu_data); nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -63,7 +81,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_pdu_data, int sn_size, int t_reordering, - int discard_timer); + int discard_timer, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); void nr_DRB_preconfiguration(uint16_t crnti); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c index f2f849b9e3..62881c184e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c @@ -29,12 +29,21 @@ void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size) { nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + int sn; if (size < 3) abort(); if (!(buffer[0] & 0x80)) LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + sn = (((unsigned char)buffer[0] & 0x3) << 16) | + ((unsigned char)buffer[1] << 8) | + (unsigned char)buffer[2]; + + if (entity->common.has_ciphering) + entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3, + entity->rb_id, sn, entity->common.is_gnb ? 0 : 1); + entity->common.deliver_sdu(entity->common.deliver_sdu_data, (nr_pdcp_entity_t *)entity, buffer+3, size-3); } @@ -59,6 +68,10 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int buf[2] = sn & 0xff; memcpy(buf+3, buffer, size); + if (entity->common.has_ciphering) + entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size, + entity->rb_id, sn, entity->common.is_gnb ? 1 : 0); + entity->common.deliver_pdu(entity->common.deliver_pdu_data, (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id); } @@ -71,5 +84,7 @@ void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *ke void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity) { nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + if (entity->common.free_security != NULL) + entity->common.free_security(entity->common.security_context); free(entity); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 6195a91ea2..4c61596f17 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -591,7 +591,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s) TODO; } -static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) +static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -621,8 +625,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue, - sn_size_dl, t_reordering, discard_timer); + pdcp_drb = new_nr_pdcp_entity_drb_am(is_gnb, drb_id, + deliver_sdu_drb, ue, deliver_pdu_drb, ue, + sn_size_dl, t_reordering, discard_timer, + ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); @@ -630,16 +637,21 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config) +static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, + NR_RLC_Config_t *rlc_Config, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { switch (rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(rnti, s); + add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: - //add_drb_um(rnti, s); - /* hack */ - add_drb_am(rnti, s); + LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -657,7 +669,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -676,7 +689,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( //srb2add_list == NULL || //drb2add_list != NULL || drb2release_list != NULL || - security_modeP != 255 || + //security_modeP != 255 || //kRRCenc != NULL || //kRRCint != NULL || //kUPenc != NULL || @@ -693,7 +706,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req( if (drb2add_list != NULL) { for (i = 0; i < drb2add_list->list.count; i++) { - add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config); + add_drb(ctxt_pP->enb_flag, rnti, drb2add_list->list.array[i], + rlc_bearer2add_list->list.array[i]->rlc_Config, + security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, + kUPenc, kUPint); } } @@ -705,6 +721,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( free(kRRCenc); free(kRRCint); free(kUPenc); + free(kUPint); return 0; } @@ -805,6 +822,7 @@ void nr_DRB_preconfiguration(uint16_t crnti) NULL, NULL, NULL, + NULL, Rlc_Bearer_ToAdd_list); nr_rrc_rlc_config_asn1_req (&ctxt, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c new file mode 100644 index 0000000000..fc07f661dd --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c @@ -0,0 +1,65 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_security_nea2.h" + +#include +#include +#include +#include +#include + +void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key) +{ + void *ctx = calloc(1, nettle_aes128.context_size); + if (ctx == NULL) exit(1); + +#if NETTLE_VERSION_MAJOR < 3 + nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key); +#else + nettle_aes128.set_encrypt_key(ctx, ciphering_key); +#endif + + return ctx; +} + +void nr_pdcp_security_nea2_cipher(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction) +{ + unsigned char t[16]; + + t[0] = (count >> 24) & 255; + t[1] = (count >> 16) & 255; + t[2] = (count >> 8) & 255; + t[3] = (count ) & 255; + t[4] = ((bearer-1) << 3) | (direction << 2); + memset(&t[5], 0, 16-5); + + nettle_ctr_crypt(security_context, nettle_aes128.encrypt, + nettle_aes128.block_size, t, + length, buffer, buffer); +} + +void nr_pdcp_security_nea2_free_security(void *security_context) +{ + free(security_context); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h new file mode 100644 index 0000000000..c3667c93d4 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_SECURITY_NEA2_H_ +#define _NR_PDCP_SECURITY_NEA2_H_ + +void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key); + +void nr_pdcp_security_nea2_cipher(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction); + +void nr_pdcp_security_nea2_free_security(void *security_context); + +#endif /* _NR_PDCP_SECURITY_NEA2_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 2d9d53a441..b9d2cd4528 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4484,10 +4484,10 @@ static int encode_CG_ConfigInfo( rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig )); rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig)); - rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea2; rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL; rb_config->securityConfig->keyToUse = calloc(1,sizeof(long)); - *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_secondary; } cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo)); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index abf85a805b..6d430d7223 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -887,6 +888,7 @@ rrc_gNB_process_RRCReconfigurationComplete( kUPenc, NULL, NULL, + NULL, NULL); /* Refresh SRBs/DRBs */ nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -1702,6 +1704,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, // NULL, // NULL, // NULL, + // NULL, // NULL); // if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index a390d05a08..27380aa107 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -39,6 +39,7 @@ #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" #include "executables/softmodem-common.h" #include +#include "UTIL/OSA/osa_defs.h" extern boolean_t nr_rrc_pdcp_config_asn1_req( const protocol_ctxt_t *const ctxt_pP, @@ -48,7 +49,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -280,15 +282,40 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ctxt.eNB_index); } + /* store security key and security capabilities*/ + memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32); + ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; + ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; + + /* select ciphering algorithm based on gNB configuration file and + * UE's supported algorithms + */ + /* hardcode ciphering to nea2 of the moment */ + ue_context_p->ue_context.ciphering_algorithm = 2; //NR_CipheringAlgorithm_nea2; + /* integrity: no integrity protection */ + ue_context_p->ue_context.integrity_algorithm = 0; + + /* derive UP security key */ + unsigned char *kUPenc_kdf, *kUPenc; + nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kUPenc_kdf); + /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ + kUPenc = malloc(16); + if (kUPenc == NULL) exit(1); + memcpy(kUPenc, kUPenc_kdf+16, 16); + free(kUPenc_kdf); + nr_rrc_pdcp_config_asn1_req( &ctxt, (NR_SRB_ToAddModList_t *) NULL, ue_context_p->ue_context.rb_config->drb_ToAddModList , ue_context_p->ue_context.rb_config->drb_ToReleaseList, - 0xff, - NULL, - NULL, - NULL, + (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, + NULL, /* kRRCenc - unused */ + NULL, /* kRRCint - unused */ + kUPenc, /* kUPenc */ + NULL, /* kUPint - unused */ NULL, NULL, ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index b6c0ae4b45..460dbf1d22 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -186,7 +186,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -2085,6 +2086,7 @@ nr_sa_rrc_ue_process_radioBearerConfig( // NULL, // NULL, // NULL, + // NULL, // NULL); // Refresh SRBs // nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -2176,6 +2178,7 @@ nr_sa_rrc_ue_process_radioBearerConfig( // NULL, // kUPenc, // NULL, + // NULL, // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, // NULL); // Refresh DRBs From cb589c211c9042ad73b485c78f3381155932b210 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 12 Feb 2021 15:49:11 +0100 Subject: [PATCH 27/43] minor trivial bugfix --- openair2/RRC/NR/rrc_gNB_nsa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 27380aa107..7539afc1ae 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -117,11 +117,11 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL // dump ue_capabilities - if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr); } - if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } From 73f3a458cfcff2b9474e058038a3a9c2c7e1617a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 12 Feb 2021 15:53:40 +0100 Subject: [PATCH 28/43] NSA: finalize nea2 security for gNB - a new section in the configuration file to select security algorithms, with new code to deal with it - cleanup CG-ConfigInfo: specs seem to indicate that we must not add mcg_RB_Config; the gNB has to deal with that - as a consequence, modify fill_default_rbconfig() that is called in every cases and needs security and bearer parameters The new section in the configuration file looks like: security = { # preferred ciphering algorithms # the first one of the list that an UE supports in chosen # valid values: nea0, nea1, nea2, nea3 ciphering_algorithms = ( "nea0", "nea2" ); # preferred integrity algorithms # the first one of the list that an UE supports in chosen # valid values: nia0, nia1, nia2, nia3 integrity_algorithms = ( "nia0" ); }; --- openair2/GNB_APP/gnb_config.c | 97 +++++++++++++- openair2/GNB_APP/gnb_paramdef.h | 23 ++++ openair2/RRC/LTE/rrc_eNB.c | 67 ---------- openair2/RRC/NR/nr_rrc_defs.h | 11 ++ openair2/RRC/NR/nr_rrc_proto.h | 6 +- openair2/RRC/NR/rrc_gNB_nsa.c | 126 ++++++++++++------ openair2/RRC/NR/rrc_gNB_reconfig.c | 15 ++- .../GENERIC-LTE-EPC/CONF/testing_gnb.conf | 12 ++ 8 files changed, 242 insertions(+), 115 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 0c056d27b6..ff4c6cfaea 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -513,6 +513,101 @@ void RCconfig_nr_macrlc() { } +void config_security(gNB_RRC_INST *rrc) +{ + paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC; + int ret = config_get(logparams_defaults, + sizeof(logparams_defaults) / sizeof(paramdef_t), + CONFIG_STRING_SECURITY); + int i; + + if (ret < 0) { + LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n"); + rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */ + rrc->security.ciphering_algorithms_count = 1; + rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */ + rrc->security.integrity_algorithms_count = 1; + return; + } + + if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) { + LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n"); + exit(1); + } + if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) { + LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n"); + exit(1); + } + + /* get ciphering algorithms */ + rrc->security.ciphering_algorithms_count = 0; + for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) { + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3; + rrc->security.ciphering_algorithms_count++; + continue; + } + LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n", + logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]); + exit(1); + } + + /* get integrity algorithms */ + rrc->security.integrity_algorithms_count = 0; + for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) { + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3; + rrc->security.integrity_algorithms_count++; + continue; + } + LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n", + logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]); + exit(1); + } + + if (rrc->security.ciphering_algorithms_count == 0) { + LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n"); + rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */ + rrc->security.ciphering_algorithms_count = 1; + } + + if (rrc->security.integrity_algorithms_count == 0) { + LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n"); + rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */ + rrc->security.integrity_algorithms_count = 1; + } +} + void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { int num_gnbs = 0; @@ -679,7 +774,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { }//End for (k=0; k 0) - + config_security(rrc); }//End RCconfig_NRRRC function int RCconfig_nr_gtpu(void ) { diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index f1fe0c97c9..403602c109 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -452,4 +452,27 @@ typedef enum { #define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n" #define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n" /*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* security configuration */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CONFIG_STRING_SECURITY "security" + +#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms" +#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* security configuration */ +/* optname help paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define SECURITY_GLOBALPARAMS_DESC { \ + {SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \ + {SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \ +} + +#define SECURITY_CONFIG_CIPHERING_IDX 0 +#define SECURITY_CONFIG_INTEGRITY_IDX 1 +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + #endif diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index b9d2cd4528..526ce129b1 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo( struct NR_RadioBearerConfig *rb_config = NULL; asn_enc_rval_t enc_rval; int RRC_OK = 1; - int index = 0; char temp_buff[ASN_MAX_ENCODE_SIZE]; NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL; int RAT_Container_count = 0; - rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig)); - AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config"); - - if(ue_context_pP->ue_context.DRB_configList->list.count != 0) { - rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList )); - AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist"); - rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED; - rb_config->drb_ToAddModList->list.array - = calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *)); - AssertFatal( rb_config->drb_ToAddModList->list.array != NULL, - "falied to allocate memory for list.array"); - - for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) { - rb_config->drb_ToAddModList->list.array[index] - = calloc(1,sizeof(struct NR_DRB_ToAddMod)); - AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL, - "failed to allocate memory for drb_toaddmod"); - rb_config->drb_ToAddModList->list.array[index]->drb_Identity - = ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity; - - if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) { - rb_config->drb_ToAddModList->list.array[index]->cnAssociation - = calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation)); - AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL, - "failed to allocate memory cnAssociation"); - rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present - = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity - = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity); - } - - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config)); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb)); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer - = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL - = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL - = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present - = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering - = NR_PDCP_Config__t_Reordering_ms0; - } - - rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig )); - rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig)); - rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea2; - rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL; - rb_config->securityConfig->keyToUse = calloc(1,sizeof(long)); - *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_secondary; - } cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo)); AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo"); @@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo( (const char *)temp_buff, (enc_rval.encoded+7)>>3); } - cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config - = calloc(1,sizeof(OCTET_STRING_t)); - AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo-> - mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config"); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,temp_buff,ASN_MAX_ENCODE_SIZE); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config, - (const char *)temp_buff, (enc_rval.encoded+7)>>3); // this xer_fprint can be enabled for additional debugging messages // xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index c53d44983c..36d9bdee60 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -447,6 +447,15 @@ typedef struct { //--------------------------------------------------- +typedef struct { + /* nea0 = 0, nea1 = 1, ... */ + int ciphering_algorithms[4]; + int ciphering_algorithms_count; + + /* nia0 = 0, nia1 = 1, ... */ + int integrity_algorithms[4]; + int integrity_algorithms_count; +} nr_security_configuration_t; //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -479,6 +488,8 @@ typedef struct gNB_RRC_INST_s { int srb1_timer_status_prohibit; int srs_enable[MAX_NUM_CCs]; + // security configuration (preferred algorithms) + nr_security_configuration_t security; } gNB_RRC_INST; #include "nr_rrc_proto.h" //should be put here otherwise compilation error diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 9b7d734e2c..6d876a0eef 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -39,6 +39,7 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" #include "NR_CG-ConfigInfo.h" +#include "NR_SecurityConfig.h" int rrc_init_nr_global_param(void); @@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon int n_physical_antenna_ports, int initial_csi_index); -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig); +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, + int eps_bearer_id, int rb_id, + e_NR_CipheringAlgorithm ciphering_algorithm, + e_NR_SecurityConfig__keyToUse key_to_use); int generate_CG_Config(gNB_RRC_INST *rrc, NR_CG_Config_t *cg_Config, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 7539afc1ae..5ea02c7832 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -125,20 +125,6 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } - if(cg_config_info && cg_config_info->mcg_RB_Config) { - asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_NR_RadioBearerConfig, - (void **)&ue_context_p->ue_context.rb_config, - cg_config_info->mcg_RB_Config->buf, - cg_config_info->mcg_RB_Config->size, 0, 0); - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n", - dec_rval.consumed, cg_config_info->mcg_RB_Config->size); - } - } - - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config); rrc_add_nsa_user(rrc,ue_context_p, m); } @@ -154,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; protocol_ctxt_t ctxt={0}; + unsigned char *kUPenc = NULL; + int i; // NR RRCReconfiguration AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n"); ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t)); @@ -164,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; carrier->initial_csi_index[rrc->Nb_ue] = 0; + ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ - ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); - fill_default_rbconfig(ue_context_p->ue_context.rb_config); + fill_default_rbconfig(ue_context_p->ue_context.rb_config, + 5 /* EPS bearer ID */, + 1 /* drb ID */, + NR_CipheringAlgorithm_nea0, + NR_SecurityConfig__keyToUse_master); + } else { + /* TODO: handle more than one bearer */ + if (m == NULL) { + LOG_E(RRC, "fatal: m==NULL\n"); + exit(1); + } + if (m->nb_e_rabs_tobeadded != 1) { + LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded); + exit(1); + } + + /* store security key and security capabilities */ + memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32); + ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; + ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; + + /* Select ciphering algorithm based on gNB configuration file and + * UE's supported algorithms. + * We take the first from the list that is supported by the UE. + * The ordering of the list comes from the configuration file. + */ + /* preset nea0 as fallback */ + ue_context_p->ue_context.ciphering_algorithm = 0; + for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) { + int nea_mask[4] = { + 0, + 0x8000, /* nea1 */ + 0x4000, /* nea2 */ + 0x2000 /* nea3 */ + }; + if (rrc->security.ciphering_algorithms[i] == 0) { + /* nea0 already preselected */ + break; + } + if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) { + ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i]; + break; + } + } + + LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm); + + /* integrity: no integrity protection for DRB in ENDC mode + * as written in 38.331: "If UE is connected to E-UTRA/EPC, this field + * indicates the integrity protection algorithm to be used for SRBs + * configured with NR PDCP, as specified in TS 33.501" + * So nothing for DRB. Plus a test with a COTS UE revealed that it + * did not apply integrity on the DRB. + */ + ue_context_p->ue_context.integrity_algorithm = 0; + + LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm); + + /* derive UP security key */ + unsigned char *kUPenc_kdf; + nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kUPenc_kdf); + /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ + kUPenc = malloc(16); + if (kUPenc == NULL) exit(1); + memcpy(kUPenc, kUPenc_kdf+16, 16); + free(kUPenc_kdf); + + e_NR_CipheringAlgorithm cipher_algo; + switch (ue_context_p->ue_context.ciphering_algorithm) { + case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break; + case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break; + case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break; + case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break; + default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); + } + + fill_default_rbconfig(ue_context_p->ue_context.rb_config, + m->e_rabs_tobeadded[0].e_rab_id, + m->e_rabs_tobeadded[0].drb_ID, + cipher_algo, + NR_SecurityConfig__keyToUse_secondary); } fill_default_reconfig(carrier->servingcellconfigcommon, reconfig_ies, @@ -282,30 +352,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ctxt.eNB_index); } - /* store security key and security capabilities*/ - memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32); - ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; - ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; - - /* select ciphering algorithm based on gNB configuration file and - * UE's supported algorithms - */ - /* hardcode ciphering to nea2 of the moment */ - ue_context_p->ue_context.ciphering_algorithm = 2; //NR_CipheringAlgorithm_nea2; - /* integrity: no integrity protection */ - ue_context_p->ue_context.integrity_algorithm = 0; - - /* derive UP security key */ - unsigned char *kUPenc_kdf, *kUPenc; - nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, - ue_context_p->ue_context.kgnb, - &kUPenc_kdf); - /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ - kUPenc = malloc(16); - if (kUPenc == NULL) exit(1); - memcpy(kUPenc, kUPenc_kdf+16, 16); - free(kUPenc_kdf); - nr_rrc_pdcp_config_asn1_req( &ctxt, (NR_SRB_ToAddModList_t *) NULL, diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index aebdc2f1cc..ab3f192276 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -1329,7 +1329,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon reconfig->nonCriticalExtension = NULL; } -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, + int eps_bearer_id, int rb_id, + e_NR_CipheringAlgorithm ciphering_algorithm, + e_NR_SecurityConfig__keyToUse key_to_use) { rbconfig->srb_ToAddModList = NULL; rbconfig->srb3_ToRelease = NULL; @@ -1337,8 +1340,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; - drb_ToAddMod->drb_Identity = 1; + drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id; + drb_ToAddMod->drb_Identity = rb_id; drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); @@ -1367,12 +1370,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); - rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm; rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); - *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + *rbconfig->securityConfig->keyToUse = key_to_use; - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); +// xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); } /* Function to set or overwrite PTRS DL RRC parameters */ void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 555af5835d..c46ea98ec2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -278,6 +278,18 @@ THREAD_STRUCT = ( } ); +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0", "nea2" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia0" ); +}; + log_config : { global_log_level ="info"; From 67b9cd1892e81ff02d103e9cc3b6331d2ffa11a4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 13 Feb 2021 08:55:20 +0100 Subject: [PATCH 29/43] hack: fix NR dlsim compilation Dirty... --- openair1/SIMULATION/NR_PHY/dlsim.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9581038283..c0b7e7fa73 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -151,6 +151,12 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc From 778e487323811cc5436a734b1e0171cd28c5cb0f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 13 Feb 2021 09:06:55 +0100 Subject: [PATCH 30/43] hack: fix NR ulsim compilation Dirty. --- openair1/SIMULATION/NR_PHY/ulsim.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index fd2e1dc0b7..48046c55bc 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -158,6 +158,12 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + // needed for some functions uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; From 3cfa2c266b4513193b629dde5e73e6de95a60f69 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 13 Feb 2021 09:33:55 +0100 Subject: [PATCH 31/43] hack: fix NR prachsim compilation Dirty! --- openair1/SIMULATION/NR_PHY/prachsim.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 941a06128f..3d41e244f9 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -137,6 +137,12 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + int main(int argc, char **argv){ char c; From 21ff70e84ffe41220b274ec756e54d33c05ea281 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 13 Feb 2021 16:14:54 +0100 Subject: [PATCH 32/43] hack: put back a hack that seems necessary for NR rfsim tests in the CI go figure... --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 4c61596f17..f14d25b145 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -650,8 +650,10 @@ static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: - LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); + //add_drb_um(rnti, s); + /* hack */ + add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", From a3b1216b233fdb1406bceb1d2e3c5b4c56ceb11c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Feb 2021 14:13:26 +0100 Subject: [PATCH 33/43] Fixup sched_ul_bytes logic 1) Only count new transmission as scheduled bytes (which is then compared against the BSR) 2) When subtracting scheduled bytes after successful reception, subtract TBsize from correct HARQ process --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 90a1811b22..0b1c86177a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -432,7 +432,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (sduP != NULL){ LOG_D(MAC, "Received PDU at MAC gNB \n"); - UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; @@ -442,7 +443,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; /* reduce sched_ul_bytes when cur_harq->round == 3 */ if (cur_harq->round == 3){ - UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; } @@ -916,6 +918,7 @@ void nr_schedule_ulsch(module_id_t module_id, /* Save information on MCS, TBS etc for the current initial transmission * so we have access to it when retransmitting */ cur_harq->sched_pusch = *sched_pusch; + sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; } else { LOG_D(MAC, "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", @@ -929,7 +932,6 @@ void nr_schedule_ulsch(module_id_t module_id, cur_harq->ndi); } UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; - sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; LOG_D(MAC, "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", From 80cac226fc054858f3e60e71bfd3d568e1c3b19e Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 18 Feb 2021 08:50:45 +0100 Subject: [PATCH 34/43] fixed a warning in gNB_scheduler_ulsch.c --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 90a1811b22..47034cdb99 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -862,7 +862,7 @@ void nr_schedule_ulsch(module_id_t module_id, /* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each * allocated PDCCH so we can easily allocate UE's DCIs independent of any * CORESET order */ - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {0}; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {{0}}; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; From 11a318170ebb20b7aef6c681201636e0ba1beb45 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Thu, 18 Feb 2021 22:23:31 +0100 Subject: [PATCH 35/43] memory wrong free in global vars used for configuration storage --- common/config/config_load_configmodule.c | 3 ++- common/config/config_load_configmodule.h | 3 +++ common/config/config_userapi.c | 5 ++++- common/config/libconfig/config_libconfig.c | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 61a3984347..9b76fbb2a9 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -331,9 +331,10 @@ void end_configmodule(void) { printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); for(int i=0; inumptrs ; i++) { - if (cfgptr->ptrs[i] != NULL) { + if (cfgptr->ptrs[i] != NULL && cfgptr->ptrsAllocated[i] == true) { free(cfgptr->ptrs[i]); cfgptr->ptrs[i]=NULL; + cfgptr->ptrsAllocated[i] = false; } } diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index d0309c62c3..8baaa99bb8 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -36,6 +36,8 @@ #include #include +#include +#include #include "common/config/config_paramdesc.h" #include "common/utils/T/T.h" #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O :P1:P2... @@ -74,6 +76,7 @@ typedef struct configmodule_interface { uint32_t numptrs; uint32_t rtflags; char *ptrs[CONFIG_MAX_ALLOCATEDPTRS]; + bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS]; } configmodule_interface_t; #ifdef CONFIG_LOADCONFIG_MAIN diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 33d6408828..af70cae71e 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -62,6 +62,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr; + config_get_if()->ptrsAllocated[config_get_if()->numptrs] = true; config_get_if()->numptrs++; } } else { @@ -82,7 +83,9 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { } if (*ptr == NULL) { - *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch + *ptr = malloc(length>40?length:40); + // LTS: dummy fix, waiting Francois full fix in 4G branch + // the issue is we don't know at this point the size we will get if ( *ptr != NULL) { memset(*ptr,0,length); diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index 2e9fd614c5..eb08a70183 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -346,6 +346,7 @@ int config_libconfig_init(char *cfgP[], int numP) { libconfig_privdata.configfile = strdup((char *)cfgP[0]); config_get_if()->numptrs=0; memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS); + memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated)); /* Read the file. If there is an error, report it and exit. */ if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) { From abea2ef92690c6981603ec528e01750e2db38240 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Thu, 18 Feb 2021 22:36:45 +0100 Subject: [PATCH 36/43] protect nrscope when thread starts before end of init --- openair1/PHY/TOOLS/nr_phy_scope.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index f6cb93ed03..cb61523852 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -225,6 +225,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye } static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { + if ( values == NULL ) + return; fl_winset(FL_ObjWin(graph->graph)); const int samplesPerPixel=datasize/graph->w; int displayPart=graph->waterFallh-ScaleZone; From e893ee8a1678a525b0fe869a27c37b9e0fc2f6bd Mon Sep 17 00:00:00 2001 From: guhan Date: Fri, 19 Feb 2021 11:47:55 +0530 Subject: [PATCH 37/43] Fixed the issue w.r.t looping of configured preamble list --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9439181044..ac3a4e77d2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -477,6 +477,8 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t total_RApreambles = 64; uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + int pr_found; + if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; @@ -487,10 +489,19 @@ void nr_initiate_ra_proc(module_id_t module_idP, for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &cc->ra[i]; - + pr_found = 0; if (ra->state == RA_IDLE) { - if ((preamble_index < total_RApreambles) && (preamble_index > cc->cb_preambles_per_ssb) && (!ra->cfra)) - continue; + for(int j = 0; j < ra->preambles.num_preambles; j++) { + //check if the preamble received correspond to one of the listed or configured preambles + if (preamble_index == ra->preambles.preamble_list[j]) { + pr_found=1; + break; + } + } + + if (pr_found == 0) { + continue; + } uint16_t ra_rnti; From c910668e7baaa9c795e28db3e5769f98dd36a268 Mon Sep 17 00:00:00 2001 From: laurent Date: Fri, 19 Feb 2021 10:48:35 +0100 Subject: [PATCH 38/43] add LOG_M() binary format --- common/utils/LOG/log.c | 33 ++++++++++++++++++++++++++++++++- common/utils/LOG/log.h | 20 +++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 2340c78bf1..9fd67a6dbb 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -88,16 +88,19 @@ int write_file_matlab(const char *fname, void *data, int length, int dec, - char format) + unsigned int format) { FILE *fp=NULL; int i; + AssertFatal((format&~MATLAB_RAW) <16,""); + if (data == NULL) return -1; //printf("Writing %d elements of type %d to %s\n",length,format,fname); + if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) { fp = fopen(fname,"a+"); } else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) { @@ -109,6 +112,32 @@ int write_file_matlab(const char *fname, return(-1); } + if ( (format&MATLAB_RAW) == MATLAB_RAW ) { + int sz[16]={sizeof(short), 2*sizeof(short), + sizeof(int), 2*sizeof(int), + sizeof(char), 2*sizeof(char), + sizeof(long long), + sizeof(double), 2*sizeof(double), + sizeof(unsigned char), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short) + }; + int eltSz= sz[format&~MATLAB_RAW]; + if (dec==1) + fwrite(data, eltSz, length, fp); + else + for (i=0; i Date: Fri, 19 Feb 2021 11:47:25 +0100 Subject: [PATCH 39/43] reducing UL target power for Benetel 5G RRU and adding missing parameter for PUSCH multi thread processing --- .../PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 940d619a51..504d5e7b34 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -104,9 +104,9 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 74; zeroCorrelationZoneConfig = 13; - #preambleReceivedTargetPower = -118; + preambleReceivedTargetPower = -118; #preambleReceivedTargetPower = -104; - preambleReceivedTargetPower = -108; + #preambleReceivedTargetPower = -108; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -153,7 +153,7 @@ gNBs = msg3_DeltaPreamble = 1; #p0_NominalWithGrant =-90; - p0_NominalWithGrant =-108; + p0_NominalWithGrant =-118; # pucch-ConfigCommon setup : # pucchGroupHopping @@ -161,7 +161,7 @@ gNBs = pucchGroupHopping = 0; hoppingId = 40; #p0_nominal = -90; - p0_nominal = -108; + p0_nominal = -118; # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; @@ -234,9 +234,9 @@ gNBs = { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.187/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.187/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -256,6 +256,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); From a51e3defa834bd34781555a83b1dd5085ab49fa1 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 19 Feb 2021 11:01:03 +0100 Subject: [PATCH 40/43] when PRACH config 4 is used (Benetel RRU) we only schedule UL slots 8 and 9 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index d5dbbe5ddf..cf361f9342 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -370,7 +370,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, #define BIT(x) (1 << (x)) const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16); - const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18); + + uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint64_t ulsch_in_slot_bitmap; + if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config. + ulsch_in_slot_bitmap = BIT( 8) | BIT( 9); + else + ulsch_in_slot_bitmap = BIT( 8) | BIT(18); memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 From 2651cd0cd3697f63919143b33061501cda21386f Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 19 Feb 2021 11:16:29 +0100 Subject: [PATCH 41/43] removing dead code --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 4 ---- openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index d2baa40451..713e71674b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -67,10 +67,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; -#if 0 -printf("nr_pusch_channel_estimation rxdataF %p\n", &rxdataF[0][0]); -#endif - nushift = (p>>1)&1; gNB->frame_parms.nushift = nushift; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 25c9fee832..7e6becb4a8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -250,10 +250,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, uint8_t is_dmrs_re; start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; -#if 0 -printf("frame_parms->first_carrier_offset in nr_ulsch_extract_rbs_single %d\n", frame_parms->first_carrier_offset); -printf("rxdataF in nr_ulsch_extract_rbs_single %p\n", &rxdataF[0][0]); -#endif nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; #ifdef __AVX2__ int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); From 37a2ce7d3da0e5f5c2df31a48a48b43c4931af8b Mon Sep 17 00:00:00 2001 From: Saankhya Date: Sat, 20 Feb 2021 14:55:10 +0530 Subject: [PATCH 42/43] following coding guideline fixing the RE offset for each Rx antenna in pusch channel estimation --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..38b35dcf6d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -158,6 +158,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + re_offset = k; /* Initializing the Resource element offset for each Rx antenna */ + pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; From fdc818bc0684025f269a8aa65262e47c1f49aaa9 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 2 Mar 2021 21:39:19 +0100 Subject: [PATCH 43/43] Update TESTING_GNB_W_COTS_UE.md --- doc/TESTING_GNB_W_COTS_UE.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 610cc5bdd4..73ae18351f 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -30,8 +30,6 @@ http://www.saelig.com/MFR00066/ste2300.htm ## Configuration Overview * Non Standalone (NSA) configuration : initial Control Plane established between UE and RAN eNB, then User Plane established between UE and gNB, Core network is 4G based supporting rel 15 - -* Commercial UE: Oppo Reno 5G * OAI Software Defined gNB and eNB * eNB RF front end: USRP (ETTUS) B200 Mini or B210 * gNB RF front end: USRP (ETTUS) B200 Mini or B210 (N310 will be needed for MIMO and wider BW's) @@ -40,6 +38,17 @@ http://www.saelig.com/MFR00066/ste2300.htm * BW: 40MHz * Antenna scheme: SISO +## COTS UEs + +Our code might not work with all 5G phones yet, but we are constantly improving it. Here is a list of COTS UEs that we know that work with OAI. + +* Oppo Reno 5G +* Samsung A90 5G +* Google Pixel 5G +* Simcom SIMCOM8200EA +* Quectel RM500Q-GL + + ## Repository https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop