diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index 1c67266f0c9b89776a73aae111a592aa3c87ce95..1bca25027f9d57e60ebf99935977c6aa3addf433 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -58,7 +58,7 @@ <class>Pull_Local_Registry</class> <desc>Pull Images from Local Registry</desc> <test_svr_id>0</test_svr_id> - <images_to_pull>oai-gnb-asan oai-nr-ue-asan</images_to_pull> + <images_to_pull>oai-gnb-asan oai-nr-ue</images_to_pull> </testCase> <testCase id="000000"> diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index 6a2f31aac2001bd055230f81696dc234a9810ddd..220b646f2508140ab2359f8abcb48e007636a3f4 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -185,8 +185,8 @@ <testCase id="070000"> <class>Iperf</class> - <desc>iperf (DL/90Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 90M -t 60 -i 1 -fm</iperf_args> + <desc>iperf (DL/70Mbps/UDP)(60 sec)(single-ue profile)</desc> + <iperf_args>-u -b 70M -t 60 -i 1 -fm</iperf_args> <direction>DL</direction> <id>idefix</id> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml index d603b3f1eab9ec73de5e0c55d8f1904ecf970870..c826d93ce6c4c3c0c9370190facfdf7dbfb400e9 100644 --- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -129,8 +129,8 @@ <testCase id="270000"> <class>Iperf</class> - <desc>iperf (DL/100Mbps/UDP)(30 sec)(single-ue profile)</desc> - <iperf_args>-u -b 100M -t 30 -i 1 -fm</iperf_args> + <desc>iperf (DL/80Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 80M -t 30 -i 1 -fm</iperf_args> <direction>DL</direction> <id>idefix</id> <iperf_packetloss_threshold>5</iperf_packetloss_threshold> diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index 93d9011f8328d0d4d7fc7cf61f6acba06232eefe..8d62746300a4e47901d039175129e932d8426218 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -167,7 +167,7 @@ services: privileged: true container_name: rfsim5g-oai-cu environment: - USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-ext-dn diff --git a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml index 7b4a0fcc967a0b2fa1bb1d9848776b4304894b2f..4eaa9428243296db8d077021492882eac6763432 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml @@ -169,7 +169,7 @@ services: privileged: true container_name: rfsim5g-oai-cucp environment: - USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-ext-dn @@ -191,7 +191,7 @@ services: privileged: true container_name: rfsim5g-oai-cuup environment: - USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-cucp diff --git a/docker/Dockerfile.nr-cuup.ubuntu20 b/docker/Dockerfile.nr-cuup.ubuntu20 index 9cd795ac1f81611a234329d3f43b1b8d5de0e426..0ed9d2cb1377b3d26ce474605f2239395ef7255a 100644 --- a/docker/Dockerfile.nr-cuup.ubuntu20 +++ b/docker/Dockerfile.nr-cuup.ubuntu20 @@ -44,6 +44,8 @@ RUN apt-get update && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ libasan5 \ + iproute2 \ + net-tools \ libubsan1 \ liblapacke; fi' && \ rm -rf /var/lib/apt/lists/* diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 1c3fb5ee842123c7dc5a1495f14647e338cc21b5..2b94c7d827b2029f2c4d5fa2f696ca31d89f838c 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -896,35 +896,43 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { else //FDD cfg->duplex_mode = duplex_mode_FDD; + cfg->configFilename = rf_config_file; + cfg->Mod_id = 0; cfg->num_rb_dl=N_RB; cfg->tx_num_channels=ru->nb_tx; cfg->rx_num_channels=ru->nb_rx; LOG_I(PHY,"Setting RF config for N_RB %d, NB_RX %d, NB_TX %d\n",cfg->num_rb_dl,cfg->rx_num_channels,cfg->tx_num_channels); + LOG_I(PHY,"tune_offset %.0f Hz, sample_rate %.0f Hz\n",cfg->tune_offset,cfg->sample_rate); for (i=0; i<ru->nb_tx; i++) { if (ru->if_frequency == 0) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; - cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; } else if (ru->if_freq_offset) { cfg->tx_freq[i] = (double)(ru->if_frequency); - cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset); - LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); + LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF TX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); } else { cfg->tx_freq[i] = (double)ru->if_frequency; - cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); } cfg->tx_gain[i] = ru->att_tx; + LOG_I(PHY, "Channel %d: setting tx_gain offset %.0f, tx_freq %.0f Hz\n", + i, cfg->tx_gain[i],cfg->tx_freq[i]); + } + + for (i=0; i<ru->nb_rx; i++) { + if (ru->if_frequency == 0) { + cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; + } else if (ru->if_freq_offset) { + cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset); + LOG_I(PHY, "Setting IF RX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); + } else { + cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); + } + cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; - cfg->configFilename = rf_config_file; - LOG_I(PHY, "Channel %d: setting tx_gain offset %.0f, rx_gain offset %.0f, tx_freq %.0f Hz, rx_freq %.0f Hz, tune_offset %.0f Hz, sample_rate %.0f Hz\n", - i, cfg->tx_gain[i], - cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i], - cfg->tune_offset, - cfg->sample_rate); + LOG_I(PHY, "Channel %d: setting rx_gain offset %.0f, rx_freq %.0f Hz\n", + i,cfg->rx_gain[i],cfg->rx_freq[i]); } } diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 3dc6e930b790a72d8b8ce53d5cf9a2f49c176595..67dd5d19b7efb2c4b30d09d77d80ba6a7edb232d 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -662,7 +662,8 @@ typedef struct typedef struct { uint8_t prach_sequence_length;//RACH sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence - uint8_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4 + uint8_t prach_sub_c_spacing; // Subcarrier spacing of PRACH. [38.211 sec 4.2] Value: 0: 15 kHz 1: 30 kHz 2: 60 kHz 3: 120 kHz + // 4: 1.25 kHz 5: 5 kHz uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B uint8_t num_prach_fd_occasions;//Corresponds to the parameter 饾憖 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8 fapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list; diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 3d338fb114150f509c1993fee81d51777f1a209e..92a1d94fd4ab2c8f7bc25e3450dc3a845ba6a8e2 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -23,6 +23,8 @@ #include "PHY/NR_REFSIG/nr_mod_table.h" #include "executables/softmodem-common.h" +// #define DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // TODO: For debug, to be removed if want to merge to develop + //Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j const char nr_W_1l_2p[6][2][1] = { {{'1'}, {'0'}}, // pmi 0 @@ -711,3 +713,97 @@ c16_t nr_layer_precoder_cm(int n_layers, return precodatatx_F; } +void nr_layer_precoder_simd(const int n_layers, + const int n_symbols, + const int symSz, + const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz], + const c16_t prec_matrix[n_layers], + const int symbol, + const int sc_offset, + const int re_cnt, + c16_t *txdataF_precoded) +{ + uint32_t sc = sc_offset; + + // For x86, use 256 SIMD for every 8 RE and 128 SIMD for last 4 RE + // For aarch64, use 128 SIMD for every 4 RE + + // 256 SIMD: Do 8 RE in one iteration, 3 iterations for 2 RB + #ifdef __AVX2__ + const uint32_t re_cnt_align8 = re_cnt & ~7; + for(; sc<sc_offset+(re_cnt_align8); sc+=sizeof(simde__m256i)/sizeof(*prec_matrix)){ + // Matrix multiplication for 4 elements of the result (sizeof(simde__m256i) / sizeof(*prec_matrix) = 8) + simde__m256i y = simde_mm256_set1_epi16(0); // Y = W[0]*X[0] + W[1]*X[1] + ... + W[nrOfLayers-1]*X[nrOfLayers-1] + for(int nl=0; nl<n_layers; nl++){ + const simde__m256i x = simde_mm256_loadu_epi32(&txdataF_res_mapped[nl][symbol][sc]); + + // Rearrange precoding matrix weight to match complex multiplication and broadcast it to match SIMD size + const simde__m256i w_c = simde_mm256_set1_epi32(c16toI32(c16conj(prec_matrix[nl]))); // broadcast conjugate of w + const simde__m256i w_s = simde_mm256_set1_epi32(c16toI32(c16swap(prec_matrix[nl]))); // broadcast swapped real and img of w + + // Multiplication and shift + const simde__m256i reals = simde_mm256_srai_epi32(simde_mm256_madd_epi16(x, w_c), 15); // (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15 + const simde__m256i imags = simde_mm256_slli_epi32(simde_mm256_madd_epi16(x, w_s), 1); // (int32_t) .i = (x.r * w.i + x.i * w.r) << 1, since higher 16 bit of each 32 bit is taken by blend_epi16 + + // Re-arrange to match c16_t format + const simde__m256i produ = simde_mm256_blend_epi16(reals, imags, 0xAA); + + // Accumulate the product + y = simde_mm256_adds_epi16(y, produ); + } + // Store the result to txdataF + simde_mm256_storeu_si256(&txdataF_precoded[sc], y); + } + #endif + + // 128 SIMD: Do 4 RE in one iteration, 3 iterations for 1 RB + const uint32_t re_cnt_align4 = re_cnt & ~3; + for(; sc<sc_offset+re_cnt_align4; sc+=sizeof(simde__m128i)/sizeof(*prec_matrix)){ + #ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Get result with trivial solution, TODO: To be removed + c16_t y_triv[4]; + for(int i=0; i<4; i++) + y_triv[i] = nr_layer_precoder_cm(n_layers, + NR_SYMBOLS_PER_SLOT, + symSz, + txdataF_res_mapped, + prec_matrix, + symbol, + sc + i); + memcpy(&txdataF_precoded[sc], y_triv, sizeof(y_triv)); + #endif + + // Matrix multiplication for 4 elements of the result (sizeof(simde__m128i) / sizeof(c16_t) = 4) + simde__m128i y = simde_mm_set1_epi16(0); // Y = W[0]*X[0] + W[1]*X[1] + ... + W[nrOfLayers-1]*X[nrOfLayers-1] + for(int nl=0; nl<n_layers; nl++){ + const simde__m128i x = simde_mm_loadu_epi32(&txdataF_res_mapped[nl][symbol][sc]); + + // Rearrange precoding matrix weight to match complex multiplication and broadcast it to match SIMD size + const simde__m128i w_c = simde_mm_set1_epi32(c16toI32(c16conj(prec_matrix[nl]))); // broadcast conjugate of w + const simde__m128i w_s = simde_mm_set1_epi32(c16toI32(c16swap(prec_matrix[nl]))); // broadcast swapped real and img of w + + // Multiplication and shift + const simde__m128i reals = simde_mm_srai_epi32(simde_mm_madd_epi16(x, w_c), 15); // (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15 + const simde__m128i imags = simde_mm_slli_epi32(simde_mm_madd_epi16(x, w_s), 1); // (int32_t) .i = (x.r * w.i + x.i * w.r) << 1, since higher 16 bit of each 32 bit is taken by blend_epi16 + + /* Re-arrange to match c16_t format + bit index: 0 | 16 | 32 | 48 | 64 | 80 | 96 | 112 + reals = {R0.r[15..30] | R0.r[31] (0)*15 | R1.r[15..30] | R1.r[31] (0)*15 | R2.r[15..30] | R2.r[31] (0)*15 | R3.r[15..30] | R3.r[31] (0)*15} + imags = {0 R0.i[0..14]| R0.i[15..30] | 0 R1.i[0..14]| R1.i[15..30] | 0 R2.i[0..14]| R2.i[15..30] | 0 R3.i[0..14]| R3.i[15..30] } + 16b from {reals | imags | reals | imags | reals | imags | reals | imags } + produ = {R0.r[15..30] | R0.i[15..30] | R1.r[15..30] | R1.i[15..30] | R2.r[15..30] | R2.i[15..30] | R3.r[15..30] | R3.i[15..30] } + */ + const simde__m128i produ = simde_mm_blend_epi16(reals, imags, 0xAA); + + // Accumulate the product + y = simde_mm_adds_epi16(y, produ); + } + // Store the result to txdataF + simde_mm_storeu_si128(&txdataF_precoded[sc], y); + + #ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Print simd and trivial result, TODO: To be removed + c16_t *y_simd = (c16_t*) &y; + printf("debug_to_be_removed re_cnt=%d, sc=%d, y_simd=(%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d)\n", re_cnt, sc, y_simd[0].r, y_simd[0].i, y_simd[1].r, y_simd[1].i, y_simd[2].r, y_simd[2].i, y_simd[3].r, y_simd[3].i); + printf("debug_to_be_removed re_cnt=%d, sc=%d, y_triv=(%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d)\n", re_cnt, sc, y_triv[0].r, y_triv[0].i, y_triv[1].r, y_triv[1].i, y_triv[2].r, y_triv[2].i, y_triv[3].r, y_triv[3].i); + #endif + } +} diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 45cd4858e8eb44da7487a84229f71b409dd00a47..c129369221fbdaf33ab368ae9f840925523d69c4 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -145,4 +145,20 @@ c16_t nr_layer_precoder_cm(int n_layers, c16_t *prec_matrix, int symbol, int offset); + +/*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[] + @param[in] txdataF_res_mapped Tx data after resource mapping, before precoding. + @param[in] prec_matrix Weights of precoding matrix. + @param[in] re_cnt Number of RE (sub carrier) to write to txdataF_precoded, should be multiple of 4. + @param[out] txdataF_precoded Precoded antenna data +*/ +void nr_layer_precoder_simd(const int n_layers, + const int n_symbols, + const int symSz, + const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz], + const c16_t prec_matrix[n_layers], + const int symbol, + const int sc_offset, + const int re_cnt, + c16_t *txdataF_precoded); #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index b1f9f1a1aa764e8915abf1156753f1683f907c34..51a2059586df2a25b24e9eda8a4b12122367b57b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -209,7 +209,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) if (start_sc >= frame_parms->ofdm_symbol_size) start_sc -= frame_parms->ofdm_symbol_size; - const uint32_t txdataF_offset = slot*frame_parms->samples_per_slot_wCP; + const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP; c16_t txdataF_precoding[rel15->nrOfLayers][NR_NUMBER_OF_SYMBOLS_PER_SLOT][frame_parms->ofdm_symbol_size] __attribute__((aligned(64)));; #ifdef DEBUG_DLSCH_MAPPING @@ -486,35 +486,40 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) { for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) { uint16_t subCarrier = start_sc; - - for (int rb=0; rb<rel15->rbSize; rb++) { - const size_t txdataF_offset_per_symbol = l_symbol * frame_parms->ofdm_symbol_size + txdataF_offset; - + const size_t txdataF_offset_per_symbol = l_symbol * frame_parms->ofdm_symbol_size + txdataF_offset; + int rb = 0; + while(rb < rel15->rbSize) { //get pmi info - uint8_t pmi; - if (0 /*rel15->precodingAndBeamforming.prg_size > 0*/) - pmi = rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx; - else - pmi = 0;//no precoding + const int pmi = (rel15->precodingAndBeamforming.prg_size > 0) ? + (rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx) : 0; + const int pmi2 = (rb < (rel15->rbSize - 1) && rel15->precodingAndBeamforming.prg_size > 0) ? + (rel15->precodingAndBeamforming.prgs_list[(int)(rb+1)/rel15->precodingAndBeamforming.prg_size].pm_idx) : -1; + + // If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row + // if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row + const int rb_step = pmi == pmi2 ? 2 : 1; + const int re_cnt = NR_NB_SC_PER_RB * rb_step; if (pmi == 0) {//unitary Precoding - if (subCarrier + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC + if (subCarrier + re_cnt <= frame_parms->ofdm_symbol_size) { // RB does not cross DC if (ant < rel15->nrOfLayers) - memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], - &txdataF_precoding[ant][l_symbol][subCarrier], - NR_NB_SC_PER_RB * sizeof(**txdataF)); + memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], + &txdataF_precoding[ant][l_symbol][subCarrier], + re_cnt * sizeof(**txdataF)); else memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, - NR_NB_SC_PER_RB * sizeof(**txdataF)); + re_cnt * sizeof(**txdataF)); } else { // RB does cross DC - int neg_length = frame_parms->ofdm_symbol_size - subCarrier; - int pos_length = NR_NB_SC_PER_RB - neg_length; + const int neg_length = frame_parms->ofdm_symbol_size - subCarrier; + const int pos_length = re_cnt - neg_length; if (ant < rel15->nrOfLayers) { memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], &txdataF_precoding[ant][l_symbol][subCarrier], neg_length * sizeof(**txdataF)); - memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant][l_symbol], pos_length * sizeof(**txdataF)); + memcpy(&txdataF[ant][txdataF_offset_per_symbol], + &txdataF_precoding[ant][l_symbol], + pos_length * sizeof(**txdataF)); } else { memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, @@ -524,51 +529,68 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) pos_length * sizeof(**txdataF)); } } - subCarrier += NR_NB_SC_PER_RB; + subCarrier += re_cnt; if (subCarrier >= frame_parms->ofdm_symbol_size) { subCarrier -= frame_parms->ofdm_symbol_size; } } - else { - if(frame_parms->nb_antennas_tx==1){//no precoding matrix defined + else { // non-unitary Precoding + if(frame_parms->nb_antennas_tx == 1){ // no precoding matrix defined memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], &txdataF_precoding[ant][l_symbol][subCarrier], - NR_NB_SC_PER_RB * sizeof(**txdataF)); - subCarrier += NR_NB_SC_PER_RB; + re_cnt * sizeof(**txdataF)); + subCarrier += re_cnt; if (subCarrier >= frame_parms->ofdm_symbol_size) { subCarrier -= frame_parms->ofdm_symbol_size; } } - else { + else { // precoding with more than 1 tx //get the precoding matrix weights: c16_t **mat = (c16_t**)gNB->nr_mimo_precoding_matrix[rel15->nrOfLayers - 1]; //i_row =0,...,dl_antenna_port //j_col =0,...,nrOfLayers //mat[pmi][i_rows*2+j_col] c16_t *W_prec = &mat[pmi][ant * rel15->nrOfLayers]; - for (int i=0; i<NR_NB_SC_PER_RB; i++) { - txdataF[ant][txdataF_offset_per_symbol + subCarrier] = nr_layer_precoder_cm(rel15->nrOfLayers, - NR_SYMBOLS_PER_SLOT, - frame_parms->ofdm_symbol_size, - txdataF_precoding, - W_prec, - l_symbol, - subCarrier); + if((subCarrier + re_cnt) < frame_parms->ofdm_symbol_size){ // within ofdm_symbol_size, use SIMDe + nr_layer_precoder_simd(rel15->nrOfLayers, + NR_SYMBOLS_PER_SLOT, + frame_parms->ofdm_symbol_size, + txdataF_precoding, + W_prec, + l_symbol, + subCarrier, + re_cnt, + &txdataF[ant][txdataF_offset_per_symbol]); + subCarrier += re_cnt; + } + else{ // crossing ofdm_symbol_size, use simple arithmetic operations + for (int i = 0; i < re_cnt; i++) { + txdataF[ant][txdataF_offset_per_symbol + subCarrier] = + nr_layer_precoder_cm(rel15->nrOfLayers, + NR_SYMBOLS_PER_SLOT, + frame_parms->ofdm_symbol_size, + txdataF_precoding, + W_prec, + l_symbol, + subCarrier); #ifdef DEBUG_DLSCH_MAPPING - printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n", - ant, - l_symbol, - subCarrier, - txdataF[ant][l_symbol * frame_parms->ofdm_symbol_size + subCarrier + txdataF_offset].r, - txdataF[ant][l_symbol * frame_parms->ofdm_symbol_size + subCarrier + txdataF_offset].i); + printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n", + ant, + symbol, + subCarrier, + txdataF[ant][l_symbol * frame_parms->ofdm_symbol_size + subCarrier + txdataF_offset].r, + txdataF[ant][l_symbol * frame_parms->ofdm_symbol_size + subCarrier + txdataF_offset].i); #endif - if (++subCarrier >= frame_parms->ofdm_symbol_size) { - subCarrier -= frame_parms->ofdm_symbol_size; + if (++subCarrier >= frame_parms->ofdm_symbol_size) { + subCarrier -= frame_parms->ofdm_symbol_size; + } } - } - } - } - } //RB loop + } // else{ // crossing ofdm_symbol_size, use simple arithmetic operations + } // else { // precoding with more than 1 tx + } // else { // non-unitary Precoding + + rb += rb_step; + } // RB loop: while(rb < rel15->rbSize) } // symbol loop } // port loop diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 61497871f8eb04fd028625d96de2b928b79e3159..e98b20b277f3408a832315d752c5c838fbc68f79 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -161,6 +161,24 @@ extern "C" { #define squaredMod(a) ((a).r*(a).r + (a).i*(a).i) #define csum(res, i1, i2) (res).r = (i1).r + (i2).r ; (res).i = (i1).i + (i2).i + __attribute__((always_inline)) inline c16_t c16conj(const c16_t a) { + return (c16_t) { + .r = a.r, + .i = (int16_t)-a.i + }; + } + + __attribute__((always_inline)) inline uint32_t c16toI32(const c16_t a) { + return *((uint32_t*)&a); + } + + __attribute__((always_inline)) inline c16_t c16swap(const c16_t a) { + return (c16_t){ + .r = a.i, + .i = a.r + }; + } + __attribute__((always_inline)) inline uint32_t c16amp2(const c16_t a) { return a.r * a.r + a.i * a.i; } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index b91f8e52109e91ae716cfc0cf69ae77574271991..a31112c90d36a7209492107425264746e9f4d60e 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -754,8 +754,11 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) const int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; int offset = 10 * gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; - int power_rxF = signal_energy_nodc((int32_t *)&gNB->common_vars.rxdataF[0][soffset + offset + (47 * 12)], 12 * 18); - LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF); + LOG_D(PHY, + "frame %d, slot %d: UL signal energy %d\n", + frame_rx, + slot_rx, + signal_energy_nodc((int32_t *)&gNB->common_vars.rxdataF[0][soffset + offset + (47 * 12)], 12 * 18)); start_meas(&gNB->phy_proc_rx); @@ -783,8 +786,11 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1; offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12); - power_rxF = signal_energy_nodc((int32_t *)&gNB->common_vars.rxdataF[0][soffset+offset], 12); - LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n", frame_rx, slot_rx, power_rxF); + LOG_D(PHY, + "frame %d, slot %d: PUCCH signal energy %d\n", + frame_rx, + slot_rx, + signal_energy_nodc((int32_t *)&gNB->common_vars.rxdataF[0][soffset + offset], 12)); nr_decode_pucch0(gNB, frame_rx, diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 20aabed512bfe7e849747c4f2dec44b0b3c21b48..812a2a59fbc147ede91776f9497f0f94ad507083 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -54,15 +54,13 @@ #include "NR_UE_PHY_INTERFACE/NR_IF_Module.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" -//#include "LAYER2/NR_MAC_gNB/mac_proto.h" -//#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "NR_asn_constant.h" #include "RRC/NR/nr_rrc_config.h" #include "openair1/SIMULATION/RF/rf.h" #include "openair1/SIMULATION/TOOLS/sim.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" -//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "NR_RRCReconfiguration.h" #define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) @@ -138,14 +136,6 @@ void nr_dlsim_preprocessor(module_id_t module_id, NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP; NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; - //TODO better implementation needed - //for now artificially set candidates for the required aggregation levels - sched_ctrl->search_space->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; - sched_ctrl->search_space->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - sched_ctrl->search_space->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; - sched_ctrl->search_space->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1; - sched_ctrl->search_space->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; - uint8_t nr_of_candidates = 0; if (g_mcsIndex < 4) { find_aggregation_candidates(&sched_ctrl->aggregation_level, @@ -614,6 +604,7 @@ int main(int argc, char **argv) InitSinLUT(); get_softmodem_params()->phy_test = 1; + get_softmodem_params()->usim_test = 1; get_softmodem_params()->do_ra = 0; set_softmodem_optmask(SOFTMODEM_DLSIM_BIT); @@ -879,10 +870,13 @@ int main(int argc, char **argv) // generate signal AssertFatal(input_fd==NULL,"Not ready for input signal file\n"); + // clone CellGroup to have a separate copy at UE + NR_CellGroupConfig_t *UE_CellGroup = clone_CellGroupConfig(secondaryCellGroup); + //Configure UE NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false); - nr_rrc_mac_config_req_cg(0, 0, secondaryCellGroup); + nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup); UE_mac->state = UE_CONNECTED; UE_mac->ra.ra_state = RA_SUCCEEDED; @@ -1409,7 +1403,7 @@ void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg) } /* Additional DMRS positions 0 ,1 ,2 and 3 */ - if(dmrs_arg[1] >= 0 && dmrs_arg[1] <4 ) { + if (dmrs_arg[1] >= 0 && dmrs_arg[1] < 4) { add_pos = dmrs_arg[1]; } else { AssertFatal(1==0,"Incorrect Additional Position, valid options 0-pos1, 1-pos1, 2-pos2, 3-pos3\n"); @@ -1468,7 +1462,19 @@ void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg) if (dmrs_config->dmrs_AdditionalPosition == NULL) { dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition)); } - *dmrs_config->dmrs_AdditionalPosition = add_pos; + switch (add_pos) { + case 0: + *dmrs_config->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0; + break; + case 1: + *dmrs_config->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1; + break; + case 3: + *dmrs_config->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3; + break; + default: + AssertFatal(false, "DMRS additional position %d not valid\n", add_pos); + } } else { // if NULL, Value pos2 free(dmrs_config->dmrs_AdditionalPosition); dmrs_config->dmrs_AdditionalPosition = NULL; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index de0373e37a109822c5ac950b1e7054f18ae96604..bc12793140f2179dac1adf038cd8848ebb50b926 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -278,7 +278,8 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_dl; scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_DL; - scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth=275*(N_RB_DL-1); + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth = + PRBalloc_to_locationandbandwidth(N_RB_DL, 0); scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing=mu_dl;//NR_SubcarrierSpacing_kHz30; *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=12; *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero=0; @@ -298,7 +299,7 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_ul; scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_UL; *scc->uplinkConfigCommon->frequencyInfoUL->p_Max=20; - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth=275*(N_RB_UL-1); + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(N_RB_UL, 0); scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing=mu_ul;//NR_SubcarrierSpacing_kHz30; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex=98; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM=NR_RACH_ConfigGeneric__msg1_FDM_one; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index e5c7e7e04bf8e30c88af2bca8d54cfdd839057ea..0df63710b28bc87686d4e9059f014a946a26151c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -560,48 +560,61 @@ typedef struct nr_srs_feedback { typedef struct NR_UE_DL_BWP { NR_BWP_Id_t bwp_id; - int n_dl_bwp; int scs; long *cyclicprefix; uint16_t BWPSize; uint16_t BWPStart; - uint16_t initial_BWPSize; - uint16_t initial_BWPStart; NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList_Common; NR_PDSCH_Config_t *pdsch_Config; - NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig; uint8_t mcsTableIdx; nr_dci_format_t dci_format; - int bw_tbslbrm; } NR_UE_DL_BWP_t; typedef struct NR_UE_UL_BWP { NR_BWP_Id_t bwp_id; - int n_ul_bwp; int scs; long *cyclicprefix; uint16_t BWPSize; uint16_t BWPStart; - uint16_t initial_BWPSize; - uint16_t initial_BWPStart; NR_RACH_ConfigCommon_t *rach_ConfigCommon; - NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig; NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList_Common; NR_ConfiguredGrantConfig_t *configuredGrantConfig; NR_PUSCH_Config_t *pusch_Config; NR_PUCCH_Config_t *pucch_Config; NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon; - NR_UplinkConfig_t *supplementaryUplink; - NR_CSI_MeasConfig_t *csi_MeasConfig; NR_SRS_Config_t *srs_Config; long *msg3_DeltaPreamble; long transform_precoding; uint8_t mcs_table; nr_dci_format_t dci_format; - int bw_tbslbrm; int max_fb_time; } NR_UE_UL_BWP_t; +// non-BWP serving cell configuration +typedef struct { + NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig; + NR_SRS_CarrierSwitching_t *carrierSwitching; + NR_UplinkConfig_t *supplementaryUplink; + NR_PDSCH_CodeBlockGroupTransmission_t *pdsch_CGB_Transmission; + long *xOverhead_PDSCH; + long *nrofHARQ_ProcessesForPDSCH; + long *maxMIMO_Layers_PDSCH; + NR_PUSCH_CodeBlockGroupTransmission_t *pusch_CGB_Transmission; + long *rateMatching_PUSCH; + long *xOverhead_PUSCH; + long *maxMIMO_Layers_PUSCH; + NR_CSI_MeasConfig_t *csi_MeasConfig; + NR_CSI_AperiodicTriggerStateList_t *aperiodicTriggerStateList; + uint16_t initial_dl_BWPSize; + uint16_t initial_dl_BWPStart; + uint16_t initial_ul_BWPSize; + uint16_t initial_ul_BWPStart; + int n_dl_bwp; + int n_ul_bwp; + int dl_bw_tbslbrm; + int ul_bw_tbslbrm; +} NR_UE_ServingCell_Info_t; + typedef enum { defaultA = 0, defaultB = 1, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index aceec80613a7d129460813efc71f28d5056d773c..e0bc7ccb2ad378c2af5de883834983b84c4fe3b0 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -608,7 +608,9 @@ NR_tda_info_t get_dl_tda_info(const NR_UE_DL_BWP_t *dl_BWP, int ss_type, int tda int mux_pattern, nr_rnti_type_t rnti_type, int coresetid, bool sib1) { NR_tda_info_t tda_info; - bool normal_CP = dl_BWP->cyclicprefix ? false : true; + bool normal_CP = true; + if (dl_BWP && dl_BWP->cyclicprefix) + normal_CP = false; // implements Table 5.1.2.1.1-1 of 38.214 NR_PDSCH_TimeDomainResourceAllocationList_t *tdalist = get_dl_tdalist(dl_BWP, coresetid, ss_type, rnti_type); switch (rnti_type) { @@ -2865,7 +2867,7 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, } // #define DEBUG_SRS_RESOURCE_IND -uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig, +uint8_t compute_srs_resource_indicator(long *maxMIMO_Layers, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, nr_srs_feedback_t *srs_feedback, @@ -2930,15 +2932,10 @@ uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servi // - otherwise, Lmax is given by the maximum number of layers for PUSCH supported by the UE for the serving cell // for non-codebook based operation. int Lmax = 0; - if (pusch_servingcellconfig != NULL) { - if (pusch_servingcellconfig->ext1->maxMIMO_Layers != NULL) { - Lmax = *pusch_servingcellconfig->ext1->maxMIMO_Layers; - } else { - AssertFatal(1 == 0, "MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); - } - } else { + if (maxMIMO_Layers != NULL) + Lmax = *maxMIMO_Layers; + else AssertFatal(1 == 0, "MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); - } int lmin = 0; int lsum = 0; int count = 0; @@ -3278,7 +3275,7 @@ uint16_t get_rb_bwp_dci(nr_dci_format_t format, uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, const NR_UE_UL_BWP_t *UL_BWP, - const NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig, + const NR_UE_ServingCell_Info_t *sc_info, long pdsch_HARQ_ACK_Codebook, dci_pdu_rel15_t *dci_pdu, nr_dci_format_t format, @@ -3289,7 +3286,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, uint16_t cset0_bwp_size, uint16_t alt_size) { - uint16_t size = 0; uint16_t numRBG = 0; long rbg_size_config; @@ -3307,8 +3303,8 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, cset0_bwp_size, UL_BWP->BWPSize, DL_BWP->BWPSize, - UL_BWP->initial_BWPSize, - DL_BWP->initial_BWPSize); + sc_info->initial_ul_BWPSize, + sc_info->initial_dl_BWPSize); switch(format) { case NR_UL_DCI_FORMAT_0_0: @@ -3329,21 +3325,21 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, ULSCH indicator 1 --16 size += 16; // Carrier indicator - if (crossCarrierSchedulingConfig != NULL) { - dci_pdu->carrier_indicator.nbits=3; + if (sc_info->crossCarrierSchedulingConfig) { + dci_pdu->carrier_indicator.nbits = 3; size += dci_pdu->carrier_indicator.nbits; } // UL/SUL indicator - if (UL_BWP->supplementaryUplink != NULL) { - dci_pdu->carrier_indicator.nbits=1; + if (sc_info->supplementaryUplink) { + dci_pdu->carrier_indicator.nbits = 1; size += dci_pdu->ul_sul_indicator.nbits; } // BWP Indicator - if (UL_BWP->n_ul_bwp < 2) - dci_pdu->bwp_indicator.nbits = UL_BWP->n_ul_bwp; + if (sc_info->n_ul_bwp < 2) + dci_pdu->bwp_indicator.nbits = sc_info->n_ul_bwp; else dci_pdu->bwp_indicator.nbits = 2; - LOG_D(NR_MAC, "BWP indicator nbits %d, num UL BWPs %d\n", dci_pdu->bwp_indicator.nbits, UL_BWP->n_ul_bwp); + LOG_D(NR_MAC, "BWP indicator nbits %d, num UL BWPs %d\n", dci_pdu->bwp_indicator.nbits, sc_info->n_ul_bwp); size += dci_pdu->bwp_indicator.nbits; // Freq domain assignment if (pusch_Config) { @@ -3384,12 +3380,13 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, size += dci_pdu->dai[0].nbits; LOG_D(NR_MAC, "DAI1 nbits %d\n", dci_pdu->dai[0].nbits); // 2nd DAI - if (DL_BWP->pdsch_servingcellconfig && DL_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) { + if (sc_info->pdsch_CGB_Transmission) { dci_pdu->dai[1].nbits = 2; size += dci_pdu->dai[1].nbits; } // SRS resource indicator - dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(UL_BWP->pusch_servingcellconfig, pusch_Config, srs_config, NULL, NULL); + dci_pdu->srs_resource_indicator.nbits = + compute_srs_resource_indicator(sc_info->maxMIMO_Layers_PUSCH, pusch_Config, srs_config, NULL, NULL); size += dci_pdu->srs_resource_indicator.nbits; LOG_D(NR_MAC, "dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers @@ -3417,21 +3414,21 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, size += dci_pdu->antenna_ports.nbits; LOG_D(NR_MAC,"dci_pdu->antenna_ports.nbits = %d\n",dci_pdu->antenna_ports.nbits); // SRS request - if (UL_BWP->supplementaryUplink == NULL) + if (sc_info->supplementaryUplink == NULL) dci_pdu->srs_request.nbits = 2; else dci_pdu->srs_request.nbits = 3; size += dci_pdu->srs_request.nbits; // CSI request - if (UL_BWP->csi_MeasConfig != NULL) { - if (UL_BWP->csi_MeasConfig->reportTriggerSize != NULL) { - dci_pdu->csi_request.nbits = *UL_BWP->csi_MeasConfig->reportTriggerSize; + if (sc_info->csi_MeasConfig != NULL) { + if (sc_info->csi_MeasConfig->reportTriggerSize != NULL) { + dci_pdu->csi_request.nbits = *sc_info->csi_MeasConfig->reportTriggerSize; size += dci_pdu->csi_request.nbits; } } // CBGTI - if (UL_BWP->pusch_servingcellconfig && UL_BWP->pusch_servingcellconfig->codeBlockGroupTransmission != NULL) { - int num = UL_BWP->pusch_servingcellconfig->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock; + if (sc_info->pusch_CGB_Transmission) { + int num = sc_info->pusch_CGB_Transmission->maxCodeBlockGroupsPerTransportBlock; dci_pdu->cbgti.nbits = 2 + (num<<1); size += dci_pdu->cbgti.nbits; } @@ -3482,14 +3479,14 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, // Format identifier size = 1; // Carrier indicator - if (crossCarrierSchedulingConfig != NULL) { - dci_pdu->carrier_indicator.nbits=3; + if (sc_info->crossCarrierSchedulingConfig) { + dci_pdu->carrier_indicator.nbits = 3; size += dci_pdu->carrier_indicator.nbits; } // BWP Indicator - if (DL_BWP->n_dl_bwp < 2) - dci_pdu->bwp_indicator.nbits = DL_BWP->n_dl_bwp; + if (sc_info->n_dl_bwp < 2) + dci_pdu->bwp_indicator.nbits = sc_info->n_dl_bwp; else dci_pdu->bwp_indicator.nbits = 2; size += dci_pdu->bwp_indicator.nbits; @@ -3559,7 +3556,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, // PUCCH resource indicator size += 3; // PDSCH to HARQ timing indicator - uint8_t I = pucch_Config->dl_DataToUL_ACK ? pucch_Config->dl_DataToUL_ACK->list.count : 8; + uint8_t I = (pucch_Config && pucch_Config->dl_DataToUL_ACK) ? pucch_Config->dl_DataToUL_ACK->list.count : 8; dci_pdu->pdsch_to_harq_feedback_timing_indicator.nbits = (int)ceil(log2(I)); size += dci_pdu->pdsch_to_harq_feedback_timing_indicator.nbits; LOG_D(NR_MAC,"dci_pdu->pdsch_to_harq_feedback_timing_indicator.nbits %d\n",dci_pdu->pdsch_to_harq_feedback_timing_indicator.nbits); @@ -3576,20 +3573,20 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, size += dci_pdu->transmission_configuration_indication.nbits; } // SRS request - if (UL_BWP->supplementaryUplink == NULL) + if (sc_info->supplementaryUplink == NULL) dci_pdu->srs_request.nbits = 2; else dci_pdu->srs_request.nbits = 3; size += dci_pdu->srs_request.nbits; // CBGTI - if (DL_BWP->pdsch_servingcellconfig && DL_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) { - uint8_t maxCBGperTB = (DL_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock + 1) * 2; + if (sc_info->pdsch_CGB_Transmission) { + uint8_t maxCBGperTB = (sc_info->pdsch_CGB_Transmission->maxCodeBlockGroupsPerTransportBlock + 1) * 2; long *maxCWperDCI_rrc = pdsch_Config->maxNrofCodeWordsScheduledByDCI; uint8_t maxCW = (maxCWperDCI_rrc == NULL) ? 1 : *maxCWperDCI_rrc; dci_pdu->cbgti.nbits = maxCBGperTB * maxCW; size += dci_pdu->cbgti.nbits; // CBGFI - if (DL_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup->codeBlockGroupFlushIndicator) { + if (sc_info->pdsch_CGB_Transmission->codeBlockGroupFlushIndicator) { dci_pdu->cbgfi.nbits = 1; size += dci_pdu->cbgfi.nbits; } @@ -3613,7 +3610,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, default: AssertFatal(1==0, "Invalid NR DCI format %d\n", format); } - + LOG_D(NR_MAC, "DCI size: %d\n", size); return size; } @@ -3713,7 +3710,6 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, mappingType_t mappingtype, int length) { - int dmrs_AdditionalPosition = 0; NR_DMRS_DownlinkConfig_t *dmrs_config = NULL; @@ -4734,43 +4730,6 @@ uint16_t compute_pucch_prb_size(uint8_t format, return 0; } -int get_dlbw_tbslbrm(int scc_bwpsize, - const NR_ServingCellConfig_t *servingCellConfig) -{ - int bw = scc_bwpsize; - if (servingCellConfig) { - if(servingCellConfig->downlinkBWP_ToAddModList) { - const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = servingCellConfig->downlinkBWP_ToAddModList; - for (int i=0; i<BWP_list->list.count; i++) { - NR_BWP_t genericParameters = BWP_list->list.array[i]->bwp_Common->genericParameters; - int curr_bw = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - if (curr_bw > bw) - bw = curr_bw; - } - } - } - return bw; -} - -int get_ulbw_tbslbrm(int scc_bwpsize, - const NR_ServingCellConfig_t *servingCellConfig) -{ - int bw = scc_bwpsize; - if (servingCellConfig) { - if (servingCellConfig->uplinkConfig && - servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList) { - const struct NR_UplinkConfig__uplinkBWP_ToAddModList *BWP_list = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; - for (int i=0; i<BWP_list->list.count; i++) { - NR_BWP_t genericParameters = BWP_list->list.array[i]->bwp_Common->genericParameters; - int curr_bw = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - if (curr_bw > bw) - bw = curr_bw; - } - } - } - return bw; -} - /* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index fab681d8f016abeb54c90d3fc7cb3666ca1597e9..315cc9837b912412ba8d6c86129e806e9b26228a 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -71,7 +71,7 @@ bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, s bool is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type); -uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig, +uint8_t compute_srs_resource_indicator(long *maxMIMO_Layers, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, nr_srs_feedback_t *srs_feedback, @@ -95,7 +95,7 @@ NR_tda_info_t get_dl_tda_info(const NR_UE_DL_BWP_t *dl_BWP, int ss_type, int tda uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, const NR_UE_UL_BWP_t *UL_BWP, - const NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig, + const NR_UE_ServingCell_Info_t *sc_info, long pdsch_HARQ_ACK_Codebook, dci_pdu_rel15_t *dci_pdu, nr_dci_format_t format, @@ -196,12 +196,6 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset); -int get_dlbw_tbslbrm(int scc_bwpsize, - const NR_ServingCellConfig_t *servingCellConfig); - -int get_ulbw_tbslbrm(int scc_bwpsize, - const NR_ServingCellConfig_t *servingCellConfig); - uint32_t nr_compute_tbslbrm(uint16_t table, uint16_t nb_rb, uint8_t Nl); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 9ffd98062783856aa23166eecfc820c5db5b9a80..b7bfcb501eb4d48065defdcca90e976574ee6f51 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -40,6 +40,7 @@ #include "common/utils/nr/nr_common.h" #include "executables/softmodem-common.h" #include "SCHED_NR/phy_frame_config_nr.h" +#include "oai_asn1.h" const long logicalChannelGroup0_NR = 0; typedef struct NR_LogicalChannelConfig__ul_SpecificParameters LcConfig_UlParamas_t; @@ -129,10 +130,10 @@ void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, } } -void config_common_ue_sa(NR_UE_MAC_INST_t *mac, - NR_ServingCellConfigCommonSIB_t *scc, - module_id_t module_id, - int cc_idP) +static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, + NR_ServingCellConfigCommonSIB_t *scc, + module_id_t module_id, + int cc_idP) { fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; mac->phy_config.Mod_id = module_id; @@ -142,10 +143,12 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, // carrier config NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL; + AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n"); + mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR; int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, + mac->nr_band, frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); - cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR > 256 ? FR2 : FR1, bw_index); + cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) * (15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); @@ -163,13 +166,11 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, } NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL; - int UL_band_ind = frequencyInfoUL->frequencyBandList == NULL ? - *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR : - *frequencyInfoUL->frequencyBandList->list.array[0]->freqBandIndicatorNR; + mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - UL_band_ind, + mac->nr_band, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); - cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(UL_band_ind > 256 ? FR2 : FR1, bw_index); + cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); if (frequencyInfoUL->absoluteFrequencyPointA == NULL) cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency; @@ -190,7 +191,6 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology); // cell config - cfg->cell_config.phy_cell_id = mac->physCellId; cfg->cell_config.frame_duplex_type = mac->frame_type; @@ -216,14 +216,10 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, // TDD Table Configuration if (cfg->cell_config.frame_duplex_type == TDD){ - set_tdd_config_nr_ue(&cfg->tdd_table_1, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - &mac->tdd_UL_DL_ConfigurationCommon->pattern1); + set_tdd_config_nr_ue(&cfg->tdd_table_1, cfg->ssb_config.scs_common, &mac->tdd_UL_DL_ConfigurationCommon->pattern1); if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) { cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t)); - set_tdd_config_nr_ue(cfg->tdd_table_2, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->tdd_UL_DL_ConfigurationCommon->pattern2); + set_tdd_config_nr_ue(cfg->tdd_table_2, cfg->ssb_config.scs_common, mac->tdd_UL_DL_ConfigurationCommon->pattern2); } } @@ -238,27 +234,20 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, if (rach_ConfigCommon->msg1_SubcarrierSpacing) cfg->prach_config.prach_sub_c_spacing = *rach_ConfigCommon->msg1_SubcarrierSpacing; - else - cfg->prach_config.prach_sub_c_spacing = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + else { + // If absent, the UE applies the SCS as derived from the prach-ConfigurationIndex (for 839) + int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, mac->frame_type); + int format = prach_config_info_p[0]; + cfg->prach_config.prach_sub_c_spacing = format == 3 ? 5 : 4; + } cfg->prach_config.restricted_set_config = rach_ConfigCommon->restrictedSetConfig; - switch (rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM) { - case 0 : - cfg->prach_config.num_prach_fd_occasions = 1; - break; - case 1 : - cfg->prach_config.num_prach_fd_occasions = 2; - break; - case 2 : - cfg->prach_config.num_prach_fd_occasions = 4; - break; - case 3 : - cfg->prach_config.num_prach_fd_occasions = 8; - break; - default: - AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM); - } + AssertFatal(rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM < 4, + "msg1 FDM identifier %ld undefined (0,1,2,3)\n", rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM); + cfg->prach_config.num_prach_fd_occasions = 1 << rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM; + cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t)); for (int i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) { @@ -280,10 +269,10 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, } -void config_common_ue(NR_UE_MAC_INST_t *mac, - NR_ServingCellConfigCommon_t *scc, - module_id_t module_id, - int cc_idP) +static void config_common_ue(NR_UE_MAC_INST_t *mac, + NR_ServingCellConfigCommon_t *scc, + module_id_t module_id, + int cc_idP) { fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; @@ -293,82 +282,88 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, // carrier config LOG_D(MAC, "Entering UE Config Common\n"); - AssertFatal(scc != NULL, "scc cannot be null\n"); - - struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - *frequencyInfoDL->frequencyBandList.list.array[0], - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); - cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1, bw_index); - - cfg->carrier_config.dl_frequency = from_nrarfcn(*frequencyInfoDL->frequencyBandList.list.array[0], - *scc->ssbSubcarrierSpacing, - frequencyInfoDL->absoluteFrequencyPointA)/1000; // freq in kHz - - for (int i = 0; i < 5; i++) { - if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { - cfg->carrier_config.dl_grid_size[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - cfg->carrier_config.dl_k0[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; - } - else { - cfg->carrier_config.dl_grid_size[i] = 0; - cfg->carrier_config.dl_k0[i] = 0; - } - } + AssertFatal(scc->downlinkConfigCommon, "Not expecting downlinkConfigCommon to be NULL here\n"); - struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; - bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - *frequencyInfoUL->frequencyBandList->list.array[0], - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); - cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, bw_index); + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + if (frequencyInfoDL) { // NeedM for inter-freq handover + mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]; + mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology); + mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2; - int UL_pointA; - if (frequencyInfoUL->absoluteFrequencyPointA == NULL) - UL_pointA = frequencyInfoDL->absoluteFrequencyPointA; - else - UL_pointA = *frequencyInfoUL->absoluteFrequencyPointA; + int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->nr_band, + frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); - cfg->carrier_config.uplink_frequency = from_nrarfcn(*frequencyInfoUL->frequencyBandList->list.array[0], - *scc->ssbSubcarrierSpacing, - UL_pointA) / 1000; // freq in kHz + cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band, + *scc->ssbSubcarrierSpacing, + frequencyInfoDL->absoluteFrequencyPointA) + / 1000; // freq in kHz - for (int i = 0; i < 5; i++) { - if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { - cfg->carrier_config.ul_grid_size[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - cfg->carrier_config.ul_k0[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; - } - else { - cfg->carrier_config.ul_grid_size[i] = 0; - cfg->carrier_config.ul_k0[i] = 0; + for (int i = 0; i < 5; i++) { + if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { + cfg->carrier_config.dl_grid_size[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + cfg->carrier_config.dl_k0[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + } else { + cfg->carrier_config.dl_grid_size[i] = 0; + cfg->carrier_config.dl_k0[i] = 0; + } } } - uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; - mac->frequency_range = band<100?FR1:FR2; - - frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); + if (scc->uplinkConfigCommon && scc->uplinkConfigCommon->frequencyInfoUL) { + NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; + mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; + + int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + *frequencyInfoUL->frequencyBandList->list.array[0], + frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); + + long *UL_pointA = NULL; + if (frequencyInfoUL->absoluteFrequencyPointA) + UL_pointA = frequencyInfoUL->absoluteFrequencyPointA; + else if (frequencyInfoDL) + UL_pointA = &frequencyInfoDL->absoluteFrequencyPointA; + + if (UL_pointA) + cfg->carrier_config.uplink_frequency = from_nrarfcn(*frequencyInfoUL->frequencyBandList->list.array[0], + *scc->ssbSubcarrierSpacing, + *UL_pointA) + / 1000; // freq in kHz + + for (int i = 0; i < 5; i++) { + if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { + cfg->carrier_config.ul_grid_size[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + cfg->carrier_config.ul_k0[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + } else { + cfg->carrier_config.ul_grid_size[i] = 0; + cfg->carrier_config.ul_k0[i] = 0; + } + } + } // cell config - cfg->cell_config.phy_cell_id = *scc->physCellId; - cfg->cell_config.frame_duplex_type = frame_type; + cfg->cell_config.frame_duplex_type = mac->frame_type; // SSB config cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower; cfg->ssb_config.scs_common = *scc->ssbSubcarrierSpacing; // SSB Table config - int scs_scaling = 1<<(cfg->ssb_config.scs_common); - if (frequencyInfoDL->absoluteFrequencyPointA < 600000) - scs_scaling = scs_scaling*3; - if (frequencyInfoDL->absoluteFrequencyPointA > 2016666) - scs_scaling = scs_scaling>>2; - uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA); - cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10; - cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; - - // NSA -> take ssb offset from SCS - cfg->ssb_table.ssb_subcarrier_offset = absolute_diff%(12*scs_scaling); + if (frequencyInfoDL && frequencyInfoDL->absoluteFrequencySSB) { + int scs_scaling = 1 << (cfg->ssb_config.scs_common); + if (frequencyInfoDL->absoluteFrequencyPointA < 600000) + scs_scaling = scs_scaling * 3; + if (frequencyInfoDL->absoluteFrequencyPointA > 2016666) + scs_scaling = scs_scaling >> 2; + uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA); + cfg->ssb_table.ssb_offset_point_a = absolute_diff / (12 * scs_scaling) - 10; + cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; + // NSA -> take ssb offset from SCS + cfg->ssb_table.ssb_subcarrier_offset = absolute_diff % (12 * scs_scaling); + } switch (scc->ssb_PositionsInBurst->present) { case 1 : @@ -393,82 +388,111 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, // TDD Table Configuration if (cfg->cell_config.frame_duplex_type == TDD){ - set_tdd_config_nr_ue(&cfg->tdd_table_1, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - &mac->tdd_UL_DL_ConfigurationCommon->pattern1); + set_tdd_config_nr_ue(&cfg->tdd_table_1, cfg->ssb_config.scs_common, &mac->tdd_UL_DL_ConfigurationCommon->pattern1); if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) { cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t)); - set_tdd_config_nr_ue(cfg->tdd_table_2, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->tdd_UL_DL_ConfigurationCommon->pattern2); + set_tdd_config_nr_ue(cfg->tdd_table_2, cfg->ssb_config.scs_common, mac->tdd_UL_DL_ConfigurationCommon->pattern2); } } // PRACH configuration uint8_t nb_preambles = 64; - NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - if(rach_ConfigCommon->totalNumberOfRA_Preambles != NULL) - nb_preambles = *rach_ConfigCommon->totalNumberOfRA_Preambles; + if (scc->uplinkConfigCommon && scc->uplinkConfigCommon->initialUplinkBWP + && scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon) { // all NeedM - cfg->prach_config.prach_sequence_length = rach_ConfigCommon->prach_RootSequenceIndex.present-1; + NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + if (rach_ConfigCommon->totalNumberOfRA_Preambles != NULL) + nb_preambles = *rach_ConfigCommon->totalNumberOfRA_Preambles; - if (rach_ConfigCommon->msg1_SubcarrierSpacing) - cfg->prach_config.prach_sub_c_spacing = *rach_ConfigCommon->msg1_SubcarrierSpacing; - else - cfg->prach_config.prach_sub_c_spacing = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - - cfg->prach_config.restricted_set_config = rach_ConfigCommon->restrictedSetConfig; - - switch (rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM) { - case 0 : - cfg->prach_config.num_prach_fd_occasions = 1; - break; - case 1 : - cfg->prach_config.num_prach_fd_occasions = 2; - break; - case 2 : - cfg->prach_config.num_prach_fd_occasions = 4; - break; - case 3 : - cfg->prach_config.num_prach_fd_occasions = 8; - break; - default: - AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM); - } + cfg->prach_config.prach_sequence_length = rach_ConfigCommon->prach_RootSequenceIndex.present - 1; - cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t)); - for (int i = 0; i < cfg->prach_config.num_prach_fd_occasions; i++) { - fapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &cfg->prach_config.num_prach_fd_occasions_list[i]; - prach_fd_occasion->num_prach_fd_occasions = i; - if (cfg->prach_config.prach_sequence_length) - prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l139; - else - prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l839; + if (rach_ConfigCommon->msg1_SubcarrierSpacing) + cfg->prach_config.prach_sub_c_spacing = *rach_ConfigCommon->msg1_SubcarrierSpacing; + else { + // If absent, the UE applies the SCS as derived from the prach-ConfigurationIndex (for 839) + int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, mac->frame_type); + int format = prach_config_info_p[0]; + cfg->prach_config.prach_sub_c_spacing = format == 3 ? 5 : 4; + } - prach_fd_occasion->k1 = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; - prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig; - prach_fd_occasion->num_root_sequences = compute_nr_root_seq(rach_ConfigCommon, - nb_preambles, - frame_type, - mac->frequency_range); - //prach_fd_occasion->num_unused_root_sequences = ??? + cfg->prach_config.restricted_set_config = rach_ConfigCommon->restrictedSetConfig; + + AssertFatal(rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM < 4, + "msg1 FDM identifier %ld undefined (0,1,2,3)\n", rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM); + cfg->prach_config.num_prach_fd_occasions = 1 << rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM; + + cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *)malloc( + cfg->prach_config.num_prach_fd_occasions * sizeof(fapi_nr_num_prach_fd_occasions_t)); + for (int i = 0; i < cfg->prach_config.num_prach_fd_occasions; i++) { + fapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &cfg->prach_config.num_prach_fd_occasions_list[i]; + prach_fd_occasion->num_prach_fd_occasions = i; + if (cfg->prach_config.prach_sequence_length) + prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l139; + else + prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l839; + + prach_fd_occasion->k1 = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; + prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig; + prach_fd_occasion->num_root_sequences = + compute_nr_root_seq(rach_ConfigCommon, nb_preambles, mac->frame_type, mac->frequency_range); + + cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present - 1; + // prach_fd_occasion->num_unused_root_sequences = ??? + } } +} - cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1; +void release_common_ss_cset(NR_BWP_PDCCH_t *pdcch) +{ + if (pdcch->otherSI_SS) { + ASN_STRUCT_FREE(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS); + pdcch->otherSI_SS = NULL; + } + if (pdcch->ra_SS) { + ASN_STRUCT_FREE(asn_DEF_NR_SearchSpace, pdcch->ra_SS); + pdcch->otherSI_SS = NULL; + } + if (pdcch->paging_SS) { + ASN_STRUCT_FREE(asn_DEF_NR_SearchSpace, pdcch->paging_SS); + pdcch->paging_SS = NULL; + } + if (pdcch->commonControlResourceSet) { + ASN_STRUCT_FREE(asn_DEF_NR_ControlResourceSet, pdcch->commonControlResourceSet); + pdcch->commonControlResourceSet = NULL; + } } +static void modlist_ss(NR_SearchSpace_t *source, NR_SearchSpace_t *target) +{ + target->searchSpaceId = source->searchSpaceId; + if (source->controlResourceSetId) + UPDATE_MAC_IE(target->controlResourceSetId, source->controlResourceSetId, NR_ControlResourceSetId_t); + if (source->monitoringSlotPeriodicityAndOffset) + UPDATE_MAC_IE(target->monitoringSlotPeriodicityAndOffset, + source->monitoringSlotPeriodicityAndOffset, + struct NR_SearchSpace__monitoringSlotPeriodicityAndOffset); + UPDATE_MAC_IE(target->duration, source->duration, long); + if (source->monitoringSymbolsWithinSlot) + UPDATE_MAC_IE(target->monitoringSymbolsWithinSlot, source->monitoringSymbolsWithinSlot, BIT_STRING_t); + if (source->nrofCandidates) + UPDATE_MAC_IE(target->nrofCandidates, source->nrofCandidates, struct NR_SearchSpace__nrofCandidates); + if (source->searchSpaceType) + UPDATE_MAC_IE(target->searchSpaceType, source->searchSpaceType, struct NR_SearchSpace__searchSpaceType); +} -NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList, - const NR_UE_MAC_INST_t *mac, - const NR_SearchSpaceId_t ss_id) +static NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList, + const NR_BWP_PDCCH_t *pdcch, + const NR_SearchSpaceId_t ss_id) { if (ss_id == 0) - return mac->search_space_zero; + return pdcch->search_space_zero; NR_SearchSpace_t *css = NULL; for (int i = 0; i < commonSearchSpaceList->list.count; i++) { if (commonSearchSpaceList->list.array[i]->searchSpaceId == ss_id) { - css = commonSearchSpaceList->list.array[i]; + css = calloc(1, sizeof(*css)); + modlist_ss(commonSearchSpaceList->list.array[i], css); break; } } @@ -476,67 +500,165 @@ NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCommon__co return css; } -void configure_ss_coreset(NR_UE_MAC_INST_t *mac, - const NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon, - const NR_PDCCH_Config_t *pdcch_Config) +static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon) { - - // configuration of search spaces if (pdcch_ConfigCommon) { - mac->otherSI_SS = pdcch_ConfigCommon->searchSpaceOtherSystemInformation ? - get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, mac, - *pdcch_ConfigCommon->searchSpaceOtherSystemInformation) : - NULL; - mac->ra_SS = pdcch_ConfigCommon->ra_SearchSpace ? - get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, mac, - *pdcch_ConfigCommon->ra_SearchSpace) : - NULL; - mac->paging_SS = pdcch_ConfigCommon->pagingSearchSpace ? - get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, mac, - *pdcch_ConfigCommon->pagingSearchSpace) : - NULL; - } - if(pdcch_Config && - pdcch_Config->searchSpacesToAddModList) { - int ss_configured = 0; - struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList = pdcch_Config->searchSpacesToAddModList; - for (int i = 0; i < searchSpacesToAddModList->list.count; i++) { - AssertFatal(ss_configured < FAPI_NR_MAX_SS, "Attempting to configure %d SS but only %d per BWP are allowed", - ss_configured + 1, FAPI_NR_MAX_SS); - mac->BWP_searchspaces[ss_configured] = searchSpacesToAddModList->list.array[i]; - ss_configured++; + ASN_STRUCT_FREE(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS); + pdcch->otherSI_SS = NULL; + if (pdcch_ConfigCommon->searchSpaceOtherSystemInformation) + pdcch->otherSI_SS = get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, + pdcch, + *pdcch_ConfigCommon->searchSpaceOtherSystemInformation); + + ASN_STRUCT_FREE(asn_DEF_NR_SearchSpace, pdcch->ra_SS); + pdcch->ra_SS = NULL; + if (pdcch_ConfigCommon->ra_SearchSpace) { + if (pdcch->otherSI_SS && *pdcch_ConfigCommon->ra_SearchSpace == pdcch->otherSI_SS->searchSpaceId) + pdcch->ra_SS = pdcch->otherSI_SS; + else + pdcch->ra_SS = + get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->ra_SearchSpace); + } + + ASN_STRUCT_FREE(asn_DEF_NR_SearchSpace, pdcch->paging_SS); + pdcch->paging_SS = NULL; + if (pdcch_ConfigCommon->pagingSearchSpace) { + if (pdcch->otherSI_SS && *pdcch_ConfigCommon->pagingSearchSpace == pdcch->otherSI_SS->searchSpaceId) + pdcch->paging_SS = pdcch->otherSI_SS; + else if (pdcch->ra_SS && *pdcch_ConfigCommon->pagingSearchSpace == pdcch->ra_SS->searchSpaceId) + pdcch->paging_SS = pdcch->ra_SS; + if (!pdcch->paging_SS) + pdcch->paging_SS = + get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->pagingSearchSpace); } - for (int i = ss_configured; i < FAPI_NR_MAX_SS; i++) - mac->BWP_searchspaces[i] = NULL; - } - - // configuration of coresets - int cset_configured = 0; - int common_cset_id = -1; - if (pdcch_ConfigCommon && - pdcch_ConfigCommon->commonControlResourceSet) { - mac->BWP_coresets[cset_configured] = pdcch_ConfigCommon->commonControlResourceSet; - common_cset_id = pdcch_ConfigCommon->commonControlResourceSet->controlResourceSetId; - cset_configured++; - } - if(pdcch_Config && - pdcch_Config->controlResourceSetToAddModList) { - struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList = pdcch_Config->controlResourceSetToAddModList; - for (int i = 0; i < controlResourceSetToAddModList->list.count; i++) { - AssertFatal(cset_configured < FAPI_NR_MAX_CORESET_PER_BWP, "Attempting to configure %d CORESET but only %d per BWP are allowed", - cset_configured + 1, FAPI_NR_MAX_CORESET_PER_BWP); - // In case network reconfigures control resource set with the same ControlResourceSetId as used for commonControlResourceSet - // configured via PDCCH-ConfigCommon, the configuration from PDCCH-Config always takes precedence - if (controlResourceSetToAddModList->list.array[i]->controlResourceSetId == common_cset_id) - mac->BWP_coresets[0] = controlResourceSetToAddModList->list.array[i]; - else { - mac->BWP_coresets[cset_configured] = controlResourceSetToAddModList->list.array[i]; - cset_configured++; + + UPDATE_MAC_IE(pdcch->commonControlResourceSet, pdcch_ConfigCommon->commonControlResourceSet, NR_ControlResourceSet_t); + } +} + +static void modlist_coreset(NR_ControlResourceSet_t *source, NR_ControlResourceSet_t *target) +{ + target->controlResourceSetId = source->controlResourceSetId; + target->frequencyDomainResources.size = source->frequencyDomainResources.size; + if (!target->frequencyDomainResources.buf) + target->frequencyDomainResources.buf = + calloc(target->frequencyDomainResources.size, sizeof(*target->frequencyDomainResources.buf)); + for (int i = 0; i < source->frequencyDomainResources.size; i++) + target->frequencyDomainResources.buf[i] = source->frequencyDomainResources.buf[i]; + target->duration = source->duration; + target->precoderGranularity = source->precoderGranularity; + long *shiftIndex = NULL; + if (target->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved) + shiftIndex = target->cce_REG_MappingType.choice.interleaved->shiftIndex; + if (source->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved) { + target->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; + target->cce_REG_MappingType.choice.interleaved->reg_BundleSize = source->cce_REG_MappingType.choice.interleaved->reg_BundleSize; + target->cce_REG_MappingType.choice.interleaved->interleaverSize = + source->cce_REG_MappingType.choice.interleaved->interleaverSize; + UPDATE_MAC_IE(target->cce_REG_MappingType.choice.interleaved->shiftIndex, + source->cce_REG_MappingType.choice.interleaved->shiftIndex, + long); + } else { + free(shiftIndex); + target->cce_REG_MappingType = source->cce_REG_MappingType; + } + UPDATE_MAC_IE(target->tci_PresentInDCI, source->tci_PresentInDCI, long); + UPDATE_MAC_IE(target->pdcch_DMRS_ScramblingID, source->pdcch_DMRS_ScramblingID, long); + // TCI States + if (source->tci_StatesPDCCH_ToReleaseList) { + for (int i = 0; i < source->tci_StatesPDCCH_ToReleaseList->list.count; i++) { + long id = *source->tci_StatesPDCCH_ToReleaseList->list.array[i]; + int j; + for (j = 0; j < target->tci_StatesPDCCH_ToAddList->list.count; j++) { + if (id == *target->tci_StatesPDCCH_ToAddList->list.array[j]) + break; + } + if (j < target->tci_StatesPDCCH_ToAddList->list.count) + asn_sequence_del(&target->tci_StatesPDCCH_ToAddList->list, j, 1); + else + LOG_E(NR_MAC, "Element not present in the list, impossible to release\n"); + } + } + if (source->tci_StatesPDCCH_ToAddList) { + if (target->tci_StatesPDCCH_ToAddList) { + for (int i = 0; i < source->tci_StatesPDCCH_ToAddList->list.count; i++) { + long id = *source->tci_StatesPDCCH_ToAddList->list.array[i]; + int j; + for (j = 0; j < target->tci_StatesPDCCH_ToAddList->list.count; j++) { + if (id == *target->tci_StatesPDCCH_ToAddList->list.array[j]) + break; + } + if (j == target->tci_StatesPDCCH_ToAddList->list.count) + ASN_SEQUENCE_ADD(&target->tci_StatesPDCCH_ToAddList->list, source->tci_StatesPDCCH_ToAddList->list.array[i]); + } + } else + UPDATE_MAC_IE(target->tci_StatesPDCCH_ToAddList, + source->tci_StatesPDCCH_ToAddList, + struct NR_ControlResourceSet__tci_StatesPDCCH_ToAddList); + } + // end TCI States +} + +static void configure_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_Config_t *pdcch_Config) +{ + if (!pdcch_Config) + return; + if (pdcch_Config->controlResourceSetToAddModList) { + for (int i = 0; i < pdcch_Config->controlResourceSetToAddModList->list.count; i++) { + NR_ControlResourceSet_t *source_coreset = pdcch_Config->controlResourceSetToAddModList->list.array[i]; + NR_ControlResourceSet_t *target_coreset = NULL; + for (int j = 0; j < pdcch->list_Coreset.count; j++) { + if (pdcch->list_Coreset.array[j]->controlResourceSetId == source_coreset->controlResourceSetId) { + target_coreset = pdcch->list_Coreset.array[j]; + break; + } + } + if (!target_coreset) { + target_coreset = calloc(1, sizeof(*target_coreset)); + ASN_SEQUENCE_ADD(&pdcch->list_Coreset, target_coreset); + } + modlist_coreset(source_coreset, target_coreset); + } + } + if (pdcch_Config->controlResourceSetToReleaseList) { + for (int i = 0; i < pdcch_Config->controlResourceSetToReleaseList->list.count; i++) { + NR_ControlResourceSetId_t id = *pdcch_Config->controlResourceSetToReleaseList->list.array[i]; + for (int j = 0; j < pdcch->list_Coreset.count; j++) { + if (id == pdcch->list_Coreset.array[j]->controlResourceSetId) { + asn_sequence_del(&pdcch->list_Coreset, j, 1); + break; + } + } + } + } + if (pdcch_Config->searchSpacesToAddModList) { + for (int i = 0; i < pdcch_Config->searchSpacesToAddModList->list.count; i++) { + NR_SearchSpace_t *source_ss = pdcch_Config->searchSpacesToAddModList->list.array[i]; + NR_SearchSpace_t *target_ss = NULL; + for (int j = 0; j < pdcch->list_SS.count; j++) { + if (pdcch->list_SS.array[j]->searchSpaceId == source_ss->searchSpaceId) { + target_ss = pdcch->list_SS.array[j]; + break; + } + } + if (!target_ss) { + target_ss = calloc(1, sizeof(*target_ss)); + ASN_SEQUENCE_ADD(&pdcch->list_SS, target_ss); + } + modlist_ss(source_ss, target_ss); + } + } + if (pdcch_Config->searchSpacesToReleaseList) { + for (int i = 0; i < pdcch_Config->searchSpacesToReleaseList->list.count; i++) { + NR_ControlResourceSetId_t id = *pdcch_Config->searchSpacesToReleaseList->list.array[i]; + for (int j = 0; j < pdcch->list_SS.count; j++) { + if (id == pdcch->list_SS.array[j]->searchSpaceId) { + asn_sequence_del(&pdcch->list_SS, j, 1); + break; + } } } } - for (int i = cset_configured; i < FAPI_NR_MAX_CORESET_PER_BWP; i++) - mac->BWP_coresets[i] = NULL; } static int lcid_cmp(const void *lc1, const void *lc2, void *mac_inst) @@ -557,8 +679,8 @@ void nr_release_mac_config_logicalChannelBearer(module_id_t module_id, long chan { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); if (mac->logicalChannelConfig[channel_identity - 1] != NULL) { + ASN_STRUCT_FREE(asn_DEF_NR_LogicalChannelConfig, mac->logicalChannelConfig[channel_identity - 1]); mac->logicalChannelConfig[channel_identity - 1] = NULL; - memset(&mac->scheduling_info.lc_sched_info[channel_identity - 1], 0, sizeof(NR_LC_SCHEDULING_INFO)); } else { LOG_E(NR_MAC, "Trying to release a non configured logical channel bearer %li\n", channel_identity); } @@ -637,7 +759,7 @@ void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i]; int lc_identity = rlc_bearer->logicalChannelIdentity; mac->lc_ordered_info[i].lcids_ordered = lc_identity; - NR_LogicalChannelConfig_t *mac_lc_config; + NR_LogicalChannelConfig_t *mac_lc_config = NULL; if (mac->logicalChannelConfig[lc_identity - 1] == NULL) { /* setup of new LCID*/ LOG_D(NR_MAC, "Establishing the logical channel %d\n", lc_identity); @@ -645,7 +767,7 @@ void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */ NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; if (rlc_bearer->mac_LogicalChannelConfig != NULL) { - mac_lc_config = rlc_bearer->mac_LogicalChannelConfig; + UPDATE_MAC_IE(mac_lc_config, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t); } else { LOG_I(NR_RRC, "Applying the default logicalChannelConfig for SRB\n"); if (srb_id == 1) @@ -658,21 +780,21 @@ void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, AssertFatal(1 == 0, "The logical id %d is not a valid SRB id %li\n", lc_identity, srb_id); } } else { /* DRB */ - mac_lc_config = rlc_bearer->mac_LogicalChannelConfig; - AssertFatal(mac_lc_config != NULL, "For DRB, it should be mandatorily present\n"); + AssertFatal(rlc_bearer->mac_LogicalChannelConfig, + "When establishing a DRB, LogicalChannelConfig should be mandatorily present\n"); + UPDATE_MAC_IE(mac_lc_config, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t); } } else { /* LC is already established, reconfiguring the LC */ LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity); if (rlc_bearer->mac_LogicalChannelConfig != NULL) { - mac_lc_config = rlc_bearer->mac_LogicalChannelConfig; - } else { - /* Need M - Maintains current value */ - continue; + UPDATE_MAC_IE(mac_lc_config, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t); } } - mac->lc_ordered_info[i].logicalChannelConfig_ordered = mac_lc_config; - nr_configure_mac_config_logicalChannelBearer(module_id, lc_identity, mac_lc_config); + if (mac_lc_config) { + mac->lc_ordered_info[i].logicalChannelConfig_ordered = mac_lc_config; + nr_configure_mac_config_logicalChannelBearer(module_id, lc_identity, mac_lc_config); + } } // reorder the logical channels as per its priority @@ -680,169 +802,6 @@ void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, } } -void configure_scc(NR_UE_MAC_INST_t *mac, - NR_ServingCellConfigCommonSIB_t *scc_sib, - NR_ServingCellConfigCommon_t *scc) -{ - // SCC is provided when receiving reconfigurationWithSync - // SCC_SIB is provided when receiving SIB1 - // So never at the same time - if (scc) { - if (scc->physCellId) - mac->physCellId = *scc->physCellId; - mac->bwp_dlcommon = scc->downlinkConfigCommon->initialDownlinkBWP; - mac->bwp_ulcommon = scc->uplinkConfigCommon->initialUplinkBWP; - mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position; - mac->tdd_UL_DL_ConfigurationCommon = scc->tdd_UL_DL_ConfigurationCommon; - mac->p_Max = scc->uplinkConfigCommon->frequencyInfoUL->p_Max ? - *scc->uplinkConfigCommon->frequencyInfoUL->p_Max : - INT_MIN; - mac->nr_band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - } - if (scc_sib) { - mac->bwp_dlcommon = &scc_sib->downlinkConfigCommon.initialDownlinkBWP; - mac->bwp_ulcommon = &scc_sib->uplinkConfigCommon->initialUplinkBWP; - mac->tdd_UL_DL_ConfigurationCommon = scc_sib->tdd_UL_DL_ConfigurationCommon; - mac->p_Max = scc_sib->uplinkConfigCommon->frequencyInfoUL.p_Max ? - *scc_sib->uplinkConfigCommon->frequencyInfoUL.p_Max : - INT_MIN; - mac->nr_band = *scc_sib->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR; - } -} - -void configure_current_BWP(NR_UE_MAC_INST_t *mac, - NR_ServingCellConfigCommonSIB_t *scc, - const NR_ServingCellConfig_t *spCellConfigDedicated) -{ - NR_UE_DL_BWP_t *DL_BWP = &mac->current_DL_BWP; - NR_UE_UL_BWP_t *UL_BWP = &mac->current_UL_BWP; - NR_BWP_t dl_genericParameters = {0}; - NR_BWP_t ul_genericParameters = {0}; - - if(scc) { - dl_genericParameters = mac->bwp_dlcommon->genericParameters; - if(mac->bwp_ulcommon) - ul_genericParameters = mac->bwp_ulcommon->genericParameters; - else - ul_genericParameters = mac->bwp_dlcommon->genericParameters; - - if (mac->bwp_dlcommon->pdsch_ConfigCommon) - DL_BWP->tdaList_Common = mac->bwp_dlcommon->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - if (mac->bwp_ulcommon->pusch_ConfigCommon) { - UL_BWP->tdaList_Common = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - UL_BWP->msg3_DeltaPreamble = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble; - } - if (mac->bwp_ulcommon->pucch_ConfigCommon) - UL_BWP->pucch_ConfigCommon = mac->bwp_ulcommon->pucch_ConfigCommon->choice.setup; - if (mac->bwp_ulcommon->rach_ConfigCommon) { - UL_BWP->rach_ConfigCommon = mac->bwp_ulcommon->rach_ConfigCommon->choice.setup; - // Setup the SSB to Rach Occasions mapping according to the config - build_ssb_to_ro_map(mac); - } - if (mac->bwp_dlcommon->pdcch_ConfigCommon) - configure_ss_coreset(mac, mac->bwp_dlcommon->pdcch_ConfigCommon->choice.setup, NULL); - } - - if(spCellConfigDedicated) { - UL_BWP->supplementaryUplink = spCellConfigDedicated->supplementaryUplink; - UL_BWP->csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig ? spCellConfigDedicated->csi_MeasConfig->choice.setup : NULL; - UL_BWP->pusch_servingcellconfig = - spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig ? spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL; - DL_BWP->pdsch_servingcellconfig = spCellConfigDedicated->pdsch_ServingCellConfig ? spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup : NULL; - - if (spCellConfigDedicated->firstActiveDownlinkBWP_Id) - DL_BWP->bwp_id = *spCellConfigDedicated->firstActiveDownlinkBWP_Id; - if (spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) - UL_BWP->bwp_id = *spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; - - NR_BWP_Downlink_t *bwp_downlink = NULL; - const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = spCellConfigDedicated->downlinkBWP_ToAddModList; - if (bwpList) - DL_BWP->n_dl_bwp = bwpList->list.count; - if (bwpList && DL_BWP->bwp_id > 0) { - for (int i = 0; i < bwpList->list.count; i++) { - bwp_downlink = bwpList->list.array[i]; - if(bwp_downlink->bwp_Id == DL_BWP->bwp_id) - break; - } - AssertFatal(bwp_downlink != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", DL_BWP->bwp_id); - dl_genericParameters = bwp_downlink->bwp_Common->genericParameters; - DL_BWP->pdsch_Config = bwp_downlink->bwp_Dedicated->pdsch_Config->choice.setup; - DL_BWP->tdaList_Common = bwp_downlink->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - configure_ss_coreset(mac, - bwp_downlink->bwp_Common->pdcch_ConfigCommon ? bwp_downlink->bwp_Common->pdcch_ConfigCommon->choice.setup : NULL, - bwp_downlink->bwp_Dedicated->pdcch_Config ? bwp_downlink->bwp_Dedicated->pdcch_Config->choice.setup : NULL); - - } - else { - dl_genericParameters = mac->bwp_dlcommon->genericParameters; - DL_BWP->pdsch_Config = spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup; - DL_BWP->tdaList_Common = mac->bwp_dlcommon->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - configure_ss_coreset(mac, - mac->bwp_dlcommon->pdcch_ConfigCommon ? mac->bwp_dlcommon->pdcch_ConfigCommon->choice.setup : NULL, - spCellConfigDedicated->initialDownlinkBWP->pdcch_Config ? spCellConfigDedicated->initialDownlinkBWP->pdcch_Config->choice.setup : NULL); - } - - UL_BWP->msg3_DeltaPreamble = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble; - - NR_BWP_Uplink_t *bwp_uplink = NULL; - const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList; - if (ubwpList) - UL_BWP->n_ul_bwp = ubwpList->list.count; - if (ubwpList && UL_BWP->bwp_id > 0) { - for (int i = 0; i < ubwpList->list.count; i++) { - bwp_uplink = ubwpList->list.array[i]; - if(bwp_uplink->bwp_Id == UL_BWP->bwp_id) - break; - } - AssertFatal(bwp_uplink != NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id); - ul_genericParameters = bwp_uplink->bwp_Common->genericParameters; - UL_BWP->tdaList_Common = bwp_uplink->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - UL_BWP->pusch_Config = bwp_uplink->bwp_Dedicated->pusch_Config->choice.setup; - UL_BWP->pucch_Config = bwp_uplink->bwp_Dedicated->pucch_Config->choice.setup; - UL_BWP->srs_Config = bwp_uplink->bwp_Dedicated->srs_Config->choice.setup; - UL_BWP->configuredGrantConfig = bwp_uplink->bwp_Dedicated->configuredGrantConfig ? bwp_uplink->bwp_Dedicated->configuredGrantConfig->choice.setup : NULL; - if (bwp_uplink->bwp_Common->pucch_ConfigCommon) - UL_BWP->pucch_ConfigCommon = bwp_uplink->bwp_Common->pucch_ConfigCommon->choice.setup; - if (bwp_uplink->bwp_Common->rach_ConfigCommon) { - UL_BWP->rach_ConfigCommon = bwp_uplink->bwp_Common->rach_ConfigCommon->choice.setup; - // Setup the SSB to Rach Occasions mapping according to the config - build_ssb_to_ro_map(mac); - } - } - else { - UL_BWP->tdaList_Common = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - UL_BWP->pusch_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup; - UL_BWP->pucch_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - UL_BWP->srs_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; - UL_BWP->configuredGrantConfig = - spCellConfigDedicated->uplinkConfig->initialUplinkBWP->configuredGrantConfig ? spCellConfigDedicated->uplinkConfig->initialUplinkBWP->configuredGrantConfig->choice.setup : NULL; - ul_genericParameters = mac->bwp_ulcommon->genericParameters; - if (mac->bwp_ulcommon->pucch_ConfigCommon) - UL_BWP->pucch_ConfigCommon = mac->bwp_ulcommon->pucch_ConfigCommon->choice.setup; - if (mac->bwp_ulcommon->rach_ConfigCommon) - UL_BWP->rach_ConfigCommon = mac->bwp_ulcommon->rach_ConfigCommon->choice.setup; - } - } - - DL_BWP->scs = dl_genericParameters.subcarrierSpacing; - DL_BWP->cyclicprefix = dl_genericParameters.cyclicPrefix; - DL_BWP->BWPSize = NRRIV2BW(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - DL_BWP->BWPStart = NRRIV2PRBOFFSET(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - UL_BWP->scs = ul_genericParameters.subcarrierSpacing; - UL_BWP->cyclicprefix = ul_genericParameters.cyclicPrefix; - UL_BWP->BWPSize = NRRIV2BW(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - UL_BWP->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - - DL_BWP->initial_BWPSize = NRRIV2BW(mac->bwp_dlcommon->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - UL_BWP->initial_BWPSize = NRRIV2BW(mac->bwp_ulcommon->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - DL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(mac->bwp_dlcommon->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - UL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(mac->bwp_ulcommon->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - - DL_BWP->bw_tbslbrm = get_dlbw_tbslbrm(DL_BWP->initial_BWPSize, spCellConfigDedicated); - UL_BWP->bw_tbslbrm = get_ulbw_tbslbrm(UL_BWP->initial_BWPSize, spCellConfigDedicated); -} - void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs) { int slots_per_frame = nr_slots_per_frame[scs]; @@ -872,6 +831,526 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, cc_idP); } +static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target) +{ + UPDATE_MAC_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); + UPDATE_MAC_IE(target->msg3_Alpha, source->msg3_Alpha, NR_Alpha_t); + if (source->p0_NominalWithoutGrant) + UPDATE_MAC_IE(target->p0_NominalWithoutGrant, source->p0_NominalWithoutGrant, long); + if (source->p0_AlphaSets) + UPDATE_MAC_IE(target->p0_AlphaSets, source->p0_AlphaSets, struct NR_PUSCH_PowerControl__p0_AlphaSets); + UPDATE_MAC_IE(target->twoPUSCH_PC_AdjustmentStates, source->twoPUSCH_PC_AdjustmentStates, long); + UPDATE_MAC_IE(target->deltaMCS, source->deltaMCS, long); + if (source->pathlossReferenceRSToReleaseList) { + RELEASE_IE_FROMLIST(source->pathlossReferenceRSToReleaseList, + target->pathlossReferenceRSToAddModList, + pusch_PathlossReferenceRS_Id); + } + if (source->pathlossReferenceRSToAddModList) { + if (!target->pathlossReferenceRSToAddModList) + target->pathlossReferenceRSToAddModList = calloc(1, sizeof(*target->pathlossReferenceRSToAddModList)); + ADDMOD_IE_FROMLIST(source->pathlossReferenceRSToAddModList, + target->pathlossReferenceRSToAddModList, + pusch_PathlossReferenceRS_Id, + NR_PUSCH_PathlossReferenceRS_t); + } + if (source->sri_PUSCH_MappingToReleaseList) { + RELEASE_IE_FROMLIST(source->sri_PUSCH_MappingToReleaseList, + target->sri_PUSCH_MappingToAddModList, + sri_PUSCH_PowerControlId); + } + if (source->sri_PUSCH_MappingToAddModList) { + if (!target->sri_PUSCH_MappingToAddModList) + target->sri_PUSCH_MappingToAddModList = calloc(1, sizeof(*target->sri_PUSCH_MappingToAddModList)); + ADDMOD_IE_FROMLIST(source->sri_PUSCH_MappingToAddModList, + target->sri_PUSCH_MappingToAddModList, + sri_PUSCH_PowerControlId, + NR_SRI_PUSCH_PowerControl_t); + } +} + +static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target) +{ + UPDATE_MAC_IE(target->dataScramblingIdentityPUSCH, source->dataScramblingIdentityPUSCH, long); + UPDATE_MAC_IE(target->txConfig, source->txConfig, long); + if (source->dmrs_UplinkForPUSCH_MappingTypeA) + HANDLE_SETUPRELEASE_IE(target->dmrs_UplinkForPUSCH_MappingTypeA, + source->dmrs_UplinkForPUSCH_MappingTypeA, + NR_DMRS_UplinkConfig_t, + asn_DEF_NR_SetupRelease_DMRS_UplinkConfig); + if (source->dmrs_UplinkForPUSCH_MappingTypeB) + HANDLE_SETUPRELEASE_IE(target->dmrs_UplinkForPUSCH_MappingTypeB, + source->dmrs_UplinkForPUSCH_MappingTypeB, + NR_DMRS_UplinkConfig_t, + asn_DEF_NR_SetupRelease_DMRS_UplinkConfig); + if (source->pusch_PowerControl) { + if (!target->pusch_PowerControl) + target->pusch_PowerControl = calloc(1, sizeof(*target->pusch_PowerControl)); + setup_puschpowercontrol(source->pusch_PowerControl, target->pusch_PowerControl); + } + UPDATE_MAC_IE(target->frequencyHopping, source->frequencyHopping, long); + if (source->frequencyHoppingOffsetLists) + UPDATE_MAC_IE(target->frequencyHoppingOffsetLists, + source->frequencyHoppingOffsetLists, + struct NR_PUSCH_Config__frequencyHoppingOffsetLists); + target->resourceAllocation = source->resourceAllocation; + if (source->pusch_TimeDomainAllocationList) + HANDLE_SETUPRELEASE_IE(target->pusch_TimeDomainAllocationList, + source->pusch_TimeDomainAllocationList, + NR_PUSCH_TimeDomainResourceAllocationList_t, + asn_DEF_NR_SetupRelease_PUSCH_TimeDomainResourceAllocationList); + UPDATE_MAC_IE(target->pusch_AggregationFactor, source->pusch_AggregationFactor, long); + UPDATE_MAC_IE(target->mcs_Table, source->mcs_Table, long); + UPDATE_MAC_IE(target->mcs_TableTransformPrecoder, source->mcs_TableTransformPrecoder, long); + UPDATE_MAC_IE(target->transformPrecoder, source->transformPrecoder, long); + UPDATE_MAC_IE(target->codebookSubset, source->codebookSubset, long); + UPDATE_MAC_IE(target->maxRank, source->maxRank, long); + UPDATE_MAC_IE(target->rbg_Size, source->rbg_Size, long); + UPDATE_MAC_IE(target->tp_pi2BPSK, source->tp_pi2BPSK, long); + if (source->uci_OnPUSCH) { + if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_UCI_OnPUSCH, target->uci_OnPUSCH); + target->uci_OnPUSCH = NULL; + } + if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_setup) { + if (target->uci_OnPUSCH) { + target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling; + if (source->uci_OnPUSCH->choice.setup->betaOffsets) + UPDATE_MAC_IE(target->uci_OnPUSCH->choice.setup->betaOffsets, + source->uci_OnPUSCH->choice.setup->betaOffsets, + struct NR_UCI_OnPUSCH__betaOffsets); + } + } + } +} + +static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *target) +{ + UPDATE_MAC_IE(target->dataScramblingIdentityPDSCH, source->dataScramblingIdentityPDSCH, long); + if (source->dmrs_DownlinkForPDSCH_MappingTypeA) + HANDLE_SETUPRELEASE_IE(target->dmrs_DownlinkForPDSCH_MappingTypeA, + source->dmrs_DownlinkForPDSCH_MappingTypeA, + NR_DMRS_DownlinkConfig_t, + asn_DEF_NR_SetupRelease_DMRS_DownlinkConfig); + if (source->dmrs_DownlinkForPDSCH_MappingTypeB) + HANDLE_SETUPRELEASE_IE(target->dmrs_DownlinkForPDSCH_MappingTypeB, + source->dmrs_DownlinkForPDSCH_MappingTypeB, + NR_DMRS_DownlinkConfig_t, + asn_DEF_NR_SetupRelease_DMRS_DownlinkConfig); + // TCI States + if (source->tci_StatesToReleaseList) { + RELEASE_IE_FROMLIST(source->tci_StatesToReleaseList, + target->tci_StatesToAddModList, + tci_StateId); + } + if (source->tci_StatesToAddModList) { + if (!target->tci_StatesToAddModList) + target->tci_StatesToAddModList = calloc(1, sizeof(*target->tci_StatesToAddModList)); + ADDMOD_IE_FROMLIST(source->tci_StatesToAddModList, + target->tci_StatesToAddModList, + tci_StateId, + NR_TCI_State_t); + } + // end TCI States + UPDATE_MAC_IE(target->vrb_ToPRB_Interleaver, source->vrb_ToPRB_Interleaver, long); + target->resourceAllocation = source->resourceAllocation; + if (source->pdsch_TimeDomainAllocationList) + HANDLE_SETUPRELEASE_IE(target->pdsch_TimeDomainAllocationList, + source->pdsch_TimeDomainAllocationList, + NR_PDSCH_TimeDomainResourceAllocationList_t, + asn_DEF_NR_SetupRelease_PDSCH_TimeDomainResourceAllocationList); + UPDATE_MAC_IE(target->pdsch_AggregationFactor, source->pdsch_AggregationFactor, long); + // rateMatchPattern + if (source->rateMatchPatternToReleaseList) { + RELEASE_IE_FROMLIST(source->rateMatchPatternToReleaseList, + target->rateMatchPatternToAddModList, + rateMatchPatternId); + } + if (source->rateMatchPatternToAddModList) { + if (!target->rateMatchPatternToAddModList) + target->rateMatchPatternToAddModList = calloc(1, sizeof(*target->rateMatchPatternToAddModList)); + ADDMOD_IE_FROMLIST(source->rateMatchPatternToAddModList, + target->rateMatchPatternToAddModList, + rateMatchPatternId, + NR_RateMatchPattern_t); + } + // end rateMatchPattern + UPDATE_MAC_IE(target->rateMatchPatternGroup1, source->rateMatchPatternGroup1, NR_RateMatchPatternGroup_t); + UPDATE_MAC_IE(target->rateMatchPatternGroup2, source->rateMatchPatternGroup2, NR_RateMatchPatternGroup_t); + target->rbg_Size = source->rbg_Size; + UPDATE_MAC_IE(target->mcs_Table, source->mcs_Table, long); + UPDATE_MAC_IE(target->maxNrofCodeWordsScheduledByDCI, source->maxNrofCodeWordsScheduledByDCI, long); + target->prb_BundlingType = source->prb_BundlingType; + AssertFatal(source->zp_CSI_RS_ResourceToAddModList == NULL, "Not handled\n"); + AssertFatal(source->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList == NULL, "Not handled\n"); + AssertFatal(source->sp_ZP_CSI_RS_ResourceSetsToAddModList == NULL, "Not handled\n"); +} + +static void setup_sr_resource(NR_SchedulingRequestResourceConfig_t *target, NR_SchedulingRequestResourceConfig_t *source) +{ + target->schedulingRequestResourceId = source->schedulingRequestResourceId; + target->schedulingRequestID = source->schedulingRequestID; + if (source->periodicityAndOffset) + UPDATE_MAC_IE(target->periodicityAndOffset, + source->periodicityAndOffset, + struct NR_SchedulingRequestResourceConfig__periodicityAndOffset); + if (source->resource) + UPDATE_MAC_IE(target->resource, source->resource, NR_PUCCH_ResourceId_t); +} + +static void setup_pucchconfig(NR_PUCCH_Config_t *source, NR_PUCCH_Config_t *target) +{ + // PUCCH-ResourceSet + if (source->resourceSetToAddModList) { + if (!target->resourceSetToAddModList) + target->resourceSetToAddModList = calloc(1, sizeof(*target->resourceSetToAddModList)); + ADDMOD_IE_FROMLIST(source->resourceSetToAddModList, + target->resourceSetToAddModList, + pucch_ResourceSetId, + NR_PUCCH_ResourceSet_t); + } + if (source->resourceSetToReleaseList) { + RELEASE_IE_FROMLIST(source->resourceSetToReleaseList, + target->resourceSetToAddModList, + pucch_ResourceSetId); + } + // PUCCH-Resource + if (source->resourceToAddModList) { + if (!target->resourceToAddModList) + target->resourceToAddModList = calloc(1, sizeof(*target->resourceToAddModList)); + ADDMOD_IE_FROMLIST(source->resourceToAddModList, + target->resourceToAddModList, + pucch_ResourceId, + NR_PUCCH_Resource_t); + } + if (source->resourceToReleaseList) { + RELEASE_IE_FROMLIST(source->resourceToReleaseList, + target->resourceToAddModList, + pucch_ResourceId); + } + // PUCCH-FormatConfig + if (source->format1) + HANDLE_SETUPRELEASE_IE(target->format1, + source->format1, + NR_PUCCH_FormatConfig_t, + asn_DEF_NR_SetupRelease_PUCCH_FormatConfig); + if (source->format2) + HANDLE_SETUPRELEASE_IE(target->format2, + source->format2, + NR_PUCCH_FormatConfig_t, + asn_DEF_NR_SetupRelease_PUCCH_FormatConfig); + if (source->format3) + HANDLE_SETUPRELEASE_IE(target->format3, + source->format3, + NR_PUCCH_FormatConfig_t, + asn_DEF_NR_SetupRelease_PUCCH_FormatConfig); + if (source->format4) + HANDLE_SETUPRELEASE_IE(target->format4, + source->format4, + NR_PUCCH_FormatConfig_t, + asn_DEF_NR_SetupRelease_PUCCH_FormatConfig); + // SchedulingRequestResourceConfig + if (source->schedulingRequestResourceToAddModList) { + if (!target->schedulingRequestResourceToAddModList) + target->schedulingRequestResourceToAddModList = calloc(1, sizeof(*target->schedulingRequestResourceToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(source->schedulingRequestResourceToAddModList, + target->schedulingRequestResourceToAddModList, + schedulingRequestResourceId, + NR_SchedulingRequestResourceConfig_t, + setup_sr_resource); + } + if (source->schedulingRequestResourceToReleaseList) { + RELEASE_IE_FROMLIST(source->schedulingRequestResourceToReleaseList, + target->schedulingRequestResourceToAddModList, + schedulingRequestResourceId); + } + + if (source->multi_CSI_PUCCH_ResourceList) + UPDATE_MAC_IE(target->multi_CSI_PUCCH_ResourceList, + source->multi_CSI_PUCCH_ResourceList, + struct NR_PUCCH_Config__multi_CSI_PUCCH_ResourceList); + if (source->dl_DataToUL_ACK) + UPDATE_MAC_IE(target->dl_DataToUL_ACK, source->dl_DataToUL_ACK, struct NR_PUCCH_Config__dl_DataToUL_ACK); + // PUCCH-SpatialRelationInfo + if (source->spatialRelationInfoToAddModList) { + if (!target->spatialRelationInfoToAddModList) + target->spatialRelationInfoToAddModList = calloc(1, sizeof(*target->spatialRelationInfoToAddModList)); + ADDMOD_IE_FROMLIST(source->spatialRelationInfoToAddModList, + target->spatialRelationInfoToAddModList, + pucch_SpatialRelationInfoId, + NR_PUCCH_SpatialRelationInfo_t); + } + if (source->spatialRelationInfoToReleaseList) { + RELEASE_IE_FROMLIST(source->spatialRelationInfoToReleaseList, + target->spatialRelationInfoToAddModList, + pucch_SpatialRelationInfoId); + } + + if (source->pucch_PowerControl) { + if (!target->pucch_PowerControl) + target->pucch_PowerControl = calloc(1, sizeof(*target->pucch_PowerControl)); + UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f0, source->pucch_PowerControl->deltaF_PUCCH_f0, long); + UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f1, source->pucch_PowerControl->deltaF_PUCCH_f1, long); + UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f2, source->pucch_PowerControl->deltaF_PUCCH_f2, long); + UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f3, source->pucch_PowerControl->deltaF_PUCCH_f3, long); + UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f4, source->pucch_PowerControl->deltaF_PUCCH_f4, long); + if (source->pucch_PowerControl->p0_Set) + UPDATE_MAC_IE(target->pucch_PowerControl->p0_Set, source->pucch_PowerControl->p0_Set, struct NR_PUCCH_PowerControl__p0_Set); + if (source->pucch_PowerControl->pathlossReferenceRSs) + UPDATE_MAC_IE(target->pucch_PowerControl->pathlossReferenceRSs, + source->pucch_PowerControl->pathlossReferenceRSs, + struct NR_PUCCH_PowerControl__pathlossReferenceRSs); + UPDATE_MAC_IE(target->pucch_PowerControl->twoPUCCH_PC_AdjustmentStates, + source->pucch_PowerControl->twoPUCCH_PC_AdjustmentStates, + long); + } +} + +static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source) +{ + target->srs_ResourceSetId = source->srs_ResourceSetId; + if (source->srs_ResourceIdList) + UPDATE_MAC_IE(target->srs_ResourceIdList, source->srs_ResourceIdList, struct NR_SRS_ResourceSet__srs_ResourceIdList); + target->resourceType = source->resourceType; + target->usage = source->usage; + UPDATE_MAC_IE(target->alpha, source->alpha, NR_Alpha_t); + if (source->p0) + UPDATE_MAC_IE(target->p0, source->p0, long); + if (source->pathlossReferenceRS) + UPDATE_MAC_IE(target->pathlossReferenceRS, source->pathlossReferenceRS, struct NR_PathlossReferenceRS_Config); + UPDATE_MAC_IE(target->srs_PowerControlAdjustmentStates, source->srs_PowerControlAdjustmentStates, long); +} + +static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target) +{ + UPDATE_MAC_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); + // SRS-Resource + if (source->srs_ResourceToAddModList) { + if (!target->srs_ResourceToAddModList) + target->srs_ResourceToAddModList = calloc(1, sizeof(*target->srs_ResourceToAddModList)); + ADDMOD_IE_FROMLIST(source->srs_ResourceToAddModList, + target->srs_ResourceToAddModList, + srs_ResourceId, + NR_SRS_Resource_t); + } + if (source->srs_ResourceToReleaseList) { + RELEASE_IE_FROMLIST(source->srs_ResourceToReleaseList, + target->srs_ResourceToAddModList, + srs_ResourceId); + } + // SRS-ResourceSet + if (source->srs_ResourceSetToAddModList) { + if (!target->srs_ResourceSetToAddModList) + target->srs_ResourceSetToAddModList = calloc(1, sizeof(*target->srs_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(source->srs_ResourceSetToAddModList, + target->srs_ResourceSetToAddModList, + srs_ResourceSetId, + NR_SRS_ResourceSet_t, + setup_srsresourceset); + } + if (source->srs_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(source->srs_ResourceSetToReleaseList, + target->srs_ResourceSetToAddModList, + srs_ResourceSetId); + } +} + +static NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) +{ + NR_UE_DL_BWP_t *bwp = NULL; + for (int i = 0; i < mac->dl_BWPs.count; i++) { + if (bwp_id == mac->dl_BWPs.array[i]->bwp_id) { + bwp = mac->dl_BWPs.array[i]; + break; + } + } + if (!bwp && setup) { + bwp = calloc(1, sizeof(*bwp)); + ASN_SEQUENCE_ADD(&mac->dl_BWPs, bwp); + } + if (!setup) { + mac->sc_info.n_dl_bwp = mac->dl_BWPs.count - 1; + mac->sc_info.dl_bw_tbslbrm = 0; + for (int i = 0; i < mac->dl_BWPs.count; i++) { + if (mac->dl_BWPs.array[i]->BWPSize > mac->sc_info.dl_bw_tbslbrm) + mac->sc_info.dl_bw_tbslbrm = mac->dl_BWPs.array[i]->BWPSize; + } + } + return bwp; +} + +static NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) +{ + NR_UE_UL_BWP_t *bwp = NULL; + for (int i = 0; i < mac->ul_BWPs.count; i++) { + if (bwp_id == mac->ul_BWPs.array[i]->bwp_id) { + bwp = mac->ul_BWPs.array[i]; + break; + } + } + if (!bwp && setup) { + bwp = calloc(1, sizeof(*bwp)); + ASN_SEQUENCE_ADD(&mac->ul_BWPs, bwp); + } + if (!setup) { + mac->sc_info.n_ul_bwp = mac->ul_BWPs.count - 1; + mac->sc_info.ul_bw_tbslbrm = 0; + for (int i = 0; i < mac->ul_BWPs.count; i++) { + if (mac->ul_BWPs.array[i]->BWPSize > mac->sc_info.ul_bw_tbslbrm) + mac->sc_info.ul_bw_tbslbrm = mac->ul_BWPs.array[i]->BWPSize; + } + } + return bwp; +} + +static void configure_dedicated_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkDedicated_t *dl_dedicated) +{ + if (dl_dedicated) { + NR_UE_DL_BWP_t *bwp = get_dl_bwp_structure(mac, bwp_id, true); + bwp->bwp_id = bwp_id; + NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id]; + if (dl_dedicated->pdsch_Config) { + if (dl_dedicated->pdsch_Config->present == NR_SetupRelease_PDSCH_Config_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config); + bwp->pdsch_Config = NULL; + } + if (dl_dedicated->pdsch_Config->present == NR_SetupRelease_PDSCH_Config_PR_setup) { + if (!bwp->pdsch_Config) + bwp->pdsch_Config = calloc(1, sizeof(*bwp->pdsch_Config)); + setup_pdschconfig(dl_dedicated->pdsch_Config->choice.setup, bwp->pdsch_Config); + } + } + if (dl_dedicated->pdcch_Config) { + if (dl_dedicated->pdcch_Config->present == NR_SetupRelease_PDCCH_Config_PR_release) { + for (int i = 0; pdcch->list_Coreset.count; i++) + asn_sequence_del(&pdcch->list_Coreset, i, 1); + for (int i = 0; pdcch->list_SS.count; i++) + asn_sequence_del(&pdcch->list_SS, i, 1); + } + if (dl_dedicated->pdcch_Config->present == NR_SetupRelease_PDCCH_Config_PR_setup) + configure_ss_coreset(pdcch, dl_dedicated->pdcch_Config->choice.setup); + } + } +} + +static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_UplinkDedicated_t *ul_dedicated) +{ + if (ul_dedicated) { + NR_UE_UL_BWP_t *bwp = get_ul_bwp_structure(mac, bwp_id, true); + bwp->bwp_id = bwp_id; + if (ul_dedicated->pucch_Config) { + if (ul_dedicated->pucch_Config->present == NR_SetupRelease_PUCCH_Config_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_PUCCH_Config, bwp->pucch_Config); + bwp->pucch_Config = NULL; + } + if (ul_dedicated->pucch_Config->present == NR_SetupRelease_PUCCH_Config_PR_setup) { + if (!bwp->pucch_Config) + bwp->pucch_Config = calloc(1, sizeof(*bwp->pucch_Config)); + setup_pucchconfig(ul_dedicated->pucch_Config->choice.setup, bwp->pucch_Config); + } + } + if (ul_dedicated->pusch_Config) { + if (ul_dedicated->pusch_Config->present == NR_SetupRelease_PUSCH_Config_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_PUSCH_Config, bwp->pusch_Config); + bwp->pusch_Config = NULL; + } + if (ul_dedicated->pusch_Config->present == NR_SetupRelease_PUSCH_Config_PR_setup) { + if (!bwp->pusch_Config) + bwp->pusch_Config = calloc(1, sizeof(*bwp->pusch_Config)); + setup_puschconfig(ul_dedicated->pusch_Config->choice.setup, bwp->pusch_Config); + } + } + if (ul_dedicated->srs_Config) { + if (ul_dedicated->srs_Config->present == NR_SetupRelease_SRS_Config_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_SRS_Config, bwp->srs_Config); + bwp->srs_Config = NULL; + } + if (ul_dedicated->srs_Config->present == NR_SetupRelease_SRS_Config_PR_setup) { + if (!bwp->srs_Config) + bwp->srs_Config = calloc(1, sizeof(*bwp->srs_Config)); + setup_srsconfig(ul_dedicated->srs_Config->choice.setup, bwp->srs_Config); + } + } + AssertFatal(!ul_dedicated->configuredGrantConfig, "configuredGrantConfig not supported\n"); + } +} + +static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkCommon_t *dl_common) +{ + if (dl_common) { + NR_UE_DL_BWP_t *bwp = get_dl_bwp_structure(mac, bwp_id, true); + bwp->bwp_id = bwp_id; + NR_BWP_t *dl_genericParameters = &dl_common->genericParameters; + bwp->scs = dl_genericParameters->subcarrierSpacing; + bwp->cyclicprefix = dl_genericParameters->cyclicPrefix; + bwp->BWPSize = NRRIV2BW(dl_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + bwp->BWPStart = NRRIV2PRBOFFSET(dl_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + if (bwp_id == 0) { + mac->sc_info.initial_dl_BWPSize = bwp->BWPSize; + mac->sc_info.initial_dl_BWPStart = bwp->BWPStart; + } + if (dl_common->pdsch_ConfigCommon) { + if (dl_common->pdsch_ConfigCommon->present == NR_SetupRelease_PDSCH_ConfigCommon_PR_setup) + UPDATE_MAC_IE(bwp->tdaList_Common, + dl_common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, + NR_PDSCH_TimeDomainResourceAllocationList_t); + if (dl_common->pdsch_ConfigCommon->present == NR_SetupRelease_PDSCH_ConfigCommon_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_PDSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common); + bwp->tdaList_Common = NULL; + } + } + NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id]; + if (dl_common->pdcch_ConfigCommon) { + if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup) + configure_common_ss_coreset(pdcch, dl_common->pdcch_ConfigCommon->choice.setup); + if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_release) + release_common_ss_cset(pdcch); + } + } +} + +static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_UplinkCommon_t *ul_common) +{ + if (ul_common) { + NR_UE_UL_BWP_t *bwp = get_ul_bwp_structure(mac, bwp_id, true); + bwp->bwp_id = bwp_id; + NR_BWP_t *ul_genericParameters = &ul_common->genericParameters; + bwp->scs = ul_genericParameters->subcarrierSpacing; + bwp->cyclicprefix = ul_genericParameters->cyclicPrefix; + bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + if (bwp_id == 0) { + mac->sc_info.initial_ul_BWPSize = bwp->BWPSize; + mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; + } + if (ul_common->rach_ConfigCommon) { + HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon, + ul_common->rach_ConfigCommon, + NR_RACH_ConfigCommon_t, + asn_DEF_NR_RACH_ConfigCommon); + } + if (ul_common->pucch_ConfigCommon) + HANDLE_SETUPRELEASE_DIRECT(bwp->pucch_ConfigCommon, + ul_common->pucch_ConfigCommon, + NR_PUCCH_ConfigCommon_t, + asn_DEF_NR_PUCCH_ConfigCommon); + if (ul_common->pusch_ConfigCommon) { + if (ul_common->pusch_ConfigCommon->present == NR_SetupRelease_PUSCH_ConfigCommon_PR_setup) { + UPDATE_MAC_IE(bwp->tdaList_Common, + ul_common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList, + NR_PUSCH_TimeDomainResourceAllocationList_t); + UPDATE_MAC_IE(bwp->msg3_DeltaPreamble, ul_common->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble, long); + } + if (ul_common->pusch_ConfigCommon->present == NR_SetupRelease_PUSCH_ConfigCommon_PR_release) { + ASN_STRUCT_FREE(asn_DEF_NR_PUSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common); + bwp->tdaList_Common = NULL; + free(bwp->msg3_DeltaPreamble); + bwp->msg3_DeltaPreamble = NULL; + } + } + } +} + void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SI_SchedulingInfo_t *si_SchedulingInfo, @@ -880,34 +1359,66 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); AssertFatal(scc, "SIB1 SCC should not be NULL\n"); - configure_scc(mac, scc, NULL); + UPDATE_MAC_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); + UPDATE_MAC_IE(mac->si_SchedulingInfo, si_SchedulingInfo, NR_SI_SchedulingInfo_t); - mac->si_SchedulingInfo = si_SchedulingInfo; config_common_ue_sa(mac, scc, module_id, cc_idP); - // configure BWP only if it is a SIB1 detection in non connected state (after sync) - // not if it is a periodical update of SIB1 (no change of BWP in that case) - if(mac->state < UE_CONNECTED) - configure_current_BWP(mac, scc, NULL); + configure_common_BWP_dl(mac, + 0, // bwp-id + &scc->downlinkConfigCommon.initialDownlinkBWP); + if (scc->uplinkConfigCommon) + configure_common_BWP_ul(mac, + 0, // bwp-id + &scc->uplinkConfigCommon->initialUplinkBWP); + // set current BWP only if coming from non-connected state + // otherwise it is just a periodically update of the SIB1 content + if (mac->state < UE_CONNECTED) { + mac->current_DL_BWP = get_dl_bwp_structure(mac, 0, false); + AssertFatal(mac->current_DL_BWP, "Couldn't find DL-BWP0\n"); + mac->current_UL_BWP = get_ul_bwp_structure(mac, 0, false); + AssertFatal(mac->current_UL_BWP, "Couldn't find DL-BWP0\n"); + } + + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac); if (!get_softmodem_params()->emulate_l1) mac->if_module->phy_config_request(&mac->phy_config); mac->phy_config_request_sent = true; } -void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, - module_id_t module_id, - int cc_idP, - const NR_ReconfigurationWithSync_t *reconfigurationWithSync) +static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, + module_id_t module_id, + int cc_idP, + const NR_ReconfigurationWithSync_t *reconfigurationWithSync) { + mac->crnti = reconfigurationWithSync->newUE_Identity; + LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti); + RA_config_t *ra = &mac->ra; if (reconfigurationWithSync->rach_ConfigDedicated) { - ra->rach_ConfigDedicated = reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + AssertFatal( + reconfigurationWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink, + "RACH on supplementaryUplink not supported\n"); + UPDATE_MAC_IE(ra->rach_ConfigDedicated, reconfigurationWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); } - configure_scc(mac, NULL, reconfigurationWithSync->spCellConfigCommon); - mac->crnti = reconfigurationWithSync->newUE_Identity; - LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti); - config_common_ue(mac, reconfigurationWithSync->spCellConfigCommon, module_id, cc_idP); + if (reconfigurationWithSync->spCellConfigCommon) { + NR_ServingCellConfigCommon_t *scc = reconfigurationWithSync->spCellConfigCommon; + if (scc->physCellId) + mac->physCellId = *scc->physCellId; + mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position; + UPDATE_MAC_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); + config_common_ue(mac, scc, module_id, cc_idP); + if (scc->downlinkConfigCommon) + configure_common_BWP_dl(mac, + 0, // bwp-id + scc->downlinkConfigCommon->initialDownlinkBWP); + if (scc->uplinkConfigCommon) + configure_common_BWP_ul(mac, + 0, // bwp-id + scc->uplinkConfigCommon->initialUplinkBWP); + } mac->state = UE_NOT_SYNC; ra->ra_state = RA_UE_IDLE; @@ -923,8 +1434,8 @@ void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, } } -void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, - const NR_PhysicalCellGroupConfig_t *phyConfig) +static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, + const NR_PhysicalCellGroupConfig_t *phyConfig) { mac->pdsch_HARQ_ACK_Codebook = phyConfig->pdsch_HARQ_ACK_Codebook; mac->harq_ACK_SpatialBundlingPUCCH = phyConfig->harq_ACK_SpatialBundlingPUCCH ? true : false; @@ -942,7 +1453,7 @@ void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, *p_UE_FR1 : *p_NR_FR1); } -void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroupConfig_t *mcg) +static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroupConfig_t *mcg) { NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info; if (mcg->drx_Config) @@ -995,6 +1506,396 @@ void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroupConfig_ } } +static void configure_csi_resourcemapping(NR_CSI_RS_ResourceMapping_t *target, NR_CSI_RS_ResourceMapping_t *source) +{ + target->frequencyDomainAllocation.present = source->frequencyDomainAllocation.present; + switch (source->frequencyDomainAllocation.present) { + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: + target->frequencyDomainAllocation.choice.row1.size = source->frequencyDomainAllocation.choice.row1.size; + target->frequencyDomainAllocation.choice.row1.bits_unused = source->frequencyDomainAllocation.choice.row1.bits_unused; + if (!target->frequencyDomainAllocation.choice.row1.buf) + target->frequencyDomainAllocation.choice.row1.buf = + calloc(target->frequencyDomainAllocation.choice.row1.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.row1.size; i++) + target->frequencyDomainAllocation.choice.row1.buf[i] = source->frequencyDomainAllocation.choice.row1.buf[i]; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: + target->frequencyDomainAllocation.choice.row2.size = source->frequencyDomainAllocation.choice.row2.size; + target->frequencyDomainAllocation.choice.row2.bits_unused = source->frequencyDomainAllocation.choice.row2.bits_unused; + if (!target->frequencyDomainAllocation.choice.row2.buf) + target->frequencyDomainAllocation.choice.row2.buf = + calloc(target->frequencyDomainAllocation.choice.row2.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.row2.size; i++) + target->frequencyDomainAllocation.choice.row2.buf[i] = source->frequencyDomainAllocation.choice.row2.buf[i]; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: + target->frequencyDomainAllocation.choice.row4.size = source->frequencyDomainAllocation.choice.row4.size; + target->frequencyDomainAllocation.choice.row4.bits_unused = source->frequencyDomainAllocation.choice.row4.bits_unused; + if (!target->frequencyDomainAllocation.choice.row4.buf) + target->frequencyDomainAllocation.choice.row4.buf = + calloc(target->frequencyDomainAllocation.choice.row4.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.row4.size; i++) + target->frequencyDomainAllocation.choice.row4.buf[i] = source->frequencyDomainAllocation.choice.row4.buf[i]; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: + target->frequencyDomainAllocation.choice.other.size = source->frequencyDomainAllocation.choice.other.size; + target->frequencyDomainAllocation.choice.other.bits_unused = source->frequencyDomainAllocation.choice.other.bits_unused; + if (!target->frequencyDomainAllocation.choice.other.buf) + target->frequencyDomainAllocation.choice.other.buf = + calloc(target->frequencyDomainAllocation.choice.other.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.other.size; i++) + target->frequencyDomainAllocation.choice.other.buf[i] = source->frequencyDomainAllocation.choice.other.buf[i]; + break; + default: + AssertFatal(false, "Invalid entry\n"); + } + target->nrofPorts = source->nrofPorts; + target->firstOFDMSymbolInTimeDomain = source->firstOFDMSymbolInTimeDomain; + UPDATE_MAC_IE(target->firstOFDMSymbolInTimeDomain2, source->firstOFDMSymbolInTimeDomain2, long); + target->cdm_Type = source->cdm_Type; + target->density = source->density; + target->freqBand = source->freqBand; +} + +static void configure_csirs_resource(NR_NZP_CSI_RS_Resource_t *target, NR_NZP_CSI_RS_Resource_t *source) +{ + configure_csi_resourcemapping(&target->resourceMapping, &source->resourceMapping); + target->powerControlOffset = source->powerControlOffset; + UPDATE_MAC_IE(target->powerControlOffsetSS, source->powerControlOffsetSS, long); + target->scramblingID = source->scramblingID; + if (source->periodicityAndOffset) + UPDATE_MAC_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); + if (source->qcl_InfoPeriodicCSI_RS) + UPDATE_MAC_IE(target->qcl_InfoPeriodicCSI_RS, source->qcl_InfoPeriodicCSI_RS, NR_TCI_StateId_t); +} + +static void configure_csiim_resource(NR_CSI_IM_Resource_t *target, NR_CSI_IM_Resource_t *source) +{ + if (source->csi_IM_ResourceElementPattern) + UPDATE_MAC_IE(target->csi_IM_ResourceElementPattern, + source->csi_IM_ResourceElementPattern, + struct NR_CSI_IM_Resource__csi_IM_ResourceElementPattern); + if (source->freqBand) + UPDATE_MAC_IE(target->freqBand, source->freqBand, NR_CSI_FrequencyOccupation_t); + if (source->periodicityAndOffset) + UPDATE_MAC_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); +} + +static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_SetupRelease_CSI_MeasConfig *csi_MeasConfig_sr) +{ + switch (csi_MeasConfig_sr->present) { + case NR_SetupRelease_CSI_MeasConfig_PR_NOTHING: + break; + case NR_SetupRelease_CSI_MeasConfig_PR_release: + ASN_STRUCT_FREE(asn_DEF_NR_CSI_MeasConfig, sc_info->csi_MeasConfig); + sc_info->csi_MeasConfig = NULL; + break; + case NR_SetupRelease_CSI_MeasConfig_PR_setup: + if (!sc_info->csi_MeasConfig) { // setup + UPDATE_MAC_IE(sc_info->csi_MeasConfig, csi_MeasConfig_sr->choice.setup, NR_CSI_MeasConfig_t); + } else { // modification + NR_CSI_MeasConfig_t *target = sc_info->csi_MeasConfig; + NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup; + if (csi_MeasConfig->reportTriggerSize) + UPDATE_MAC_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long); + if (csi_MeasConfig->aperiodicTriggerStateList) + HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList, + csi_MeasConfig->aperiodicTriggerStateList, + NR_CSI_AperiodicTriggerStateList_t, + asn_DEF_NR_CSI_AperiodicTriggerStateList); + if (csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList) + HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList, + csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList, + NR_CSI_SemiPersistentOnPUSCH_TriggerStateList_t, + asn_DEF_NR_SetupRelease_CSI_SemiPersistentOnPUSCH_TriggerStateList); + // NZP-CSI-RS-Resources + if (csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList, + target->nzp_CSI_RS_ResourceToAddModList, + nzp_CSI_RS_ResourceId); + } + if (csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList) { + if (!target->nzp_CSI_RS_ResourceToAddModList) + target->nzp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList, + target->nzp_CSI_RS_ResourceToAddModList, + nzp_CSI_RS_ResourceId, + NR_NZP_CSI_RS_Resource_t, + configure_csirs_resource); + } + // NZP-CSI-RS-ResourceSets + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList, + target->nzp_CSI_RS_ResourceSetToAddModList, + nzp_CSI_ResourceSetId); + } + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList) { + if (!target->nzp_CSI_RS_ResourceSetToAddModList) + target->nzp_CSI_RS_ResourceSetToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList, + target->nzp_CSI_RS_ResourceSetToAddModList, + nzp_CSI_ResourceSetId, + NR_NZP_CSI_RS_ResourceSet_t); + } + // CSI-IM-Resource + if (csi_MeasConfig->csi_IM_ResourceToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceToReleaseList, + target->csi_IM_ResourceToAddModList, + csi_IM_ResourceId); + } + if (csi_MeasConfig->csi_IM_ResourceToAddModList) { + if (!target->csi_IM_ResourceToAddModList) + target->csi_IM_ResourceToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->csi_IM_ResourceToAddModList, + target->csi_IM_ResourceToAddModList, + csi_IM_ResourceId, + NR_CSI_IM_Resource_t, + configure_csiim_resource); + } + // CSI-IM-ResourceSets + if (csi_MeasConfig->csi_IM_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToReleaseList, + target->csi_IM_ResourceSetToAddModList, + csi_IM_ResourceSetId); + } + if (csi_MeasConfig->csi_IM_ResourceSetToAddModList) { + if (!target->csi_IM_ResourceSetToAddModList) + target->csi_IM_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToAddModList, + target->csi_IM_ResourceSetToAddModList, + csi_IM_ResourceSetId, + NR_CSI_IM_ResourceSet_t); + } + // CSI-SSB-ResourceSets + if (csi_MeasConfig->csi_SSB_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToReleaseList, + target->csi_SSB_ResourceSetToAddModList, + csi_SSB_ResourceSetId); + } + if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList) { + if (!target->csi_SSB_ResourceSetToAddModList) + target->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_SSB_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToAddModList, + target->csi_SSB_ResourceSetToAddModList, + csi_SSB_ResourceSetId, + NR_CSI_SSB_ResourceSet_t); + } + // CSI-ResourceConfigs + if (csi_MeasConfig->csi_ResourceConfigToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToReleaseList, + target->csi_ResourceConfigToAddModList, + csi_ResourceConfigId); + } + if (csi_MeasConfig->csi_ResourceConfigToAddModList) { + if (!target->csi_ResourceConfigToAddModList) + target->csi_ResourceConfigToAddModList = calloc(1, sizeof(*target->csi_ResourceConfigToAddModList)); + ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToAddModList, + target->csi_ResourceConfigToAddModList, + csi_ResourceConfigId, + NR_CSI_ResourceConfig_t); + } + // CSI-ReportConfigs + if (csi_MeasConfig->csi_ReportConfigToReleaseList) { + RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToReleaseList, + target->csi_ReportConfigToAddModList, + reportConfigId); + } + if (csi_MeasConfig->csi_ReportConfigToAddModList) { + if (!target->csi_ReportConfigToAddModList) + target->csi_ReportConfigToAddModList = calloc(1, sizeof(*target->csi_ReportConfigToAddModList)); + ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToAddModList, + target->csi_ReportConfigToAddModList, + reportConfigId, + NR_CSI_ReportConfig_t); + } + } + break; + default: + AssertFatal(false, "Invalid case\n"); + } +} + +static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_ServingCellConfig_t *scd) +{ + if (scd->csi_MeasConfig) + configure_csiconfig(sc_info, scd->csi_MeasConfig); + + if (scd->supplementaryUplink) + UPDATE_MAC_IE(sc_info->supplementaryUplink, scd->supplementaryUplink, NR_UplinkConfig_t); + if (scd->crossCarrierSchedulingConfig) + UPDATE_MAC_IE(sc_info->crossCarrierSchedulingConfig, scd->crossCarrierSchedulingConfig, NR_CrossCarrierSchedulingConfig_t); + if (scd->pdsch_ServingCellConfig) { + switch (scd->pdsch_ServingCellConfig->present) { + case NR_SetupRelease_PDSCH_ServingCellConfig_PR_NOTHING: + break; + case NR_SetupRelease_PDSCH_ServingCellConfig_PR_release: + // release all configurations + if (sc_info->pdsch_CGB_Transmission) { + ASN_STRUCT_FREE(asn_DEF_NR_PDSCH_CodeBlockGroupTransmission, sc_info->pdsch_CGB_Transmission); + sc_info->pdsch_CGB_Transmission = NULL; + } + if (sc_info->xOverhead_PDSCH) { + free(sc_info->xOverhead_PDSCH); + sc_info->xOverhead_PDSCH = NULL; + } + if (sc_info->maxMIMO_Layers_PDSCH) { + free(sc_info->maxMIMO_Layers_PDSCH); + sc_info->maxMIMO_Layers_PDSCH = NULL; + } + break; + case NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup: { + NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = scd->pdsch_ServingCellConfig->choice.setup; + if (pdsch_servingcellconfig->codeBlockGroupTransmission) + HANDLE_SETUPRELEASE_DIRECT(sc_info->pdsch_CGB_Transmission, + pdsch_servingcellconfig->codeBlockGroupTransmission, + NR_PDSCH_CodeBlockGroupTransmission_t, + asn_DEF_NR_PDSCH_CodeBlockGroupTransmission); + UPDATE_MAC_IE(sc_info->xOverhead_PDSCH, pdsch_servingcellconfig->xOverhead, long); + if (pdsch_servingcellconfig->ext1 && pdsch_servingcellconfig->ext1->maxMIMO_Layers) + UPDATE_MAC_IE(sc_info->maxMIMO_Layers_PDSCH, pdsch_servingcellconfig->ext1->maxMIMO_Layers, long); + break; + } + default: + AssertFatal(false, "Invalid case\n"); + } + } + if (scd->uplinkConfig && scd->uplinkConfig->pusch_ServingCellConfig) { + switch (scd->uplinkConfig->pusch_ServingCellConfig->present) { + case NR_SetupRelease_PUSCH_ServingCellConfig_PR_NOTHING: + break; + case NR_SetupRelease_PUSCH_ServingCellConfig_PR_release: + // release all configurations + if (sc_info->pusch_CGB_Transmission) { + ASN_STRUCT_FREE(asn_DEF_NR_PUSCH_CodeBlockGroupTransmission, sc_info->pusch_CGB_Transmission); + sc_info->pdsch_CGB_Transmission = NULL; + } + if (sc_info->rateMatching_PUSCH) { + free(sc_info->rateMatching_PUSCH); + sc_info->rateMatching_PUSCH = NULL; + } + if (sc_info->xOverhead_PUSCH) { + free(sc_info->xOverhead_PUSCH); + sc_info->xOverhead_PUSCH = NULL; + } + if (sc_info->maxMIMO_Layers_PUSCH) { + free(sc_info->maxMIMO_Layers_PUSCH); + sc_info->maxMIMO_Layers_PUSCH = NULL; + } + break; + case NR_SetupRelease_PUSCH_ServingCellConfig_PR_setup: { + NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig = scd->uplinkConfig->pusch_ServingCellConfig->choice.setup; + UPDATE_MAC_IE(sc_info->rateMatching_PUSCH, pusch_servingcellconfig->rateMatching, long); + UPDATE_MAC_IE(sc_info->xOverhead_PUSCH, pusch_servingcellconfig->xOverhead, long); + if (pusch_servingcellconfig->ext1 && pusch_servingcellconfig->ext1->maxMIMO_Layers) + UPDATE_MAC_IE(sc_info->maxMIMO_Layers_PUSCH, pusch_servingcellconfig->ext1->maxMIMO_Layers, long); + if (pusch_servingcellconfig->codeBlockGroupTransmission) + HANDLE_SETUPRELEASE_DIRECT(sc_info->pusch_CGB_Transmission, + pusch_servingcellconfig->codeBlockGroupTransmission, + NR_PUSCH_CodeBlockGroupTransmission_t, + asn_DEF_NR_PUSCH_CodeBlockGroupTransmission); + break; + } + default: + AssertFatal(false, "Invalid case\n"); + } + } +} + +void release_dl_BWP(NR_UE_MAC_INST_t *mac, int bwp_id) +{ + NR_UE_DL_BWP_t *bwp = NULL; + for (int i = 0; i < mac->dl_BWPs.count; i++) { + if (bwp_id == mac->dl_BWPs.array[i]->bwp_id) { + bwp = mac->dl_BWPs.array[i]; + asn_sequence_del(&mac->dl_BWPs, i, 0); + break; + } + } + AssertFatal(bwp, "No DL-BWP %d to release\n", bwp_id); + free(bwp->cyclicprefix); + ASN_STRUCT_FREE(asn_DEF_NR_PDSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common); + bwp->tdaList_Common = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config); + bwp->pdsch_Config = NULL; + free(bwp); + + NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id]; + release_common_ss_cset(pdcch); + for (int i = 0; pdcch->list_Coreset.count; i++) + asn_sequence_del(&pdcch->list_Coreset, i, 1); + for (int i = 0; pdcch->list_SS.count; i++) + asn_sequence_del(&pdcch->list_SS, i, 1); +} + +void release_ul_BWP(NR_UE_MAC_INST_t *mac, int bwp_id) +{ + NR_UE_UL_BWP_t *bwp = NULL; + for (int i = 0; i < mac->ul_BWPs.count; i++) { + if (bwp_id == mac->ul_BWPs.array[i]->bwp_id) { + bwp = mac->ul_BWPs.array[i]; + asn_sequence_del(&mac->ul_BWPs, i, 0); + break; + } + } + AssertFatal(bwp, "No UL-BWP %d to release\n", bwp_id); + free(bwp->cyclicprefix); + ASN_STRUCT_FREE(asn_DEF_NR_RACH_ConfigCommon, bwp->rach_ConfigCommon); + bwp->rach_ConfigCommon = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_PUSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common); + bwp->tdaList_Common = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_ConfiguredGrantConfig, bwp->configuredGrantConfig); + bwp->configuredGrantConfig = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_PUSCH_Config, bwp->pusch_Config); + bwp->pusch_Config = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_PUCCH_Config, bwp->pucch_Config); + bwp->pucch_Config = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_PUCCH_ConfigCommon, bwp->pucch_ConfigCommon); + bwp->pucch_ConfigCommon = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_SRS_Config, bwp->srs_Config); + bwp->srs_Config = NULL; + free(bwp->msg3_DeltaPreamble); + free(bwp); +} + +static void configure_BWPs(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd) +{ + configure_dedicated_BWP_dl(mac, 0, scd->initialDownlinkBWP); + if (scd->downlinkBWP_ToReleaseList) { + for (int i = 0; i < scd->downlinkBWP_ToReleaseList->list.count; i++) + release_dl_BWP(mac, *scd->downlinkBWP_ToReleaseList->list.array[i]); + } + if (scd->downlinkBWP_ToAddModList) { + for (int i = 0; i < scd->downlinkBWP_ToAddModList->list.count; i++) { + NR_BWP_Downlink_t *bwp = scd->downlinkBWP_ToAddModList->list.array[i]; + configure_common_BWP_dl(mac, bwp->bwp_Id, bwp->bwp_Common); + configure_dedicated_BWP_dl(mac, bwp->bwp_Id, bwp->bwp_Dedicated); + } + } + if (scd->firstActiveDownlinkBWP_Id) { + mac->current_DL_BWP = get_dl_bwp_structure(mac, *scd->firstActiveDownlinkBWP_Id, false); + AssertFatal(mac->current_DL_BWP, "Couldn't find DL-BWP %ld\n", *scd->firstActiveDownlinkBWP_Id); + } + + if (scd->uplinkConfig) { + configure_dedicated_BWP_ul(mac, 0, scd->uplinkConfig->initialUplinkBWP); + if (scd->uplinkConfig->uplinkBWP_ToReleaseList) { + for (int i = 0; i < scd->uplinkConfig->uplinkBWP_ToReleaseList->list.count; i++) + release_ul_BWP(mac, *scd->uplinkConfig->uplinkBWP_ToReleaseList->list.array[i]); + } + if (scd->uplinkConfig->uplinkBWP_ToAddModList) { + for (int i = 0; i < scd->uplinkConfig->uplinkBWP_ToAddModList->list.count; i++) { + NR_BWP_Uplink_t *bwp = scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[i]; + configure_common_BWP_ul(mac, bwp->bwp_Id, bwp->bwp_Common); + configure_dedicated_BWP_ul(mac, bwp->bwp_Id, bwp->bwp_Dedicated); + } + } + if (scd->uplinkConfig->firstActiveUplinkBWP_Id) { + mac->current_UL_BWP = get_ul_bwp_structure(mac, *scd->uplinkConfig->firstActiveUplinkBWP_Id, false); + AssertFatal(mac->current_UL_BWP, "Couldn't find DL-BWP %ld\n", *scd->uplinkConfig->firstActiveUplinkBWP_Id); + } + } +} + void nr_rrc_mac_config_req_cg(module_id_t module_id, int cc_idP, NR_CellGroupConfig_t *cell_group_config) @@ -1011,17 +1912,23 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, if (cell_group_config->spCellConfig) { NR_SpCellConfig_t *spCellConfig = cell_group_config->spCellConfig; + NR_ServingCellConfig_t *scd = spCellConfig->spCellConfigDedicated; mac->servCellIndex = spCellConfig->servCellIndex ? *spCellConfig->servCellIndex : 0; if (spCellConfig->reconfigurationWithSync) { LOG_A(NR_MAC, "Received reconfigurationWithSync\n"); handle_reconfiguration_with_sync(mac, module_id, cc_idP, spCellConfig->reconfigurationWithSync); } - if (spCellConfig->spCellConfigDedicated) { - mac->crossCarrierSchedulingConfig = spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig; - configure_current_BWP(mac, NULL, spCellConfig->spCellConfigDedicated); + if (scd) { + configure_servingcell_info(&mac->sc_info, scd); + configure_BWPs(mac, scd); } } + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac); + if (!mac->dl_config_request || !mac->ul_config_request) - ue_init_config_request(mac, mac->current_DL_BWP.scs); + ue_init_config_request(mac, mac->current_DL_BWP->scs); + + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, cell_group_config); } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 0e57098d7b9ec0527b61c1d4dc96e5c6ff258248..1fdeb06e097aff523ba0f8726595582677a07156 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -432,40 +432,42 @@ typedef struct nr_lcordered_info_s { NR_LogicalChannelConfig_t *logicalChannelConfig_ordered; } nr_lcordered_info_t; +typedef struct { + NR_SearchSpace_t *otherSI_SS; + NR_SearchSpace_t *ra_SS; + NR_SearchSpace_t *paging_SS; + NR_ControlResourceSet_t *coreset0; + NR_ControlResourceSet_t *commonControlResourceSet; + NR_SearchSpace_t *search_space_zero; + A_SEQUENCE_OF(NR_ControlResourceSet_t) list_Coreset; + A_SEQUENCE_OF(NR_SearchSpace_t) list_SS; +} NR_BWP_PDCCH_t; + /*!\brief Top level UE MAC structure */ typedef struct { NR_UE_L2_STATE_t state; - int servCellIndex; - long physCellId; - //// MAC config - int first_sync_frame; - bool get_sib1; - bool get_otherSI; - NR_MIB_t *mib; + int servCellIndex; + long physCellId; + int first_sync_frame; + bool get_sib1; + bool get_otherSI; + NR_MIB_t *mib; struct NR_SI_SchedulingInfo *si_SchedulingInfo; int si_window_start; ssb_list_info_t ssb_list; - NR_UE_DL_BWP_t current_DL_BWP; - NR_UE_UL_BWP_t current_UL_BWP; - NR_BWP_DownlinkCommon_t *bwp_dlcommon; - NR_BWP_UplinkCommon_t *bwp_ulcommon; + NR_UE_ServingCell_Info_t sc_info; + A_SEQUENCE_OF(NR_UE_DL_BWP_t) dl_BWPs; + A_SEQUENCE_OF(NR_UE_UL_BWP_t) ul_BWPs; + NR_BWP_PDCCH_t config_BWP_PDCCH[5]; + NR_UE_DL_BWP_t *current_DL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP; bool harq_ACK_SpatialBundlingPUCCH; bool harq_ACK_SpatialBundlingPUSCH; NR_UL_TIME_ALIGNMENT_t ul_time_alignment; - - NR_SearchSpace_t *otherSI_SS; - NR_SearchSpace_t *ra_SS; - NR_SearchSpace_t *paging_SS; - NR_ControlResourceSet_t *BWP_coresets[FAPI_NR_MAX_CORESET_PER_BWP]; - NR_ControlResourceSet_t *coreset0; - NR_SearchSpace_t *BWP_searchspaces[FAPI_NR_MAX_SS]; - NR_SearchSpace_t *search_space_zero; - NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon; - NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig; bool phy_config_request_sent; frame_type_t frame_type; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index cb00daa6ef6792a8c58441c3eed086122367e9fe..f30e700614a719a1c5479e2ec465cf4629ff454e 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -39,6 +39,91 @@ #define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */ #define NR_DL_MAX_NB_CW (2) /* number of downlink code word */ +#define UPDATE_MAC_IE(DESTINATION, ORIGIN, TYPE) \ + do { \ + TYPE *tmp = ORIGIN; \ + ORIGIN = DESTINATION; \ + DESTINATION = tmp; \ + } while(0); \ + +#define HANDLE_SETUPRELEASE_DIRECT(DESTINATION, ORIGIN, TYPE, ASN_DEF) \ + do { \ + if (ORIGIN->present == 1) { \ + ASN_STRUCT_FREE(ASN_DEF, DESTINATION); \ + DESTINATION = NULL; \ + } \ + if (ORIGIN->present == 2) \ + UPDATE_MAC_IE(DESTINATION, ORIGIN->choice.setup, TYPE); \ + } while(0); \ + +#define HANDLE_SETUPRELEASE_IE(DESTINATION, ORIGIN, TYPE, ASN_DEF) \ + do { \ + if (ORIGIN->present == 1) { \ + ASN_STRUCT_FREE(ASN_DEF, DESTINATION); \ + DESTINATION = NULL; \ + } \ + if (ORIGIN->present == 2) { \ + if (!DESTINATION) \ + DESTINATION = calloc(1, sizeof(*DESTINATION)); \ + DESTINATION->present = ORIGIN->present; \ + UPDATE_MAC_IE(DESTINATION->choice.setup, ORIGIN->choice.setup, TYPE); \ + } \ + } while(0); \ + +#define RELEASE_IE_FROMLIST(SOURCE, TARGET, FIELD) \ + do { \ + for (int iI = 0; iI < SOURCE->list.count; iI++) { \ + long eL = *SOURCE->list.array[iI]; \ + int iJ; \ + for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ + if (eL == TARGET->list.array[iJ]->FIELD) \ + break; \ + } \ + if (iJ == TARGET->list.count) \ + asn_sequence_del(&TARGET->list, iJ, 1); \ + else \ + LOG_E(NR_MAC, "Element not present in the list, impossible to release\n"); \ + } \ + } while (0) \ + +#define ADDMOD_IE_FROMLIST(SOURCE, TARGET, FIELD, TYPE) \ + do { \ + for (int iI = 0; iI < SOURCE->list.count; iI++) { \ + long eL = SOURCE->list.array[iI]->FIELD; \ + int iJ; \ + for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ + if (eL == TARGET->list.array[iJ]->FIELD) \ + break; \ + } \ + if (iJ == TARGET->list.count) { \ + TYPE *nEW = calloc(1, sizeof(*nEW)); \ + ASN_SEQUENCE_ADD(&TARGET->list, nEW); \ + } \ + UPDATE_MAC_IE(TARGET->list.array[iJ], \ + SOURCE->list.array[iI], \ + TYPE); \ + } \ + } while (0) \ + +#define ADDMOD_IE_FROMLIST_WFUNCTION(SOURCE, TARGET, FIELD, TYPE, FUNC) \ + do { \ + for (int iI = 0; iI < SOURCE->list.count; iI++) { \ + long eL = SOURCE->list.array[iI]->FIELD; \ + int iJ; \ + for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ + if (eL == TARGET->list.array[iJ]->FIELD) \ + break; \ + } \ + if (iJ == TARGET->list.count) { \ + TYPE *nEW = calloc(1, sizeof(*nEW)); \ + ASN_SEQUENCE_ADD(&TARGET->list, nEW); \ + } \ + FUNC(TARGET->list.array[iJ], \ + SOURCE->list.array[iI]); \ + } \ + } while (0) + + /**\brief initialize the field in nr_mac instance \param module_id module id */ void nr_ue_init_mac(module_id_t module_idP); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index ebcb0e601bfd1ce358de0906150a4d440013c748..aedf2bbc2199709ccca95312fd25eb409a325ac0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -77,8 +77,8 @@ void init_RA(module_id_t mod_id, prach_resources->RA_PREAMBLE_BACKOFF = 0; NR_SubcarrierSpacing_t prach_scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing; - int n_prbs = get_N_RA_RB (prach_scs, mac->current_UL_BWP.scs); - int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP.BWPStart; + int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs); + int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart; // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) prach_resources->RA_PCMAX = nr_get_Pcmax(mac, 2, false, prach_scs, cfg->carrier_config.dl_grid_size[prach_scs], true, n_prbs, start_prb); prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; @@ -172,7 +172,7 @@ void init_RA(module_id_t mod_id, int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format) { NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing; int prach_sequence_length = nr_rach_ConfigCommon->prach_RootSequenceIndex.present - 1; uint8_t prachConfigIndex, mu; @@ -278,7 +278,7 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m int8_t receivedTargerPower; int8_t delta_preamble; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format); @@ -383,11 +383,11 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t } RA_config_t *ra = &mac->ra; - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; - if (mac->current_UL_BWP.msg3_DeltaPreamble) { - deltaPreamble_Msg3 = (*mac->current_UL_BWP.msg3_DeltaPreamble) * 2; // dB + if (mac->current_UL_BWP->msg3_DeltaPreamble) { + deltaPreamble_Msg3 = (*mac->current_UL_BWP->msg3_DeltaPreamble) * 2; // dB LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3); } @@ -552,7 +552,7 @@ void nr_get_prach_resources(module_id_t mod_id, NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; LOG_D(MAC, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3); @@ -590,8 +590,8 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP.rach_ConfigCommon; - long mu = mac->current_UL_BWP.scs; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; + long mu = mac->current_UL_BWP->scs; int subframes_per_slot = nr_slots_per_frame[mu]/10; // start contention resolution timer (cnt in slots) @@ -699,7 +699,7 @@ uint8_t nr_ue_get_rach(module_id_t mod_id, if (ra->ra_state > RA_UE_IDLE && ra->ra_state < RA_SUCCEEDED) { if (ra->RA_active == 0) { - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; init_RA(mod_id, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated); @@ -821,12 +821,12 @@ uint8_t nr_ue_get_rach(module_id_t mod_id, void nr_get_RA_window(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; int ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow; - int mu = mac->current_DL_BWP.scs; + int mu = mac->current_DL_BWP->scs; ra->RA_window_cnt = ra->RA_offset * nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 17ccd6517ec2046e3aa8a56d54354b737a224509..075afc2bd9df8588d65258e838f2503f78e4ee42 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -86,13 +86,14 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss, rel15->number_of_candidates = i; } -NR_ControlResourceSet_t *ue_get_coreset(const NR_UE_MAC_INST_t *mac, const int coreset_id) +NR_ControlResourceSet_t *ue_get_coreset(const NR_BWP_PDCCH_t *config, const int coreset_id) { + if (config->commonControlResourceSet && coreset_id == config->commonControlResourceSet->controlResourceSetId) + return config->commonControlResourceSet; NR_ControlResourceSet_t *coreset = NULL; - for (int i = 0; i < FAPI_NR_MAX_CORESET_PER_BWP; i++) { - if (mac->BWP_coresets[i] != NULL && - mac->BWP_coresets[i]->controlResourceSetId == coreset_id) { - coreset = mac->BWP_coresets[i]; + for (int i = 0; i < config->list_Coreset.count; i++) { + if (config->list_Coreset.array[i]->controlResourceSetId == coreset_id) { + coreset = config->list_Coreset.array[i]; break; } } @@ -107,20 +108,20 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, const int slot, const NR_SearchSpace_t *ss) { - - const NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; - const NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_BWP_Id_t dl_bwp_id = current_DL_BWP ? current_DL_BWP->bwp_id : 0; + NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[dl_bwp_id]; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; const int coreset_id = *ss->controlResourceSetId; NR_ControlResourceSet_t *coreset; if(coreset_id > 0) { - coreset = ue_get_coreset(mac, coreset_id); + coreset = ue_get_coreset(pdcch_config, coreset_id); rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; } else { - coreset = mac->coreset0; + coreset = pdcch_config->coreset0; rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; } @@ -175,48 +176,46 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_0; } + NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info; // loop over RNTI type and configure resource allocation for DCI for (int i = 0; i < rel15->num_dci_options; i++) { rel15->ss_type_options[i] = ss->searchSpaceType->present; const int dci_format = rel15->dci_format_options[i]; uint16_t alt_size = 0; if(current_DL_BWP) { - // computing alternative size for padding dci_pdu_rel15_t temp_pdu; if(dci_format == NR_DL_DCI_FORMAT_1_0) - alt_size = - nr_dci_size(current_DL_BWP, - current_UL_BWP, - mac->crossCarrierSchedulingConfig, - mac->pdsch_HARQ_ACK_Codebook, - &temp_pdu, - NR_UL_DCI_FORMAT_0_0, - rnti_type, - coreset, - dl_bwp_id, - ss->searchSpaceType->present, - mac->type0_PDCCH_CSS_config.num_rbs, - 0); + alt_size = nr_dci_size(current_DL_BWP, + current_UL_BWP, + sc_info, + mac->pdsch_HARQ_ACK_Codebook, + &temp_pdu, + NR_UL_DCI_FORMAT_0_0, + rnti_type, + coreset, + dl_bwp_id, + ss->searchSpaceType->present, + mac->type0_PDCCH_CSS_config.num_rbs, + 0); if(dci_format == NR_UL_DCI_FORMAT_0_0) - alt_size = - nr_dci_size(current_DL_BWP, - current_UL_BWP, - mac->crossCarrierSchedulingConfig, - mac->pdsch_HARQ_ACK_Codebook, - &temp_pdu, - NR_DL_DCI_FORMAT_1_0, - rnti_type, - coreset, - dl_bwp_id, - ss->searchSpaceType->present, - mac->type0_PDCCH_CSS_config.num_rbs, - 0); + alt_size = nr_dci_size(current_DL_BWP, + current_UL_BWP, + sc_info, + mac->pdsch_HARQ_ACK_Codebook, + &temp_pdu, + NR_DL_DCI_FORMAT_1_0, + rnti_type, + coreset, + dl_bwp_id, + ss->searchSpaceType->present, + mac->type0_PDCCH_CSS_config.num_rbs, + 0); } rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP, current_UL_BWP, - mac->crossCarrierSchedulingConfig, + sc_info, mac->pdsch_HARQ_ACK_Codebook, &mac->def_dci_pdu_rel15[dl_config->slot][dci_format], dci_format, @@ -460,8 +459,10 @@ bool monitior_dci_for_other_SI(NR_UE_MAC_INST_t *mac, void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot) { - const NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; - int scs = mac->get_sib1 ? get_softmodem_params()->numerology : current_DL_BWP->scs; + const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + NR_BWP_Id_t dl_bwp_id = current_DL_BWP ? current_DL_BWP->bwp_id : 0; + NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[dl_bwp_id]; + int scs = current_DL_BWP ? current_DL_BWP->scs : get_softmodem_params()->numerology; const int slots_per_frame = nr_slots_per_frame[scs]; if (mac->get_sib1) { int ssb_sc_offset_norm; @@ -483,22 +484,22 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl mac->mib_ssb, 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame ssb_offset_point_a); - if(mac->search_space_zero == NULL) - mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); - if(mac->coreset0 == NULL) - mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); - fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); - fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero)) { + if (pdcch_config->search_space_zero == NULL) + pdcch_config->search_space_zero = calloc(1, sizeof(*pdcch_config->search_space_zero)); + if (pdcch_config->coreset0 == NULL) + pdcch_config->coreset0 = calloc(1, sizeof(*pdcch_config->coreset0)); + fill_coresetZero(pdcch_config->coreset0, &mac->type0_PDCCH_CSS_config); + fill_searchSpaceZero(pdcch_config->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->search_space_zero)) { LOG_D(NR_MAC, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot); - config_dci_pdu(mac, dl_config, NR_RNTI_SI, slot, mac->search_space_zero); + config_dci_pdu(mac, dl_config, NR_RNTI_SI, slot, pdcch_config->search_space_zero); } } if (mac->get_otherSI) { // If searchSpaceOtherSystemInformation is set to zero, // PDCCH monitoring occasions for SI message reception in SI-window // are same as PDCCH monitoring occasions for SIB1 - const NR_SearchSpace_t *ss = mac->otherSI_SS ? mac->otherSI_SS : mac->search_space_zero; + const NR_SearchSpace_t *ss = pdcch_config->otherSI_SS ? pdcch_config->otherSI_SS : pdcch_config->search_space_zero; // TODO configure SI-window if (monitior_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) { LOG_D(NR_MAC, "Monitoring DCI for other SIs in frame %d slot %d\n", frame, slot); @@ -508,28 +509,24 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl if (mac->state == UE_PERFORMING_RA && mac->ra.ra_state >= WAIT_RAR) { // if RA is ongoing use RA search space - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->ra_SS)) { + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->ra_SS)) { int rnti_type = mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC; - config_dci_pdu(mac, dl_config, rnti_type, slot, mac->ra_SS); + config_dci_pdu(mac, dl_config, rnti_type, slot, pdcch_config->ra_SS); } } else if (mac->state == UE_CONNECTED) { - bool found = false; - for (int i = 0; i < FAPI_NR_MAX_SS; i++) { - if (mac->BWP_searchspaces[i] != NULL) { - found = true; - NR_SearchSpace_t *ss = mac->BWP_searchspaces[i]; - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, ss)) - config_dci_pdu(mac, dl_config, NR_RNTI_C, slot, ss); - } + for (int i = 0; i < pdcch_config->list_SS.count; i++) { + NR_SearchSpace_t *ss = pdcch_config->list_SS.array[i]; + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, ss)) + config_dci_pdu(mac, dl_config, NR_RNTI_C, slot, ss); } - if (!found && mac->ra_SS) { + if (pdcch_config->list_SS.count == 0 && pdcch_config->ra_SS) { // If the UE has not been provided a Type3-PDCCH CSS set or a USS set and // the UE has received a C-RNTI and has been provided a Type1-PDCCH CSS set, // the UE monitors PDCCH candidates for DCI format 0_0 and DCI format 1_0 // with CRC scrambled by the C-RNTI in the Type1-PDCCH CSS set - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->ra_SS)) - config_dci_pdu(mac, dl_config, NR_RNTI_C, slot, mac->ra_SS); + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->ra_SS)) + config_dci_pdu(mac, dl_config, NR_RNTI_C, slot, pdcch_config->ra_SS); } } } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 310aceaf6f3a7844189f8abab3ff063d1c07efef..c5e8b9d95a3c7fe9352e06fb81f4bb1bd0c154bf 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -167,11 +167,10 @@ void nr_ue_init_mac(module_id_t module_idP) mac->get_sib1 = false; mac->get_otherSI = false; mac->phy_config_request_sent = false; + memset(&mac->phy_config, 0, sizeof(mac->phy_config)); mac->state = UE_NOT_SYNC; mac->si_window_start = -1; mac->servCellIndex = 0; - memset(&mac->current_DL_BWP, 0, sizeof(mac->current_DL_BWP)); - memset(&mac->current_UL_BWP, 0, sizeof(mac->current_UL_BWP)); } void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) @@ -425,7 +424,7 @@ static int nr_ue_process_dci_ul_00(module_id_t module_id, // Schedule PUSCH const int coreset_type = dci_ind->coreset_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; // 0 for coreset0, 1 otherwise; - NR_tda_info_t tda_info = get_ul_tda_info(&mac->current_UL_BWP, + NR_tda_info_t tda_info = get_ul_tda_info(mac->current_UL_BWP, coreset_type, dci_ind->ss_type, get_rnti_type(mac, dci_ind->rnti), @@ -512,7 +511,7 @@ static int nr_ue_process_dci_ul_01(module_id_t module_id, int slot_tx; const int coreset_type = dci_ind->coreset_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; // 0 for coreset0, 1 otherwise; - NR_tda_info_t tda_info = get_ul_tda_info(&mac->current_UL_BWP, + NR_tda_info_t tda_info = get_ul_tda_info(mac->current_UL_BWP, coreset_type, dci_ind->ss_type, get_rnti_type(mac, dci_ind->rnti), @@ -613,11 +612,11 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id, fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu = &dl_conf_req->dlsch_config_pdu.dlsch_config_rel15; dlsch_pdu->pduBitmap = 0; - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; NR_PDSCH_Config_t *pdsch_config = (current_DL_BWP || !mac->get_sib1) ? current_DL_BWP->pdsch_Config : NULL; if (dci_ind->ss_type == NR_SearchSpace__searchSpaceType_PR_common) { dlsch_pdu->BWPSize = - mac->type0_PDCCH_CSS_config.num_rbs ? mac->type0_PDCCH_CSS_config.num_rbs : current_DL_BWP->initial_BWPSize; + mac->type0_PDCCH_CSS_config.num_rbs ? mac->type0_PDCCH_CSS_config.num_rbs : mac->sc_info.initial_dl_BWPSize; dlsch_pdu->BWPStart = dci_ind->cset_start; } else { dlsch_pdu->BWPSize = current_DL_BWP->BWPSize; @@ -714,7 +713,11 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id, int R = nr_get_code_rate_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table); if (R > 0) { dlsch_pdu->targetCodeRate = R; - int nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + int nb_rb_oh; + if (mac->sc_info.xOverhead_PDSCH) + nb_rb_oh = 6 * (1 + *mac->sc_info.xOverhead_PDSCH); + else + nb_rb_oh = 0; int nb_re_dmrs = ((dlsch_pdu->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? 6 : 4) * dlsch_pdu->n_dmrs_cdm_groups; dlsch_pdu->TBS = nr_compute_tbs(dlsch_pdu->qamModOrder, R, @@ -733,9 +736,7 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id, dlsch_pdu->TBS = current_harq->TBS; } - int bw_tbslbrm = current_DL_BWP->initial_BWPSize > 0 ? - current_DL_BWP->bw_tbslbrm : - dlsch_pdu->BWPSize; + int bw_tbslbrm = current_DL_BWP ? mac->sc_info.dl_bw_tbslbrm : dlsch_pdu->BWPSize; dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, bw_tbslbrm, 1); /* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ @@ -762,7 +763,7 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id, dlsch_pdu->accumulated_delta_PUCCH = tcp[dci->tpc]; // Sanity check for pucch_resource_indicator value received to check for false DCI. bool valid = false; - NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP.pucch_Config; + NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP ? mac->current_UL_BWP->pucch_Config : NULL; if (pucch_Config && pucch_Config->resourceSetToAddModList) { int pucch_res_set_cnt = pucch_Config->resourceSetToAddModList->list.count; @@ -892,7 +893,7 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id, dci->bwp_indicator.val); return -1; } - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; NR_PDSCH_Config_t *pdsch_Config = current_DL_BWP->pdsch_Config; fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); fapi_nr_dl_config_request_pdu_t *dl_conf_req = &dl_config->dl_config_list[dl_config->number_pdus]; @@ -1000,7 +1001,7 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id, // Sanity check for pucch_resource_indicator value received to check for false DCI. bool valid = false; - NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP.pucch_Config; + NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP->pucch_Config; int pucch_res_set_cnt = pucch_Config->resourceSetToAddModList->list.count; for (int id = 0; id < pucch_res_set_cnt; id++) { if (dci->pucch_resource_indicator < pucch_Config->resourceSetToAddModList->list.array[id]->resourceList.list.count) { @@ -1132,7 +1133,13 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id, if ((dlsch_pdu->dmrs_ports >> i) & 0x01) Nl += 1; } - int nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info; + int nb_rb_oh; + if (sc_info->xOverhead_PDSCH) + nb_rb_oh = 6 * (1 + *sc_info->xOverhead_PDSCH); + else + nb_rb_oh = 0; int nb_re_dmrs = ((dmrs_type == NULL) ? 6 : 4) * dlsch_pdu->n_dmrs_cdm_groups; NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid]; @@ -1157,10 +1164,9 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id, } // TBS_LBRM according to section 5.4.2.1 of 38.212 - long *maxMIMO_Layers = current_DL_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers; - AssertFatal(maxMIMO_Layers != NULL, "Option with max MIMO layers not configured is not supported\n"); - int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4; - dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, current_DL_BWP->bw_tbslbrm, nl_tbslbrm); + AssertFatal(sc_info->maxMIMO_Layers_PDSCH != NULL, "Option with max MIMO layers not configured is not supported\n"); + int nl_tbslbrm = *sc_info->maxMIMO_Layers_PDSCH < 4 ? *sc_info->maxMIMO_Layers_PDSCH : 4; + dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, sc_info->dl_bw_tbslbrm, nl_tbslbrm); /*PTRS configuration */ dlsch_pdu->pduBitmap = 0; if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) { @@ -1266,7 +1272,8 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, current_harq->N_CCE = N_CCE; current_harq->delta_pucch = delta_pucch; // FIXME k0 != 0 currently not taken into consideration - int slots_per_frame = nr_slots_per_frame[mac->current_DL_BWP.scs]; + int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : get_softmodem_params()->numerology; + int slots_per_frame = nr_slots_per_frame[scs]; current_harq->ul_frame = frame; current_harq->ul_slot = slot + data_toul_fb; if (current_harq->ul_slot >= slots_per_frame) { @@ -1304,8 +1311,8 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, fapi_nr_ul_config_pucch_pdu *pucch_pdu) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info; NR_PUCCH_FormatConfig_t *pucchfmt; long *pusch_id = NULL; long *id0 = NULL; @@ -1362,7 +1369,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, mac->pdsch_HARQ_ACK_Codebook != NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) { LOG_E(MAC,"PUCCH Unsupported cell group configuration\n"); return; - } else if (current_DL_BWP && current_DL_BWP->pdsch_servingcellconfig && current_DL_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) { + } else if (sc_info->pdsch_CGB_Transmission) { LOG_E(MAC,"PUCCH Unsupported code block group for serving cell config\n"); return; } @@ -1546,7 +1553,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int subframe_number, int O_uci) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; int PUCCH_POWER_DEFAULT = 0; int16_t P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal; @@ -1670,7 +1677,7 @@ int get_deltatf(uint16_t nb_of_prbs, int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int size) { int pucch_resource_set_id = 0; - NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP.pucch_Config; + NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP->pucch_Config; //long *pucch_max_pl_bits = NULL; @@ -2130,7 +2137,7 @@ void merge_resources(PUCCH_sched_t *res, int num_res, NR_PUCCH_Config_t *pucch_C void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res) { - NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP.pucch_Config; + NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP->pucch_Config; order_resources(pucch, num_res); // following pseudocode in Ref. 38.213 section 9.2.5 to multiplex resources int j = 0; @@ -2215,8 +2222,8 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche int number_harq_feedback = 0; uint32_t dai_max = 0; - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; bool two_transport_blocks = false; int number_of_code_word = 1; @@ -2390,7 +2397,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, int slot) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; @@ -2492,13 +2499,13 @@ int compute_csi_priority(NR_UE_MAC_INST_t *mac, NR_CSI_ReportConfig_t *csirep) int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_BWP_Id_t bwp_id = current_UL_BWP->bwp_id; NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; int num_csi = 0; - if (current_UL_BWP->csi_MeasConfig) { - NR_CSI_MeasConfig_t *csi_measconfig = current_UL_BWP->csi_MeasConfig; + if (mac->sc_info.csi_MeasConfig) { + NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; int csi_priority = INT_MAX; for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ @@ -2867,8 +2874,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, int pos = 0; int fsize = 0; int rnti_type = get_rnti_type(mac, rnti); - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; int N_RB; if(current_DL_BWP) N_RB = get_rb_bwp_dci(dci_format, @@ -2876,8 +2883,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, mac->type0_PDCCH_CSS_config.num_rbs, current_UL_BWP->BWPSize, current_DL_BWP->BWPSize, - current_UL_BWP->initial_BWPSize, - current_DL_BWP->initial_BWPSize); + mac->sc_info.initial_dl_BWPSize, + mac->sc_info.initial_dl_BWPSize); else N_RB = mac->type0_PDCCH_CSS_config.num_rbs; @@ -4156,8 +4163,14 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id) #endif // Schedule Msg3 - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; - NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP, *mac->ra_SS->controlResourceSetId, mac->ra_SS->searchSpaceType->present, NR_RNTI_RA, rar_grant.Msg3_t_alloc); + const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id]; + NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP, + *pdcch_config->ra_SS->controlResourceSetId, + pdcch_config->ra_SS->searchSpaceType->present, + NR_RNTI_RA, + rar_grant.Msg3_t_alloc); if (tda_info.nrOfSymbols == 0) { LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n"); return -1; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index f688d6c2a4a966a5ec8fbc70951de98271659760..5874f8fec9ca8a6f5f54eb7f2067f85090fe728b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -116,7 +116,7 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl //Check if requested on the right slot AssertFatal(is_nr_UL_slot(tdd_config, slot, mac->frame_type) != 0, "UL config_request called at wrong slot %d\n", slot); - int mu = mac->current_UL_BWP.scs; + int mu = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology; const int n = nr_slots_per_frame[mu]; AssertFatal(fb_time < n, "Cannot schedule to a slot more than 1 frame away, ul_config_request is not big enough\n"); AssertFatal(mac->ul_config_request != NULL, "mac->ul_config_request not initialized, logic bug\n"); @@ -135,7 +135,7 @@ fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int sl void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; NR_PUSCH_Config_t *pusch_Config = current_UL_BWP->pusch_Config; @@ -240,7 +240,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ { uint8_t rank = pusch_config_pdu->nrOfLayers; - NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP.pusch_Config; + NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config; AssertFatal(pusch_Config!=NULL,"pusch_Config shouldn't be null\n"); long transformPrecoder = pusch_config_pdu->transform_precoding; @@ -428,7 +428,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, int N_PRB_oh = 0; int rnti_type = get_rnti_type(mac, rnti); - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info; // Common configuration pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; @@ -444,8 +445,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, if (rar_grant) { // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0 - int ibwp_start = current_UL_BWP->initial_BWPStart; - int ibwp_size = current_UL_BWP->initial_BWPSize; + int ibwp_start = sc_info->initial_ul_BWPStart; + int ibwp_size = sc_info->initial_ul_BWPSize; int abwp_start = current_UL_BWP->BWPStart; int abwp_size = current_UL_BWP->BWPSize; int scs = current_UL_BWP->scs; @@ -657,20 +658,17 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->start_symbol_index, mac->dmrs_TypeA_Position); - // Num PRB Overhead from PUSCH-ServingCellConfig - if (current_UL_BWP->pusch_servingcellconfig && current_UL_BWP->pusch_servingcellconfig->xOverhead) - N_PRB_oh = *current_UL_BWP->pusch_servingcellconfig->xOverhead; + if (sc_info->xOverhead_PUSCH) + N_PRB_oh = 6 * (1 + *sc_info->xOverhead_PUSCH); else N_PRB_oh = 0; - if (current_UL_BWP->pusch_servingcellconfig && current_UL_BWP->pusch_servingcellconfig->rateMatching) { - long *maxMIMO_Layers = current_UL_BWP->pusch_servingcellconfig->ext1->maxMIMO_Layers; + if (sc_info->rateMatching_PUSCH) { + long *maxMIMO_Layers = sc_info->maxMIMO_Layers_PUSCH; if (!maxMIMO_Layers) maxMIMO_Layers = pusch_Config ? pusch_Config->maxRank : NULL; AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n"); - pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, - current_UL_BWP->bw_tbslbrm, - *maxMIMO_Layers); + pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, sc_info->ul_bw_tbslbrm, *maxMIMO_Layers); } else pusch_config_pdu->tbslbrm = 0; @@ -749,7 +747,7 @@ void configure_srs_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_srs_pdu *srs_config_pdu, int period, int offset) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; srs_config_pdu->rnti = mac->crnti; srs_config_pdu->handle = 0; @@ -820,7 +818,7 @@ void configure_srs_pdu(NR_UE_MAC_INST_t *mac, // Aperiodic SRS scheduling void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger, int frame, int slot) { - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; if (!srs_config) { @@ -885,7 +883,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo bool srs_scheduled = false; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; @@ -1437,7 +1435,7 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, uint8_t is_Msg3, frame_t curren DURATION_RX_TO_TX); int delta = 0; - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; // Get the numerology to calculate the Tx frame and slot int mu = current_UL_BWP->scs; @@ -1521,7 +1519,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { uint8_t nb_of_frames_per_prach_conf_period; uint8_t prach_conf_period_frame_idx; - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; config_index = rach_ConfigGeneric->prach_ConfigurationIndex; @@ -1530,7 +1528,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { if (setup->msg1_SubcarrierSpacing) mu = *setup->msg1_SubcarrierSpacing; else - mu = mac->current_UL_BWP.scs; + mu = mac->current_UL_BWP->scs; msg1_FDM = rach_ConfigGeneric->msg1_FDM; @@ -1697,12 +1695,12 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { } // Map the transmitted SSBs to the ROs and create the association pattern according to the config -static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { - +static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) +{ // Map SSBs to PRACH occasions // =========================== // WIP: Assumption: No PRACH occasion is rejected because of a conflict with SSBs or TDD_UL_DL_ConfigurationCommon schedule - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB @@ -2002,7 +2000,7 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, // - exact slot number // - frame offset ssb_info_p = &ssb_list->tx_ssb[ssb_idx]; - LOG_D(NR_MAC,"checking for prach : ssb_info_p->nb_mapped_ro %d\n",ssb_info_p->nb_mapped_ro); + LOG_D(NR_MAC, "checking for prach : ssb_info_p->nb_mapped_ro %d\n", ssb_info_p->nb_mapped_ro); for (uint8_t n_mapped_ro=0; n_mapped_ro<ssb_info_p->nb_mapped_ro; n_mapped_ro++) { LOG_D(NR_MAC,"%d.%d: mapped_ro[%d]->frame.slot %d.%d, prach_assoc_pattern.nb_of_frame %d\n", frame,slot,n_mapped_ro,ssb_info_p->mapped_ro[n_mapped_ro]->frame,ssb_info_p->mapped_ro[n_mapped_ro]->slot,prach_assoc_pattern.nb_of_frame); @@ -2016,8 +2014,7 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, } // If there is a matching RO slot in the SSB_to_RO map - if (NULL != prach_occasion_slot_p) - { + if (NULL != prach_occasion_slot_p) { // A random RO mapped to the SSB index should be selected in the slot // First count the number of times the SSB index is found in that RO @@ -2065,8 +2062,8 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, } // Build the SSB to RO mapping upon RRC configuration update -void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) { - +void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) +{ // Clear all the lists and maps memset(&prach_assoc_pattern, 0, sizeof(prach_association_pattern_t)); memset(&mac->ssb_list, 0, sizeof(ssb_list_info_t)); @@ -2157,14 +2154,12 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, vo } } -void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) { - - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; - - if (!current_UL_BWP->csi_MeasConfig) +void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) +{ + if (!mac->sc_info.csi_MeasConfig) return; - NR_CSI_MeasConfig_t *csi_measconfig = current_UL_BWP->csi_MeasConfig; + NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; if (csi_measconfig->csi_IM_ResourceToAddModList == NULL) return; @@ -2173,7 +2168,7 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) { NR_CSI_IM_Resource_t *imcsi; int period, offset; - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; int mu = current_DL_BWP->scs; uint16_t bwp_size = current_DL_BWP->BWPSize; uint16_t bwp_start = current_DL_BWP->BWPStart; @@ -2295,20 +2290,18 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, return meas_bitmap; } -void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) { - - NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; - - if (!current_UL_BWP->csi_MeasConfig) +void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) +{ + if (!mac->sc_info.csi_MeasConfig) return; - NR_CSI_MeasConfig_t *csi_measconfig = current_UL_BWP->csi_MeasConfig; + NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList == NULL) return; fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); - NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; NR_BWP_Id_t dl_bwp_id = current_DL_BWP->bwp_id; int mu = current_DL_BWP->scs; @@ -2446,7 +2439,6 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) { } } - // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x // PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. // - todo: @@ -2470,7 +2462,7 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr fapi_nr_prach_config_t *prach_config = &cfg->prach_config; nr_scheduled_response_t scheduled_response; - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; + NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 04a374a4f6368a2214385acc9b537b91da235eb7..a3743f15563909e52c4f1ac65bd798f17705c514 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -703,6 +703,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common; int mu = ul_bwp->scs; @@ -736,8 +737,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; - const int BWPSize = ul_bwp->initial_BWPSize; - const int BWPStart = ul_bwp->initial_BWPStart; + const int BWPSize = sc_info->initial_ul_BWPSize; + const int BWPStart = sc_info->initial_ul_BWPStart; int rbStart = 0; for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (BWPSize - ra->msg3_nb_rb)); i++) { @@ -825,9 +826,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, dci_pdu_rel15_t uldci_payload; memset(&uldci_payload, 0, sizeof(uldci_payload)); - const NR_SIB1_t *sib1 = cc->sib1 ? cc->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - config_uldci(sib1, - scc, + config_uldci(NULL, pusch_pdu, &uldci_payload, NULL, @@ -836,8 +835,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, 1, // Not toggling NDI in msg3 retransmissions ul_bwp); - fill_dci_pdu_rel15(scc, - ra->CellGroup, + fill_dci_pdu_rel15(sc_info, &ra->DL_BWP, ul_bwp, dci_pdu, @@ -885,6 +883,7 @@ static void nr_get_Msg3alloc(module_id_t module_id, frame_type_t frame_type = mac->common_channels->frame_type; NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; int mu = ul_bwp->scs; int StartSymbolIndex = 0; @@ -962,8 +961,8 @@ static void nr_get_Msg3alloc(module_id_t module_id, const int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, mu, mac->vrb_map_UL_size); uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; - int bwpSize = ul_bwp->initial_BWPSize; - int bwpStart = ul_bwp->initial_BWPStart; + int bwpSize = sc_info->initial_ul_BWPSize; + int bwpStart = sc_info->initial_ul_BWPStart; if (bwpSize != ul_bwp->BWPSize || bwpStart != ul_bwp->BWPStart) { int act_bwp_start = ul_bwp->BWPStart; int act_bwp_size = ul_bwp->BWPSize; @@ -1088,6 +1087,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; if (ra->state == RA_IDLE) { LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -1122,7 +1122,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); - const int ibwp_size = ul_bwp->initial_BWPSize; + const int ibwp_size = sc_info->initial_ul_BWPSize; const int fh = (ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping) ? 1 : 0; const int startSymbolAndLength = ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->startSymbolAndLength; const int mappingtype = ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->mappingType; @@ -1162,6 +1162,7 @@ static void nr_generate_Msg2(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_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; + NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { @@ -1177,7 +1178,7 @@ static void nr_generate_Msg2(module_id_t module_idP, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; if(*ss->controlResourceSetId != 0) { BWPStart = dl_bwp->BWPStart; - BWPSize = dl_bwp->initial_BWPSize; + BWPSize = sc_info->initial_dl_BWPSize; } else { type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; BWPStart = type0_PDCCH_CSS_config->cset_start_rb; @@ -1313,9 +1314,7 @@ static void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->TBSize[0] = TBS; } - pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, - dl_bwp->bw_tbslbrm, - 1); + pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, sc_info->dl_bw_tbslbrm, 1); pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R); // Fill PDCCH DL DCI PDU @@ -1363,8 +1362,7 @@ static void nr_generate_Msg2(module_id_t module_idP, pdcch_pdu_rel15->StartSymbolIndex, pdcch_pdu_rel15->DurationSymbols); - fill_dci_pdu_rel15(scc, - ra->CellGroup, + fill_dci_pdu_rel15(sc_info, dl_bwp, &ra->UL_BWP, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], @@ -1523,9 +1521,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, int x_Overhead = 0; nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); - pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, - dl_bwp->bw_tbslbrm, - 1); + pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, ra->sc_info.dl_bw_tbslbrm, 1); pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(tb_size<<3,R); pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1; @@ -1586,8 +1582,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, pdcch_pdu_rel15->DurationSymbols, pdsch_pdu_rel15->BWPSize); - fill_dci_pdu_rel15(scc, - ra->CellGroup, + fill_dci_pdu_rel15(&ra->sc_info, dl_bwp, &ra->UL_BWP, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], @@ -1600,20 +1595,21 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, 0, // parameter not needed for DCI 1_0 nr_mac->cset0_bwp_size); - LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); - LOG_D(NR_MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart); - LOG_D(NR_MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing); - LOG_D(NR_MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix); - LOG_D(NR_MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex); - LOG_D(NR_MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols); - for(int n=0;n<6;n++) LOG_D(NR_MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]); - LOG_D(NR_MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType); - LOG_D(NR_MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize); - LOG_D(NR_MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize); - LOG_D(NR_MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType); - LOG_D(NR_MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); - LOG_D(NR_MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); - LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); + LOG_D(NR_MAC, "BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); + LOG_D(NR_MAC, "BWPStart: %i\n", pdcch_pdu_rel15->BWPStart); + LOG_D(NR_MAC, "SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing); + LOG_D(NR_MAC, "CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix); + LOG_D(NR_MAC, "StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex); + LOG_D(NR_MAC, "DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols); + for (int n = 0; n < 6; n++) + LOG_D(NR_MAC, "FreqDomainResource[%i]: %x\n", n, pdcch_pdu_rel15->FreqDomainResource[n]); + LOG_D(NR_MAC, "CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType); + LOG_D(NR_MAC, "RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize); + LOG_D(NR_MAC, "InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize); + LOG_D(NR_MAC, "CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType); + LOG_D(NR_MAC, "ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); + LOG_D(NR_MAC, "precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); + LOG_D(NR_MAC, "numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); } static void nr_generate_Msg4(module_id_t module_idP, @@ -1885,18 +1881,17 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s if (harq->is_waiting == 0) { if (harq->round == 0) { - if (UE->Msg4_ACKed) { LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti); UE->ra_timer = 0; - - // Pause scheduling according to: - // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - nr_mac_enable_ue_rrc_processing_timer(RC.nrmac[module_id], UE, false); } else { LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at Msg4!\n", frame, slot, ra->rnti); } + // Pause scheduling according to: + // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs + nr_mac_enable_ue_rrc_processing_timer(RC.nrmac[module_id], UE, false); + nr_clear_ra_proc(module_id, CC_id, frame, ra); if (sched_ctrl->retrans_dl_harq.head >= 0) { remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 47b714fbd013f2bd0bcafb733bb3830de6971f0e..c5b815a7e2346341b1b0b85edd0e5ad83ac46a3f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -495,8 +495,7 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, int dci_format = NR_DL_DCI_FORMAT_1_0; int rnti_type = NR_RNTI_SI; - fill_dci_pdu_rel15(scc, - NULL, + fill_dci_pdu_rel15(NULL, NULL, NULL, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 230ac310e56ae6d3bfa04a744736af3b83b4c311..9a511815bec0888ecfba47857b2551e1ca831c49 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -400,8 +400,8 @@ static void get_start_stop_allocation(gNB_MAC_INST *mac, *rbStop = *rbStart + mac->cset0_bwp_size; } else { - *rbStart = dl_bwp->initial_BWPStart; - *rbStop = *rbStart + dl_bwp->initial_BWPSize; + *rbStart = UE->sc_info.initial_dl_BWPStart; + *rbStop = *rbStart + UE->sc_info.initial_dl_BWPSize; } } } @@ -932,7 +932,6 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; UE->mac_stats.dl.current_bytes = 0; UE->mac_stats.dl.current_rbs = 0; - NR_CellGroupConfig_t *cg = UE->CellGroup; /* update TA and set ta_apply every 10 frames. * Possible improvement: take the periodicity from input file. @@ -1080,15 +1079,14 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index; // TBS_LBRM according to section 5.4.2.1 of 38.212 - // TODO: verify the case where pdsch_servingcellconfig is NULL, in which case + // TODO: verify the case where maxMIMO_Layers is NULL, in which case // in principle maxMIMO_layers should be given by the maximum number of layers // for PDSCH supported by the UE for the serving cell (5.4.2.1 of 38.212) - long maxMIMO_Layers = current_BWP->pdsch_servingcellconfig ? *current_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers : 1; + long maxMIMO_Layers = UE->sc_info.maxMIMO_Layers_PDSCH ? *UE->sc_info.maxMIMO_Layers_PDSCH : 1; const int nl_tbslbrm = min(maxMIMO_Layers, 4); // Maximum number of PRBs across all configured DL BWPs - pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcsTableIdx, - current_BWP->bw_tbslbrm, - nl_tbslbrm); + pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = + nr_compute_tbslbrm(current_BWP->mcsTableIdx, UE->sc_info.dl_bw_tbslbrm, nl_tbslbrm); pdsch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R); NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config; @@ -1139,7 +1137,7 @@ void nr_schedule_ue_spec(module_id_t module_id, memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); // bwp indicator // as per table 7.3.1.1.2-1 in 38.212 - dci_payload.bwp_indicator.val = current_BWP->n_dl_bwp < 4 ? bwp_id : bwp_id - 1; + dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? bwp_id : bwp_id - 1; AssertFatal(pdsch_Config == NULL || pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, "Only frequency resource allocation type 1 is currently supported\n"); @@ -1187,8 +1185,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pucch->timing_indicator); const int rnti_type = NR_RNTI_C; - fill_dci_pdu_rel15(scc, - cg, + fill_dci_pdu_rel15(&UE->sc_info, current_BWP, &UE->current_UL_BWP, dci_pdu, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d72339c11f5fe4cd2b24ae0440c2f7de1096c280..1a5439e29224cc21890932efb134fb8426864998 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -677,16 +677,15 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, return new_mcs; } -void config_uldci(const NR_SIB1_t *sib1, - const NR_ServingCellConfigCommon_t *scc, +void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, nr_srs_feedback_t *srs_feedback, int time_domain_assignment, uint8_t tpc, uint8_t ndi, - NR_UE_UL_BWP_t *ul_bwp) { - + NR_UE_UL_BWP_t *ul_bwp) +{ int bwp_id = ul_bwp->bwp_id; nr_dci_format_t dci_format = ul_bwp->dci_format; @@ -711,13 +710,17 @@ void config_uldci(const NR_SIB1_t *sib1, LOG_D(NR_MAC,"Configuring DCI Format 0_1\n"); dci_pdu_rel15->dai[0].val = 0; //TODO // bwp indicator as per table 7.3.1.1.2-1 in 38.212 - dci_pdu_rel15->bwp_indicator.val = ul_bwp->n_ul_bwp < 4 ? bwp_id : bwp_id - 1; + dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? bwp_id : bwp_id - 1; // SRS resource indicator if (pusch_Config && pusch_Config->txConfig != NULL) { AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook, "Non Codebook configuration non supported\n"); - compute_srs_resource_indicator(ul_bwp->pusch_servingcellconfig, pusch_Config, ul_bwp->srs_Config, srs_feedback, &dci_pdu_rel15->srs_resource_indicator.val); + compute_srs_resource_indicator(sc_info->maxMIMO_Layers_PUSCH, + pusch_Config, + ul_bwp->srs_Config, + srs_feedback, + &dci_pdu_rel15->srs_resource_indicator.val); } compute_precoding_information(pusch_Config, ul_bwp->srs_Config, @@ -1052,10 +1055,12 @@ void set_r_pucch_parms(int rsetindex, *start_symbol_index = default_pucch_firstsymb[rsetindex]; } -void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *current_BWP, const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format) +void prepare_dci(const NR_UE_ServingCell_Info_t *servingCellInfo, + const NR_UE_DL_BWP_t *current_BWP, + const NR_ControlResourceSet_t *coreset, + dci_pdu_rel15_t *dci_pdu_rel15, + nr_dci_format_t format) { - AssertFatal(CellGroup!=NULL,"CellGroup shouldn't be null here\n"); - const NR_PDSCH_Config_t *pdsch_Config = current_BWP ? current_BWP->pdsch_Config : NULL; switch(format) { @@ -1063,10 +1068,10 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *cu // format indicator dci_pdu_rel15->format_indicator = 0; // carrier indicator - if (CellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) + if (servingCellInfo->crossCarrierSchedulingConfig != NULL) AssertFatal(1==0,"Cross Carrier Scheduling Config currently not supported\n"); // supplementary uplink - if (CellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) + if (servingCellInfo->supplementaryUplink != NULL) AssertFatal(1==0,"Supplementary Uplink currently not supported\n"); // SRS request dci_pdu_rel15->srs_request.val = 0; @@ -1076,7 +1081,7 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *cu // format indicator dci_pdu_rel15->format_indicator = 1; // carrier indicator - if (CellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) + if (servingCellInfo->crossCarrierSchedulingConfig != NULL) AssertFatal(1==0,"Cross Carrier Scheduling Config currently not supported\n"); //vrb to prb mapping if (pdsch_Config->vrb_ToPRB_Interleaver==NULL) @@ -1097,10 +1102,9 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *cu if (coreset->tci_PresentInDCI != NULL) AssertFatal(1==0,"TCI in DCI currently not supported\n"); //srs resource set - if (CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching!=NULL) { - NR_SRS_CarrierSwitching_t *cs = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching->choice.setup; - if (cs->srs_TPC_PDCCH_Group!=NULL){ - switch(cs->srs_TPC_PDCCH_Group->present) { + if (servingCellInfo->carrierSwitching) { + if (servingCellInfo->carrierSwitching->srs_TPC_PDCCH_Group) { + switch (servingCellInfo->carrierSwitching->srs_TPC_PDCCH_Group->present) { case NR_SRS_CarrierSwitching__srs_TPC_PDCCH_Group_PR_NOTHING: dci_pdu_rel15->srs_request.val = 0; break; @@ -1111,24 +1115,20 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *cu AssertFatal(1==0,"SRS TPC PRCCH group type B currently not supported\n"); break; } - } - else + } else dci_pdu_rel15->srs_request.val = 0; - } - else + } else dci_pdu_rel15->srs_request.val = 0; // CBGTI and CBGFI - if (current_BWP->pdsch_servingcellconfig && - current_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) - AssertFatal(1==0,"CBG transmission currently not supported\n"); - break; + if (servingCellInfo->pdsch_CGB_Transmission) + AssertFatal(1 == 0, "CBG transmission currently not supported\n"); + break; default : AssertFatal(1==0,"Prepare dci currently only implemented for 1_1 and 0_1 \n"); } } -void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *CellGroup, +void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, const NR_UE_DL_BWP_t *current_DL_BWP, const NR_UE_UL_BWP_t *current_UL_BWP, nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, @@ -1141,7 +1141,6 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, long pdsch_HARQ_ACK_Codebook, uint16_t cset0_bwp_size) { - NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig = NULL; // TODO configure uint8_t fsize = 0, pos = 0; uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload; *dci_pdu = 0; @@ -1153,15 +1152,15 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, cset0_bwp_size, current_UL_BWP->BWPSize, current_DL_BWP->BWPSize, - current_UL_BWP->initial_BWPSize, - current_DL_BWP->initial_BWPSize); + servingCellInfo->initial_ul_BWPSize, + servingCellInfo->initial_dl_BWPSize); // computing alternative size for padding dci_pdu_rel15_t temp_pdu; if(dci_format == NR_DL_DCI_FORMAT_1_0) alt_size = nr_dci_size(current_DL_BWP, current_UL_BWP, - crossCarrierSchedulingConfig, + servingCellInfo, pdsch_HARQ_ACK_Codebook, &temp_pdu, NR_UL_DCI_FORMAT_0_0, @@ -1175,7 +1174,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, if(dci_format == NR_UL_DCI_FORMAT_0_0) alt_size = nr_dci_size(current_DL_BWP, current_UL_BWP, - crossCarrierSchedulingConfig, + servingCellInfo, pdsch_HARQ_ACK_Codebook, &temp_pdu, NR_DL_DCI_FORMAT_1_0, @@ -1192,7 +1191,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, int dci_size = nr_dci_size(current_DL_BWP, current_UL_BWP, - crossCarrierSchedulingConfig, + servingCellInfo, pdsch_HARQ_ACK_Codebook, dci_pdu_rel15, dci_format, @@ -1205,7 +1204,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, pdcch_dci_pdu->PayloadSizeBits = dci_size; AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported"); if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) - prepare_dci(CellGroup, current_DL_BWP, coreset, dci_pdu_rel15, dci_format); + prepare_dci(servingCellInfo, current_DL_BWP, coreset, dci_pdu_rel15, dci_format); /// Payload generation switch (dci_format) { @@ -2021,6 +2020,40 @@ void reset_sched_ctrl(NR_UE_sched_ctrl_t *sched_ctrl) sched_ctrl->srs_feedback.sri = 0; } +int get_dlbw_tbslbrm(int scc_bwpsize, const NR_ServingCellConfig_t *servingCellConfig) +{ + int bw = scc_bwpsize; + if (servingCellConfig) { + if (servingCellConfig->downlinkBWP_ToAddModList) { + const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = servingCellConfig->downlinkBWP_ToAddModList; + for (int i = 0; i < BWP_list->list.count; i++) { + NR_BWP_t genericParameters = BWP_list->list.array[i]->bwp_Common->genericParameters; + int curr_bw = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (curr_bw > bw) + bw = curr_bw; + } + } + } + return bw; +} + +int get_ulbw_tbslbrm(int scc_bwpsize, const NR_ServingCellConfig_t *servingCellConfig) +{ + int bw = scc_bwpsize; + if (servingCellConfig) { + if (servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList) { + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *BWP_list = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; + for (int i = 0; i < BWP_list->list.count; i++) { + NR_BWP_t genericParameters = BWP_list->list.array[i]->bwp_Common->genericParameters; + int curr_bw = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (curr_bw > bw) + bw = curr_bw; + } + } + } + return bw; +} + // main function to configure parameters of current BWP void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, @@ -2033,6 +2066,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, AssertFatal((ra != NULL && UE == NULL) || (ra == NULL && UE != NULL), "RA and UE structures are mutually exlusive in BWP configuration\n"); NR_CellGroupConfig_t *CellGroup; + NR_UE_ServingCell_Info_t *sc_info; NR_UE_DL_BWP_t *DL_BWP; NR_UE_UL_BWP_t *UL_BWP; @@ -2040,19 +2074,21 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, DL_BWP = &ra->DL_BWP; UL_BWP = &ra->UL_BWP; CellGroup = ra->CellGroup; + sc_info = &ra->sc_info; } else { DL_BWP = &UE->current_DL_BWP; UL_BWP = &UE->current_UL_BWP; CellGroup = UE->CellGroup; + sc_info = &UE->sc_info; } NR_BWP_Downlink_t *dl_bwp = NULL; NR_BWP_Uplink_t *ul_bwp = NULL; NR_BWP_DownlinkDedicated_t *bwpd = NULL; NR_BWP_UplinkDedicated_t *ubwpd = NULL; // number of additional BWPs (excluding initial BWP) - DL_BWP->n_dl_bwp = 0; - UL_BWP->n_ul_bwp = 0; + sc_info->n_dl_bwp = 0; + sc_info->n_ul_bwp = 0; int old_dl_bwp_id = DL_BWP->bwp_id; int old_ul_bwp_id = UL_BWP->bwp_id; @@ -2064,11 +2100,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, CellGroup->spCellConfig->spCellConfigDedicated) { servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated; - UL_BWP->supplementaryUplink = servingCellConfig->supplementaryUplink; - DL_BWP->pdsch_servingcellconfig = servingCellConfig->pdsch_ServingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; - UL_BWP->pusch_servingcellconfig = servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->pusch_ServingCellConfig ? - servingCellConfig->uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL; - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; if(dl_bwp_switch >= 0 && ul_bwp_switch >= 0) { @@ -2088,7 +2119,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; if(bwpList) - DL_BWP->n_dl_bwp = bwpList->list.count; + sc_info->n_dl_bwp = bwpList->list.count; if (DL_BWP->bwp_id>0) { for (int i=0; i<bwpList->list.count; i++) { dl_bwp = bwpList->list.array[i]; @@ -2100,7 +2131,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; if(ubwpList) - UL_BWP->n_ul_bwp = ubwpList->list.count; + sc_info->n_ul_bwp = ubwpList->list.count; if (UL_BWP->bwp_id>0) { for (int i=0; i<ubwpList->list.count; i++) { ul_bwp = ubwpList->list.array[i]; @@ -2125,7 +2156,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, UL_BWP->pusch_Config = ubwpd->pusch_Config->choice.setup; UL_BWP->pucch_Config = ubwpd->pucch_Config->choice.setup; UL_BWP->srs_Config = ubwpd->srs_Config->choice.setup; - UL_BWP->csi_MeasConfig = servingCellConfig->csi_MeasConfig ? servingCellConfig->csi_MeasConfig->choice.setup : NULL; } else { DL_BWP->bwp_id = 0; @@ -2134,7 +2164,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, DL_BWP->pdsch_Config = NULL; UL_BWP->pusch_Config = NULL; UL_BWP->pucch_Config = NULL; - UL_BWP->csi_MeasConfig = NULL; UL_BWP->configuredGrantConfig = NULL; } @@ -2163,8 +2192,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, DL_BWP->cyclicprefix = dl_genericParameters.cyclicPrefix; DL_BWP->BWPSize = NRRIV2BW(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); DL_BWP->BWPStart = NRRIV2PRBOFFSET(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - DL_BWP->initial_BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - DL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + sc_info->initial_dl_BWPSize = + NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + sc_info->initial_dl_BWPStart = + NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); NR_BWP_t ul_genericParameters = (UL_BWP->bwp_id > 0 && ul_bwp) ? ul_bwp->bwp_Common->genericParameters: @@ -2174,11 +2205,13 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, UL_BWP->cyclicprefix = ul_genericParameters.cyclicPrefix; UL_BWP->BWPSize = NRRIV2BW(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); UL_BWP->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - UL_BWP->initial_BWPSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - UL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + sc_info->initial_ul_BWPSize = + NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + sc_info->initial_ul_BWPStart = + NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - DL_BWP->bw_tbslbrm = get_dlbw_tbslbrm(DL_BWP->initial_BWPSize, servingCellConfig); - UL_BWP->bw_tbslbrm = get_ulbw_tbslbrm(UL_BWP->initial_BWPSize, servingCellConfig); + sc_info->dl_bw_tbslbrm = get_dlbw_tbslbrm(sc_info->initial_dl_BWPSize, servingCellConfig); + sc_info->dl_bw_tbslbrm = get_ulbw_tbslbrm(sc_info->initial_ul_BWPSize, servingCellConfig); if (UL_BWP->bwp_id > 0) { UL_BWP->pucch_ConfigCommon = ul_bwp->bwp_Common->pucch_ConfigCommon ? ul_bwp->bwp_Common->pucch_ConfigCommon->choice.setup : NULL; @@ -2189,6 +2222,38 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, } if(UE) { + if (servingCellConfig) { + if (servingCellConfig->csi_MeasConfig) { + sc_info->csi_MeasConfig = servingCellConfig->csi_MeasConfig->choice.setup; + compute_csi_bitlen(sc_info->csi_MeasConfig, UE->csi_report_template); + } + if (servingCellConfig->pdsch_ServingCellConfig && servingCellConfig->pdsch_ServingCellConfig->choice.setup) { + NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = servingCellConfig->pdsch_ServingCellConfig->choice.setup; + sc_info->nrofHARQ_ProcessesForPDSCH = pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH; + if (pdsch_servingcellconfig->ext1) + sc_info->maxMIMO_Layers_PDSCH = pdsch_servingcellconfig->ext1->maxMIMO_Layers; + if (pdsch_servingcellconfig->codeBlockGroupTransmission + && pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup) + sc_info->pdsch_CGB_Transmission = pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup; + } + sc_info->crossCarrierSchedulingConfig = servingCellConfig->crossCarrierSchedulingConfig; + sc_info->supplementaryUplink = servingCellConfig->supplementaryUplink; + if (servingCellConfig->uplinkConfig) { + if (servingCellConfig->uplinkConfig->carrierSwitching) + sc_info->carrierSwitching = servingCellConfig->uplinkConfig->carrierSwitching->choice.setup; + if (servingCellConfig->uplinkConfig->pusch_ServingCellConfig + && servingCellConfig->uplinkConfig->pusch_ServingCellConfig->choice.setup) { + NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig = + servingCellConfig->uplinkConfig->pusch_ServingCellConfig->choice.setup; + if (pusch_servingcellconfig->ext1) + sc_info->maxMIMO_Layers_PUSCH = pusch_servingcellconfig->ext1->maxMIMO_Layers; + sc_info->rateMatching_PUSCH = pusch_servingcellconfig->rateMatching; + if (pusch_servingcellconfig->codeBlockGroupTransmission + && pusch_servingcellconfig->codeBlockGroupTransmission->choice.setup) + sc_info->pusch_CGB_Transmission = pusch_servingcellconfig->codeBlockGroupTransmission->choice.setup; + } + } + } if (CellGroup && CellGroup->physicalCellGroupConfig) UE->pdsch_HARQ_ACK_Codebook = CellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook; @@ -2226,9 +2291,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0; - if (UL_BWP->csi_MeasConfig) - compute_csi_bitlen (UL_BWP->csi_MeasConfig, UE->csi_report_template); - set_max_fb_time(UL_BWP, DL_BWP); set_sched_pucch_list(sched_ctrl, UL_BWP, scc); } @@ -2303,7 +2365,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf // We will attach at the end, to mitigate race conditions // This is not good, but we will fix it progressively - NR_UE_info_t *UE=calloc(1,sizeof(NR_UE_info_t)); + NR_UE_info_t *UE = calloc(1, sizeof(NR_UE_info_t)); if(!UE) { LOG_E(NR_MAC,"want to add UE %04x but the fixed allocated size is full\n",rntiP); return NULL; @@ -2337,9 +2399,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf sched_ctrl->sched_pusch.time_domain_allocation = -1; /* Set default BWPs */ - AssertFatal(ul_bwp->n_ul_bwp <= NR_MAX_NUM_BWP, - "uplinkBWP_ToAddModList has %d BWP!\n", - ul_bwp->n_ul_bwp); + AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp); if (get_softmodem_params()->phy_test == 0) { UE->ra_timer = 12000 << UE->current_DL_BWP.scs; // 12000 ms is arbitrary and found to be a good timeout from experiments @@ -2347,7 +2407,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf /* get Number of HARQ processes for this UE */ // pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes - create_dl_harq_list(sched_ctrl, dl_bwp->pdsch_servingcellconfig); + create_dl_harq_list(sched_ctrl, &UE->sc_info); // add all available UL HARQ processes for this UE // nb of ul harq processes not configurable create_nr_list(&sched_ctrl->available_ul_harq, 16); @@ -2409,10 +2469,10 @@ void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl) free(sched_ctrl->sched_pucch); } -void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, - const NR_PDSCH_ServingCellConfig_t *pdsch) { - const int nrofHARQ = pdsch && pdsch->nrofHARQ_ProcessesForPDSCH ? - get_nrofHARQ_ProcessesForPDSCH(*pdsch->nrofHARQ_ProcessesForPDSCH) : 8; +void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) +{ + const int nrofHARQ = + sc_info && sc_info->nrofHARQ_ProcessesForPDSCH ? get_nrofHARQ_ProcessesForPDSCH(*sc_info->nrofHARQ_ProcessesForPDSCH) : 8; // add all available DL HARQ processes for this UE AssertFatal(sched_ctrl->available_dl_harq.len == sched_ctrl->feedback_dl_harq.len && sched_ctrl->available_dl_harq.len == sched_ctrl->retrans_dl_harq.len, @@ -2552,7 +2612,6 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo UE_iterator(UE_info->list, UE) { NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; - NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; // CSI-RS is common to all UEs in a given BWP // therefore we need to schedule only once per BWP @@ -2565,9 +2624,10 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo continue; } - if (!ul_bwp->csi_MeasConfig) continue; + if (!UE->sc_info.csi_MeasConfig) + continue; - NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; + NR_CSI_MeasConfig_t *csi_measconfig = UE->sc_info.csi_MeasConfig; // looking for the correct CSI-RS resource in current BWP NR_NZP_CSI_RS_ResourceSetId_t *nzp = NULL; @@ -2810,7 +2870,7 @@ static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t if (get_softmodem_params()->sa) { // add all available DL HARQ processes for this UE in SA - create_dl_harq_list(sched_ctrl, UE->current_DL_BWP.pdsch_servingcellconfig); + create_dl_harq_list(sched_ctrl, &UE->sc_info); } } @@ -2904,8 +2964,17 @@ void nr_mac_update_timers(module_id_t module_id, if (UE->ra_timer > 0) { UE->ra_timer--; if (UE->ra_timer == 0) { - LOG_W(NR_MAC, "Removing UE %04x because RA timer expired\n", UE->rnti); - mac_remove_nr_ue(mac, UE->rnti); + const rnti_t rnti = UE->rnti; + LOG_W(NR_MAC, "Removing UE %04x because RA timer expired\n", rnti); + mac_remove_nr_ue(mac, rnti); + NR_COMMON_channels_t *cc = &mac->common_channels[0]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + if (cc->ra[i].rnti == rnti) { + nr_clear_ra_proc(module_id, 0, frame, &cc->ra[i]); + } + } + // don't skip a UE, current UE does not exist anymore + UE--; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 30d06ef2a847439951692000620f3e9fdd4e3037..220ce9aef2de84129594660e409ddabf828fbaa2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -212,8 +212,9 @@ void nr_csi_meas_reporting(int Mod_idP, if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test)) { continue; } - const NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; - if (!csi_measconfig) continue; + const NR_CSI_MeasConfig_t *csi_measconfig = UE->sc_info.csi_MeasConfig; + if (!csi_measconfig) + continue; AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0, "NO CSI report configuration available"); NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; @@ -496,7 +497,7 @@ static void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) uint8_t i, j; //bwp indicator - int n_dl_bwp = dl_bwp->n_dl_bwp; + int n_dl_bwp = UE->sc_info.n_dl_bwp; const int bwp_id = dl_bwp->bwp_id; if (n_dl_bwp < 4) pdsch_bwp_id = bwp_id; @@ -1051,8 +1052,8 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, return; } - NR_CSI_MeasConfig_t *csi_MeasConfig = UE->current_UL_BWP.csi_MeasConfig; - if (csi_MeasConfig==NULL) { + NR_CSI_MeasConfig_t *csi_MeasConfig = UE->sc_info.csi_MeasConfig; + if (csi_MeasConfig == NULL) { NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 448c4e94f0a3f896c8cc0ab6c13c88aee8454903..fbef1dd18b572ddeeef9ecbd8af568bc55a0e0c8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2075,13 +2075,11 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon; NR_UEs_t *UE_info = &nr_mac->UE_info; - const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; UE_iterator( UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) continue; - NR_CellGroupConfig_t *cg = UE->CellGroup; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; UE->mac_stats.ul.current_bytes = 0; @@ -2281,19 +2279,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n pusch_pdu->pusch_data.num_cb = 0; //CBG not supported pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(sched_pusch->tb_size<<3,sched_pusch->R); - if(current_BWP->pusch_servingcellconfig && - current_BWP->pusch_servingcellconfig->rateMatching) { + + NR_UE_ServingCell_Info_t *sc_info = &UE->sc_info; + if (sc_info->rateMatching_PUSCH) { // TBS_LBRM according to section 5.4.2.1 of 38.212 - long *maxMIMO_Layers = current_BWP->pusch_servingcellconfig->ext1->maxMIMO_Layers; + long *maxMIMO_Layers = sc_info->maxMIMO_Layers_PUSCH; if (!maxMIMO_Layers) maxMIMO_Layers = current_BWP->pusch_Config->maxRank; AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n"); - pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcs_table, - current_BWP->bw_tbslbrm, - *maxMIMO_Layers); - } - else - pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = 0; + pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = + nr_compute_tbslbrm(current_BWP->mcs_table, sc_info->ul_bw_tbslbrm, *maxMIMO_Layers); + } else + pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = 0; LOG_D(NR_MAC,"PUSCH PDU : data_scrambling_identity %x, dmrs_scrambling_id %x\n",pusch_pdu->data_scrambling_id,pusch_pdu->ul_dmrs_scrambling_id); /* TRANSFORM PRECODING --------------------------------------------------------*/ @@ -2373,8 +2370,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n dci_pdu_rel15_t uldci_payload; memset(&uldci_payload, 0, sizeof(uldci_payload)); - config_uldci(sib1, - scc, + config_uldci(&UE->sc_info, pusch_pdu, &uldci_payload, &sched_ctrl->srs_feedback, @@ -2383,8 +2379,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n cur_harq->ndi, current_BWP); - fill_dci_pdu_rel15(scc, - cg, + fill_dci_pdu_rel15(&UE->sc_info, &UE->current_DL_BWP, current_BWP, dci_pdu, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 9e8d9c396bc6cee933bff13c452d8b6bc7a8c8bc..0e9dae192fe46e07b7ed4ac739b1bb400f6f4fee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -142,9 +142,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, sub_frame_t slot, const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234); - -void config_uldci(const NR_SIB1_t *sib1, - const NR_ServingCellConfigCommon_t *scc, +void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, nr_srs_feedback_t *srs_feedback, @@ -225,8 +223,7 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac, int first_cce, int aggregation); -void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *CellGroup, +void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, const NR_UE_DL_BWP_t *current_DL_BWP, const NR_UE_UL_BWP_t *current_UL_BWP, nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, @@ -239,7 +236,11 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, long pdsch_HARQ_ACK_Codebook, uint16_t cset0_bwp_size); -void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *current_BWP, const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format); +void prepare_dci(const NR_UE_ServingCell_Info_t *servingCellInfo, + const NR_UE_DL_BWP_t *current_BWP, + const NR_ControlResourceSet_t *coreset, + dci_pdu_rel15_t *dci_pdu_rel15, + nr_dci_format_t format); void set_r_pucch_parms(int rsetindex, int r_pucch, @@ -353,8 +354,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint8_t ul_cqi, const uint16_t rssi); -void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, - const NR_PDSCH_ServingCellConfig_t *pdsch); +void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info); void reset_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index c1313a495e47b272fa0870bd96055b3190827ec6..ab7977d4dcef9d89d767be57830b1a52e0d2a403 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -24,7 +24,6 @@ #include "mac_proto.h" #include "openair2/F1AP/f1ap_ids.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" -#include "openair2/RRC/NR/MESSAGES/asn1_msg.h" #include "F1AP_CauseRadioNetwork.h" #include "uper_decoder.h" @@ -225,7 +224,7 @@ static NR_UE_NR_Capability_t *get_ue_nr_cap(int rnti, uint8_t *buf, uint32_t len return cap; } -static NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig) +NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig) { uint8_t buf[16636]; asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, orig, buf, sizeof(buf)); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 32759b304f18e7bcec07d9d071df0be01337ac14..c91f07e623936522c8e5cd2d0f2dbd613a334acd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -24,10 +24,11 @@ #include "platform_types.h" #include "f1ap_messages_types.h" +#include "openair2/RRC/NR/MESSAGES/asn1_msg.h" void f1_setup_response(const f1ap_setup_resp_t *resp); void f1_setup_failure(const f1ap_setup_failure_t *failure); - +NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig); void ue_context_setup_request(const f1ap_ue_context_setup_t *req); void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req); void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e3437f3c9a72fbf9737e2da8fb4a9a3f98b9b0ba..042d17c89904eb05320c6ad39828312e09ddc461 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -228,6 +228,7 @@ typedef struct { // BWP for RA NR_UE_DL_BWP_t DL_BWP; NR_UE_UL_BWP_t UL_BWP; + NR_UE_ServingCell_Info_t sc_info; } NR_RA_t; /*! \brief gNB common channels */ @@ -699,6 +700,7 @@ typedef struct { NR_UE_sched_ctrl_t UE_sched_ctrl; NR_UE_DL_BWP_t current_DL_BWP; NR_UE_UL_BWP_t current_UL_BWP; + NR_UE_ServingCell_Info_t sc_info; NR_mac_stats_t mac_stats; /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index c7de394f79543f9f09f2150433bf069e92ad5c6c..56d58430480d31a232494e32a4984c532ca45d28 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -171,15 +171,20 @@ NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int ss->nrofCandidates = calloc(1,sizeof(*ss->nrofCandidates)); // TODO temporary hardcoded implementation ss->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; - if (is_common) { + if (get_softmodem_params()->usim_test) { ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1; + } else { + if (is_common) { + ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + } else { + ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n2; + ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0; + } + ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; } - else { - ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n2; - ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0; - } - ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; ss->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; ss->searchSpaceType = calloc(1,sizeof(*ss->searchSpaceType)); if (is_common) {