From 51521ad8e446017e4ba5ec85d4b77dddf7a64b89 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 28 Aug 2020 22:29:54 +0200 Subject: [PATCH] Improved PDCCH blind search and fixed a few issues with ambiguous DCI size with Release 10 --- lib/include/srslte/phy/enb/enb_dl.h | 5 + lib/include/srslte/phy/phch/dci.h | 6 + lib/include/srslte/phy/ue/ue_dl.h | 7 +- lib/src/phy/enb/enb_dl.c | 12 ++ lib/src/phy/phch/dci.c | 49 +++++- lib/src/phy/phch/pdcch.c | 22 +-- lib/src/phy/ue/ue_dl.c | 253 +++++++++++++++++----------- srsenb/src/phy/cc_worker.cc | 17 ++ srsue/src/phy/cc_worker.cc | 2 + srsue/src/phy/sf_worker.cc | 7 +- 10 files changed, 258 insertions(+), 122 deletions(-) diff --git a/lib/include/srslte/phy/enb/enb_dl.h b/lib/include/srslte/phy/enb/enb_dl.h index efe525e6a..e9c98c429 100644 --- a/lib/include/srslte/phy/enb/enb_dl.h +++ b/lib/include/srslte/phy/enb/enb_dl.h @@ -84,6 +84,9 @@ typedef struct SRSLTE_API { float sss_signal0[SRSLTE_SSS_LEN]; float sss_signal5[SRSLTE_SSS_LEN]; + uint32_t nof_common_locations[3]; + srslte_dci_location_t common_locations[3][MAX_CANDIDATES_COM]; + } srslte_enb_dl_t; typedef struct { @@ -103,6 +106,8 @@ SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t* q, uint16_t rnti); SRSLTE_API void srslte_enb_dl_rem_rnti(srslte_enb_dl_t* q, uint16_t rnti); +SRSLTE_API bool srslte_enb_dl_location_is_common_ncce(srslte_enb_dl_t* q, uint32_t ncce); + SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t* q, srslte_dl_sf_cfg_t* dl_sf); SRSLTE_API void srslte_enb_dl_put_phich(srslte_enb_dl_t* q, srslte_phich_grant_t* grant, bool ack); diff --git a/lib/include/srslte/phy/phch/dci.h b/lib/include/srslte/phy/phch/dci.h index 6d263ffbd..6cfe3e2e2 100644 --- a/lib/include/srslte/phy/phch/dci.h +++ b/lib/include/srslte/phy/phch/dci.h @@ -234,10 +234,16 @@ SRSLTE_API char* srslte_dci_format_string(srslte_dci_format_t format); SRSLTE_API char* srslte_dci_format_string_short(srslte_dci_format_t format); +SRSLTE_API bool srslte_location_find(srslte_dci_location_t* locations, uint32_t nof_locations, srslte_dci_location_t x); + +SRSLTE_API bool srslte_location_find_ncce(srslte_dci_location_t* locations, uint32_t nof_locations, uint32_t ncce); + SRSLTE_API int srslte_dci_location_set(srslte_dci_location_t* c, uint32_t L, uint32_t nCCE); SRSLTE_API bool srslte_dci_location_isvalid(srslte_dci_location_t* c); +SRSLTE_API void srslte_dci_cfg_set_common_ss(srslte_dci_cfg_t* cfg); + SRSLTE_API uint32_t srslte_dci_format_max_tb(srslte_dci_format_t format); #endif // DCI_ diff --git a/lib/include/srslte/phy/ue/ue_dl.h b/lib/include/srslte/phy/ue/ue_dl.h index e4d5152fd..f0651dd4e 100644 --- a/lib/include/srslte/phy/ue/ue_dl.h +++ b/lib/include/srslte/phy/ue/ue_dl.h @@ -60,15 +60,18 @@ #define MAX_CANDIDATES_COM 6 // From 36.213 Table 9.1.1-1 #define MAX_CANDIDATES (MAX_CANDIDATES_UE + MAX_CANDIDATES_COM) +#define MAX_FORMATS 4 + #define MI_NOF_REGS ((q->cell.frame_type == SRSLTE_FDD) ? 1 : 6) #define MI_MAX_REGS 6 #define SRSLTE_MAX_DCI_MSG SRSLTE_MAX_CARRIERS typedef struct SRSLTE_API { - srslte_dci_format_t format; + srslte_dci_format_t formats[MAX_FORMATS]; srslte_dci_location_t loc[MAX_CANDIDATES]; uint32_t nof_locations; + uint32_t nof_formats; } dci_blind_search_t; typedef struct SRSLTE_API { @@ -105,6 +108,8 @@ typedef struct SRSLTE_API { srslte_dci_msg_t pending_ul_dci_msg[SRSLTE_MAX_DCI_MSG]; uint32_t pending_ul_dci_count; + srslte_dci_location_t allocated_locations[SRSLTE_MAX_DCI_MSG]; + uint32_t nof_allocated_locations; } srslte_ue_dl_t; // Downlink config (includes common and dedicated variables) diff --git a/lib/src/phy/enb/enb_dl.c b/lib/src/phy/enb/enb_dl.c index 592182ba1..ce65bdb14 100644 --- a/lib/src/phy/enb/enb_dl.c +++ b/lib/src/phy/enb/enb_dl.c @@ -217,6 +217,12 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t* q, srslte_cell_t cell) /* Generate PSS/SSS signals */ srslte_pss_generate(q->pss_signal, cell.id % 3); srslte_sss_generate(q->sss_signal0, q->sss_signal5, cell.id); + + // Calculate common DCI locations + for (int32_t cfi = 1; cfi <= 3; cfi++) { + q->nof_common_locations[cfi - 1] = + srslte_pdcch_common_locations(&q->pdcch, q->common_locations[cfi - 1], MAX_CANDIDATES_COM, cfi); + } } ret = SRSLTE_SUCCESS; @@ -363,6 +369,12 @@ void srslte_enb_dl_put_phich(srslte_enb_dl_t* q, srslte_phich_grant_t* grant, bo srslte_phich_encode(&q->phich, &q->dl_sf, resource, ack, q->sf_symbols); } +bool srslte_enb_dl_location_is_common_ncce(srslte_enb_dl_t* q, uint32_t ncce) +{ + return srslte_location_find_ncce( + q->common_locations[q->dl_sf.cfi - 1], q->nof_common_locations[q->dl_sf.cfi - 1], ncce); +} + int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t* q, srslte_dci_cfg_t* dci_cfg, srslte_dci_dl_t* dci_dl) { srslte_dci_msg_t dci_msg; diff --git a/lib/src/phy/phch/dci.c b/lib/src/phy/phch/dci.c index a6440c3a2..4f86ab9c0 100644 --- a/lib/src/phy/phch/dci.c +++ b/lib/src/phy/phch/dci.c @@ -1346,7 +1346,15 @@ int srslte_dci_msg_pack_pusch(srslte_cell_t* cell, cfg = &_dci_cfg; } - return dci_format0_pack(cell, sf, cfg, dci, msg); + int n = dci_format0_pack(cell, sf, cfg, dci, msg); + +#if SRSLTE_DCI_HEXDEBUG + dci->hex_str[0] = '\0'; + srslte_vec_sprint_hex(dci->hex_str, sizeof(dci->hex_str), msg->payload, msg->nof_bits); + dci->nof_bits = msg->nof_bits; +#endif /* SRSLTE_DCI_HEXDEBUG */ + + return n; } int srslte_dci_msg_unpack_pusch(srslte_cell_t* cell, @@ -1377,6 +1385,33 @@ int srslte_dci_msg_unpack_pusch(srslte_cell_t* cell, return dci_format0_unpack(cell, sf, cfg, msg, dci); } +bool srslte_location_find(srslte_dci_location_t* locations, uint32_t nof_locations, srslte_dci_location_t x) +{ + for (uint32_t i = 0; i < nof_locations; i++) { + if (locations[i].L == x.L && locations[i].ncce == x.ncce) { + return true; + } + } + return false; +} + +bool srslte_location_find_ncce(srslte_dci_location_t* locations, uint32_t nof_locations, uint32_t ncce) +{ + for (uint32_t i = 0; i < nof_locations; i++) { + if (locations[i].ncce == ncce) { + return true; + } + } + return false; +} + +// Set the configuration for Format0/1A messages allocated on Common SS +void srslte_dci_cfg_set_common_ss(srslte_dci_cfg_t* cfg) +{ + cfg->srs_request_enabled = false; + cfg->multiple_csi_request_enabled = false; +} + int srslte_dci_location_set(srslte_dci_location_t* c, uint32_t L, uint32_t nCCE) { if (L <= 3) { @@ -1593,10 +1628,6 @@ uint32_t srslte_dci_dl_info(const srslte_dci_dl_t* dci_dl, char* info_str, uint3 dci_dl->location.ncce, dci_dl->location.L); -#if SRSLTE_DCI_HEXDEBUG - n = srslte_print_check(info_str, len, n, ", len=%d, hex=%s", dci_dl->nof_bits, dci_dl->hex_str); -#endif /* SRSLTE_DCI_HEXDEBUG */ - if (dci_dl->cif_present) { n = srslte_print_check(info_str, len, n, ", cif=%d", dci_dl->cif); } @@ -1643,6 +1674,10 @@ uint32_t srslte_dci_dl_info(const srslte_dci_dl_t* dci_dl, char* info_str, uint3 n = srslte_print_check(info_str, len, n, ", tb_sw=%d, pinfo=%d", dci_dl->tb_cw_swap, dci_dl->pinfo); } +#if SRSLTE_DCI_HEXDEBUG + n = srslte_print_check(info_str, len, n, ", len=%d, hex=%s", dci_dl->nof_bits, dci_dl->hex_str); +#endif /* SRSLTE_DCI_HEXDEBUG */ + return n; } @@ -1685,6 +1720,10 @@ uint32_t srslte_dci_ul_info(srslte_dci_ul_t* dci_ul, char* info_str, uint32_t le n = srslte_print_check(info_str, len, n, ", ul_idx=%d, dai=%d", dci_ul->ul_idx, dci_ul->dai); } +#if SRSLTE_DCI_HEXDEBUG + n = srslte_print_check(info_str, len, n, ", len=%d, hex=%s", dci_ul->nof_bits, dci_ul->hex_str); +#endif /* SRSLTE_DCI_HEXDEBUG */ + return n; } diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index b1c5fe680..e39045b65 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -249,8 +249,8 @@ uint32_t srslte_pdcch_ue_locations_ncce_L(uint32_t nof_cce, } k = 0; - // All aggregation levels from 8 to 1 - for (l = 3; l >= 0; l--) { + // All aggregation levels from 1 to 8 + for (l = 0; l <= 3; l++) { L = (1 << l); if (Ls < 0 || Ls == L) { // For all candidates as given in table 9.1.1-1 @@ -309,7 +309,7 @@ uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_locatio uint32_t i, l, L, k; k = 0; - for (l = 3; l > 1; l--) { + for (l = 2; l <= 3; l++) { L = (1 << l); for (i = 0; i < SRSLTE_MIN(nof_cce, 16) / (L); i++) { // Simplified expression, derived from: @@ -405,15 +405,15 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t* q, srslte_dl_sf_cfg_t* sf, srslte_dc } else { ERROR("Error calling pdcch_dci_decode\n"); } - DEBUG("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x\n", - msg->location.ncce, - msg->location.L, - srslte_dci_format_string(msg->format), - nof_bits, - mean, - msg->rnti); + INFO("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x\n", + msg->location.ncce, + msg->location.L, + srslte_dci_format_string(msg->format), + nof_bits, + mean, + msg->rnti); } else { - DEBUG( + INFO( "Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f\n", msg->location.ncce, msg->location.L, nof_bits, mean); } } diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 18de0cf86..3aef95e94 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -38,6 +38,8 @@ const static srslte_dci_format_t ue_dci_formats[8][2] = { /* Mode 7 */ {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1}, /* Mode 8 */ {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT2B}}; +const uint32_t nof_ue_dci_formats = 2; + static srslte_dci_format_t common_formats[] = {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1C}; const uint32_t nof_common_formats = 2; @@ -431,57 +433,119 @@ static bool find_dci(srslte_dci_msg_t* dci_msg, uint32_t nof_dci_msg, srslte_dci return found; } +static bool dci_location_is_allocated(srslte_ue_dl_t* q, srslte_dci_location_t new_loc) +{ + for (uint32_t i = 0; i < q->nof_allocated_locations; i++) { + uint32_t L = q->allocated_locations[i].L; + uint32_t ncce = q->allocated_locations[i].ncce; + if ((ncce <= new_loc.ncce && new_loc.ncce < ncce + L) || // if new location starts in within an existing allocation + (new_loc.ncce <= ncce && + ncce < new_loc.ncce + new_loc.L)) { // or an existing allocation starts within the new location + return true; + } + } + return false; +} + static int dci_blind_search(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, uint16_t rnti, dci_blind_search_t* search_space, srslte_dci_cfg_t* dci_cfg, - srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG]) + srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG], + bool search_in_common) { uint32_t nof_dci = 0; if (rnti) { - int i = 0; - while ((dci_cfg->cif_enabled || !nof_dci) && (i < search_space->nof_locations) && (nof_dci < SRSLTE_MAX_DCI_MSG)) { - DEBUG("Searching format %s in %d,%d (%d/%d)\n", - srslte_dci_format_string(search_space->format), - search_space->loc[i].ncce, - search_space->loc[i].L, - i, - search_space->nof_locations); - - dci_msg[nof_dci].location = search_space->loc[i]; - dci_msg[nof_dci].format = search_space->format; - dci_msg[nof_dci].rnti = 0; - if (srslte_pdcch_decode_msg(&q->pdcch, sf, dci_cfg, &dci_msg[nof_dci])) { - ERROR("Error decoding DCI msg\n"); - return SRSLTE_ERROR; + for (int l = 0; l < search_space->nof_locations; l++) { + if (nof_dci >= SRSLTE_MAX_DCI_MSG) { + ERROR("Can't store more DCIs in buffer\n"); + return nof_dci; } + if (dci_location_is_allocated(q, search_space->loc[l])) { + INFO("Skipping location L=%d, ncce=%d. Already allocated\n", search_space->loc[l].L, search_space->loc[l].ncce); + continue; + } + for (uint32_t f = 0; f < search_space->nof_formats; f++) { + INFO("Searching format %s in %d,%d (%d/%d)\n", + srslte_dci_format_string(search_space->formats[f]), + search_space->loc[l].ncce, + search_space->loc[l].L, + l, + search_space->nof_locations); - if ((dci_msg[nof_dci].rnti == rnti) && (dci_msg[nof_dci].nof_bits > 0)) { + // Try to decode a valid DCI msg + dci_msg[nof_dci].location = search_space->loc[l]; + dci_msg[nof_dci].format = search_space->formats[f]; + dci_msg[nof_dci].rnti = 0; + if (srslte_pdcch_decode_msg(&q->pdcch, sf, dci_cfg, &dci_msg[nof_dci])) { + ERROR("Error decoding DCI msg\n"); + return SRSLTE_ERROR; + } - dci_msg[nof_dci].rnti = rnti; - // If searching for Format1A but found Format0 save it for later - if (dci_msg[nof_dci].format == SRSLTE_DCI_FORMAT0 && search_space->format == SRSLTE_DCI_FORMAT1A) { - /* If there is space for accumulate another UL DCI dci and it was not detected before, then store it */ - if (q->pending_ul_dci_count < SRSLTE_MAX_CARRIERS && - !find_dci(q->pending_ul_dci_msg, q->pending_ul_dci_count, &dci_msg[nof_dci])) { - srslte_dci_msg_t* pending_ul_dci_msg = &q->pending_ul_dci_msg[q->pending_ul_dci_count]; - pending_ul_dci_msg->format = dci_msg[nof_dci].format; - pending_ul_dci_msg->location = dci_msg[nof_dci].location; - pending_ul_dci_msg->nof_bits = dci_msg[nof_dci].nof_bits; - pending_ul_dci_msg->rnti = dci_msg[nof_dci].rnti; - memcpy(pending_ul_dci_msg->payload, dci_msg[nof_dci].payload, dci_msg[nof_dci].nof_bits); - q->pending_ul_dci_count++; + if ((dci_msg[nof_dci].rnti == rnti) && (dci_msg[nof_dci].nof_bits > 0)) { + dci_msg[nof_dci].rnti = rnti; + + // Look for the messages found and apply the new format if the location is common + if (search_in_common && (dci_cfg->multiple_csi_request_enabled || dci_cfg->srs_request_enabled)) { + uint32_t sf_idx = sf->tti % 10; + uint32_t cfi = sf->cfi; + + /* + * A UE configured to monitor PDCCH candidates whose CRCs are scrambled with C-RNTI or SPS C-RNTI, + * with a common payload size and with the same first CCE index ncce, but with different sets of DCI + * information fields in the common and UE-specific search spaces on the primary cell, is required to assume + * that only the PDCCH in the common search space is transmitted by the primary cell. + */ + INFO("checking if msg=%d, ncce=%d belongs to common\n", nof_dci, dci_msg[nof_dci].location.ncce); + // Find a matching ncce in the common SS + if (srslte_location_find_ncce(q->current_ss_common[MI_IDX(sf_idx)][cfi - 1].loc, + q->current_ss_common[MI_IDX(sf_idx)][cfi - 1].nof_locations, + dci_msg[nof_dci].location.ncce)) { + srslte_dci_cfg_t cfg = *dci_cfg; + srslte_dci_cfg_set_common_ss(&cfg); + INFO("checking if size of msg (%d) is equal to size of format1a (%d)\n", + dci_msg[nof_dci].nof_bits, + srslte_dci_format_sizeof(&q->cell, sf, &cfg, SRSLTE_DCI_FORMAT1A)); + // if the payload size is the same that it would have in the common SS (only Format0/1A is allowed there) + if (dci_msg[nof_dci].nof_bits == srslte_dci_format_sizeof(&q->cell, sf, &cfg, SRSLTE_DCI_FORMAT1A)) { + // assume that only the PDDCH is transmitted, therefore update the format to 0/1A + dci_msg[nof_dci].format = dci_msg[nof_dci].payload[0] + ? SRSLTE_DCI_FORMAT1A + : SRSLTE_DCI_FORMAT0; // Format0/1A bit indicator is the MSB + INFO("DCI msg found in location L=%d, ncce=%d, size=%d belongs to the common SS and is format %s\n", + dci_msg[nof_dci].location.L, + dci_msg[nof_dci].location.ncce, + dci_msg[nof_dci].nof_bits, + srslte_dci_format_string_short(dci_msg[nof_dci].format)); + } + } } - // Else if we found it, save location and keep going if required - } else if (dci_msg[nof_dci].format == search_space->format) { - /* Check if the DCI is duplicated */ - if (!find_dci(dci_msg, (uint32_t)nof_dci, &dci_msg[nof_dci])) { + + // If found a Format0, save it for later + if (dci_msg[nof_dci].format == SRSLTE_DCI_FORMAT0) { + // If there is space for accumulate another UL DCI dci and it was not detected before, then store it + if (q->pending_ul_dci_count < SRSLTE_MAX_DCI_MSG && + !find_dci(q->pending_ul_dci_msg, q->pending_ul_dci_count, &dci_msg[nof_dci])) { + srslte_dci_msg_t* pending_ul_dci_msg = &q->pending_ul_dci_msg[q->pending_ul_dci_count]; + *pending_ul_dci_msg = dci_msg[nof_dci]; + q->pending_ul_dci_count++; + } + /* Check if the DCI is duplicated */ + } else if (!find_dci(dci_msg, (uint32_t)nof_dci, &dci_msg[nof_dci]) && + !find_dci(q->pending_ul_dci_msg, q->pending_ul_dci_count, &dci_msg[nof_dci])) { + // Save message and continue with next location + if (q->nof_allocated_locations <= SRSLTE_MAX_DCI_MSG) { + q->allocated_locations[q->nof_allocated_locations] = dci_msg[nof_dci].location; + q->nof_allocated_locations++; + } nof_dci++; + break; + } else { + INFO("Ignoring message with size %d, already decoded\n", dci_msg[nof_dci].nof_bits); } } } - i++; } } else { ERROR("RNTI not specified\n"); @@ -489,16 +553,15 @@ static int dci_blind_search(srslte_ue_dl_t* q, return nof_dci; } -static int find_dci_ue_ss(srslte_ue_dl_t* q, - srslte_dl_sf_cfg_t* sf, - srslte_ue_dl_cfg_t* cfg, - uint16_t rnti, - srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG], - const srslte_dci_format_t* formats, - uint32_t nof_formats, - bool is_ue) +static int find_dci_ss(srslte_ue_dl_t* q, + srslte_dl_sf_cfg_t* sf, + srslte_ue_dl_cfg_t* cfg, + uint16_t rnti, + srslte_dci_msg_t* dci_msg, + const srslte_dci_format_t* formats, + uint32_t nof_formats, + bool is_ue) { - int ret = SRSLTE_SUCCESS; dci_blind_search_t search_space = {}; dci_blind_search_t* current_ss = &search_space; @@ -516,8 +579,7 @@ static int find_dci_ue_ss(srslte_ue_dl_t* q, } } else { // Disable extended CSI request and SRS request in common SS - dci_cfg.multiple_csi_request_enabled = false; - dci_cfg.srs_request_enabled = false; + srslte_dci_cfg_set_common_ss(&dci_cfg); if (q->pregen_rnti == rnti) { current_ss = &q->current_ss_common[MI_IDX(sf_idx)][cfi - 1]; @@ -528,24 +590,23 @@ static int find_dci_ue_ss(srslte_ue_dl_t* q, } // Search for DCI in the SS - if (current_ss->nof_locations > 0) { - for (int f = 0; f < nof_formats; f++) { - srslte_dci_format_t format = formats[f]; + current_ss->nof_formats = nof_formats; + memcpy(current_ss->formats, formats, nof_formats * sizeof(srslte_dci_format_t)); - INFO("Searching DCI format=%s in %d locations in %s SS\n", - srslte_dci_format_string(format), - current_ss->nof_locations, - is_ue ? "ue" : "common"); + INFO("Searching %d formats in %d locations in %s SS, csi=%d\n", + nof_formats, + current_ss->nof_locations, + is_ue ? "ue" : "common", + dci_cfg.multiple_csi_request_enabled); - current_ss->format = format; - if ((ret = dci_blind_search(q, sf, rnti, current_ss, &dci_cfg, dci_msg))) { - return ret; - } - } - } - return SRSLTE_SUCCESS; + return dci_blind_search(q, sf, rnti, current_ss, &dci_cfg, dci_msg, cfg->cfg.dci_common_ss); } +/* + * Note: This function does not perform a DCI search. It just copies the Format0 messages from the + * pending_ul_dci_msg buffer found during a call to srslte_ue_dl_find_dl_dci(). + * It is assumed that the user called srslte_ue_dl_find_dl_dci() prior to calling this function. + */ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srslte_ue_dl_cfg_t* dl_cfg, @@ -554,34 +615,12 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t* q, { srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG]; uint32_t nof_msg = 0; - int ret = 0; if (rnti) { - /* Do not search if an UL DCI is already pending */ - if (q->pending_ul_dci_count) { - nof_msg = SRSLTE_MIN(SRSLTE_MAX_DCI_MSG, q->pending_ul_dci_count); - q->pending_ul_dci_count = 0; - memcpy(dci_msg, q->pending_ul_dci_msg, sizeof(srslte_dci_msg_t) * nof_msg); - } else { - - set_mi_value(q, sf, dl_cfg); - - srslte_dci_format_t ul_format = SRSLTE_DCI_FORMAT0; - - // Search first on the UE-specific SS to avoid ambiguity on DCI sizes - // Search UE-specific search space - if ((ret = find_dci_ue_ss(q, sf, dl_cfg, rnti, dci_msg, &ul_format, 1, true)) < 0) { - return SRSLTE_ERROR; - } - - // Search common SS if no DCI present in UE SS - if (ret == 0 && dl_cfg->cfg.dci_common_ss) { - if ((ret = find_dci_ue_ss(q, sf, dl_cfg, rnti, dci_msg, &ul_format, 1, false)) < 0) { - return SRSLTE_ERROR; - } - } - nof_msg = (uint32_t)ret; - } + // Copy the messages found in the last call to srslte_ue_dl_find_dl_dci() + nof_msg = SRSLTE_MIN(SRSLTE_MAX_DCI_MSG, q->pending_ul_dci_count); + memcpy(dci_msg, q->pending_ul_dci_msg, sizeof(srslte_dci_msg_t) * nof_msg); + q->pending_ul_dci_count = 0; // Unpack DCI messages for (uint32_t i = 0; i < nof_msg; i++) { @@ -605,15 +644,15 @@ static int find_dl_dci_type_siprarnti(srslte_ue_dl_t* q, uint16_t rnti, srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG]) { - return find_dci_ue_ss(q, sf, dl_cfg, rnti, dci_msg, common_formats, nof_common_formats, false); + return find_dci_ss(q, sf, dl_cfg, rnti, dci_msg, common_formats, nof_common_formats, false); } // Blind search for C-RNTI -static int find_dl_dci_type_crnti(srslte_ue_dl_t* q, - srslte_dl_sf_cfg_t* sf, - srslte_ue_dl_cfg_t* dl_cfg, - uint16_t rnti, - srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG]) +static int find_dl_ul_dci_type_crnti(srslte_ue_dl_t* q, + srslte_dl_sf_cfg_t* sf, + srslte_ue_dl_cfg_t* dl_cfg, + uint16_t rnti, + srslte_dci_msg_t* dci_msg) { int ret = SRSLTE_SUCCESS; @@ -622,21 +661,31 @@ static int find_dl_dci_type_crnti(srslte_ue_dl_t* q, return SRSLTE_ERROR; } - // Search first on the UE-specific SS to avoid ambiguity on DCI sizes + int nof_dci_msg = 0; + + // Although the common SS has higher priority than the UE, we'll start the search with UE space + // since has the smallest aggregation levels. With the messages found in the UE space, we'll + // check if they belong to the common SS and change the format if needed + // Search UE-specific search space - if ((ret = find_dci_ue_ss(q, sf, dl_cfg, rnti, dci_msg, ue_dci_formats[dl_cfg->cfg.tm], 2, true))) { + if ((ret = find_dci_ss(q, sf, dl_cfg, rnti, dci_msg, ue_dci_formats[dl_cfg->cfg.tm], nof_ue_dci_formats, true)) < 0) { return ret; } - // Search common SS if no DCI present in UE SS + nof_dci_msg += ret; + + // Search common SS if (dl_cfg->cfg.dci_common_ss) { - srslte_dci_format_t common_format = SRSLTE_DCI_FORMAT1A; - if ((ret = find_dci_ue_ss(q, sf, dl_cfg, rnti, dci_msg, &common_format, 1, false))) { + + // Search only for SRSLTE_DCI_FORMAT1A (1st in common_formats) when looking for C-RNTI + ret = 0; + if ((ret = find_dci_ss(q, sf, dl_cfg, rnti, &dci_msg[nof_dci_msg], common_formats, 1, false)) < 0) { return ret; } + nof_dci_msg += ret; } - return SRSLTE_SUCCESS; + return nof_dci_msg; } int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t* q, @@ -649,11 +698,17 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t* q, srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG] = {}; + // Reset pending UL grants on each call + q->pending_ul_dci_count = 0; + + // Reset allocated DCI locations + q->nof_allocated_locations = 0; + int nof_msg = 0; if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || SRSLTE_RNTI_ISRAR(rnti)) { nof_msg = find_dl_dci_type_siprarnti(q, sf, dl_cfg, rnti, dci_msg); } else { - nof_msg = find_dl_dci_type_crnti(q, sf, dl_cfg, rnti, dci_msg); + nof_msg = find_dl_ul_dci_type_crnti(q, sf, dl_cfg, rnti, dci_msg); } if (nof_msg < 0) { diff --git a/srsenb/src/phy/cc_worker.cc b/srsenb/src/phy/cc_worker.cc index 84420a502..886528d61 100644 --- a/srsenb/src/phy/cc_worker.cc +++ b/srsenb/src/phy/cc_worker.cc @@ -449,6 +449,15 @@ int cc_worker::encode_pdcch_ul(stack_interface_phy_lte::ul_sched_grant_t* grants for (uint32_t i = 0; i < nof_grants; i++) { if (grants[i].needs_pdcch) { srslte_dci_cfg_t dci_cfg = phy->ue_db.get_dci_ul_config(grants[i].dci.rnti, cc_idx); + + if (SRSLTE_RNTI_ISUSER(grants[i].dci.rnti)) { + if (srslte_enb_dl_location_is_common_ncce(&enb_dl, grants[i].dci.location.ncce) && + phy->ue_db.is_pcell(grants[i].dci.rnti, cc_idx)) { + // Disable extended CSI request and SRS request in common SS + srslte_dci_cfg_set_common_ss(&dci_cfg); + } + } + if (srslte_enb_dl_put_pdcch_ul(&enb_dl, &dci_cfg, &grants[i].dci)) { ERROR("Error putting PUSCH %d\n", i); return SRSLTE_ERROR; @@ -471,6 +480,14 @@ int cc_worker::encode_pdcch_dl(stack_interface_phy_lte::dl_sched_grant_t* grants uint16_t rnti = grants[i].dci.rnti; if (rnti) { srslte_dci_cfg_t dci_cfg = phy->ue_db.get_dci_dl_config(grants[i].dci.rnti, cc_idx); + + if (SRSLTE_RNTI_ISUSER(grants[i].dci.rnti) && grants[i].dci.format == SRSLTE_DCI_FORMAT1A) { + if (srslte_enb_dl_location_is_common_ncce(&enb_dl, grants[i].dci.location.ncce) && + grants[i].dci.format == SRSLTE_DCI_FORMAT1A && phy->ue_db.is_pcell(grants[i].dci.rnti, cc_idx)) { + srslte_dci_cfg_set_common_ss(&dci_cfg); + } + } + if (srslte_enb_dl_put_pdcch_dl(&enb_dl, &dci_cfg, &grants[i].dci)) { ERROR("Error putting PDCCH %d\n", i); return SRSLTE_ERROR; diff --git a/srsue/src/phy/cc_worker.cc b/srsue/src/phy/cc_worker.cc index d661f6621..cfd1408c7 100644 --- a/srsue/src/phy/cc_worker.cc +++ b/srsue/src/phy/cc_worker.cc @@ -376,6 +376,7 @@ int cc_worker::decode_pdcch_dl() for (int i = 0; i < (ue_dl_cfg.cfg.dci.cif_present ? 2 : 1) && !nof_grants; i++) { Debug("PDCCH looking for rnti=0x%x\n", dl_rnti); ue_dl_cfg.cfg.dci.cif_enabled = i > 0; + ue_dl_cfg.cfg.dci_common_ss = (cc_idx == 0); nof_grants = srslte_ue_dl_find_dl_dci(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, dl_rnti, dci); if (nof_grants < 0) { Error("Looking for DL grants\n"); @@ -745,6 +746,7 @@ int cc_worker::decode_pdcch_ul() /* Blind search first without cross scheduling then with it if enabled */ for (int i = 0; i < (ue_dl_cfg.cfg.dci.cif_present ? 2 : 1) && !nof_grants; i++) { ue_dl_cfg.cfg.dci.cif_enabled = i > 0; + ue_dl_cfg.cfg.dci_common_ss = (cc_idx == 0); nof_grants = srslte_ue_dl_find_ul_dci(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, ul_rnti, dci); if (nof_grants < 0) { Error("Looking for UL grants\n"); diff --git a/srsue/src/phy/sf_worker.cc b/srsue/src/phy/sf_worker.cc index f8bc40843..a73514d07 100644 --- a/srsue/src/phy/sf_worker.cc +++ b/srsue/src/phy/sf_worker.cc @@ -184,15 +184,10 @@ void sf_worker::set_config(uint32_t cc_idx, srslte::phy_cfg_t& phy_cfg) std::lock_guard lock(mutex); if (cc_idx < cc_workers.size()) { Info("Setting configuration for worker=%d, cc=%d\n", get_id(), cc_idx); - // Search common SS in PCell only - if (cc_idx > 0) { - phy_cfg.dl_cfg.dci_common_ss = true; - } cc_workers[cc_idx]->set_config(phy_cfg); if (cc_idx > 0) { // Update DCI config for PCell - srslte_dci_cfg_t dci_cfg = phy_cfg.dl_cfg.dci; - cc_workers[0]->upd_config_dci(dci_cfg); + cc_workers[0]->upd_config_dci(phy_cfg.dl_cfg.dci); } } else { Error("Setting config for cc=%d; Invalid cc_idx\n", cc_idx);