// Blind search for SI/P/RA-RNTI static int find_dl_dci_type_siprarnti(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]) { int ret = 0; srslte_dci_cfg_t* dci_cfg = &cfg->dci_cfg; // Configure and run DCI blind search dci_blind_search_t search_space; search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, sf->cfi); INFO("Searching SI/P/RA-RNTI in %d common locations, %d formats, tti=%d, cfi=%d, rnti=0x%x\n", search_space.nof_locations, nof_common_formats, sf->tti, sf->cfi, rnti); // Search for RNTI only if there is room for the common search space if (search_space.nof_locations > 0) { for (uint32_t f = 0; f < nof_common_formats; f++) { search_space.format = common_formats[f]; if ((ret = dci_blind_search(q, sf, rnti, &search_space, dci_cfg, dci_msg))) { return ret; } } } return SRSLTE_SUCCESS; }
// 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* cfg, uint16_t rnti, srslte_dci_msg_t dci_msg[SRSLTE_MAX_DCI_MSG]) { int ret = SRSLTE_SUCCESS; dci_blind_search_t search_space; dci_blind_search_t* current_ss = &search_space; uint32_t sf_idx = sf->tti % 10; uint32_t cfi = sf->cfi; srslte_dci_cfg_t* dci_cfg = &cfg->dci_cfg; // Search UE-specific search space if (q->pregen_rnti == rnti) { current_ss = &q->current_ss_ue[MI_IDX(sf_idx)][cfi - 1][sf_idx]; } else { // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_ue_locations(&q->pdcch, sf, current_ss->loc, MAX_CANDIDATES_UE, rnti); } if (cfg->cfg.tm > SRSLTE_TM8) { ERROR("Searching DL CRNTI: Invalid TM=%d\n", cfg->cfg.tm + 1); } for (int f = 0; f < 2; f++) { srslte_dci_format_t format = ue_dci_formats[cfg->cfg.tm][f]; INFO("Searching DL C-RNTI %s in %d ue locations\n", srslte_dci_format_string(format), current_ss->nof_locations); current_ss->format = format; if ((ret = dci_blind_search(q, sf, rnti, current_ss, dci_cfg, dci_msg))) { return ret; } } // Search Format 1A in the Common SS also if (q->pregen_rnti == rnti) { current_ss = &q->current_ss_common[MI_IDX(sf_idx)][cfi - 1]; } else { // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_common_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_COM, cfi); } // Search for RNTI only if there is room for the common search space if (current_ss->nof_locations > 0) { current_ss->format = SRSLTE_DCI_FORMAT1A; INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", current_ss->nof_locations); return dci_blind_search(q, sf, rnti, current_ss, dci_cfg, dci_msg); } return SRSLTE_SUCCESS; }
/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while * to execute, so shall be called once the final C-RNTI has been allocated for the session. * For the connection procedure, use srslte_pusch_encode_rnti() or srslte_pusch_decode_rnti() functions */ void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q, uint16_t rnti) { srslte_pdsch_set_rnti(&q->pdsch, rnti); // Compute UE-specific and Common search space for this RNTI for (int cfi=0;cfi<3;cfi++) { for (int sf_idx=0;sf_idx<10;sf_idx++) { q->current_ss_ue[cfi][sf_idx].nof_locations = srslte_pdcch_ue_locations(&q->pdcch, q->current_ss_ue[cfi][sf_idx].loc, MAX_CANDIDATES_UE, sf_idx, cfi+1, rnti); } q->current_ss_common[cfi].nof_locations = srslte_pdcch_common_locations(&q->pdcch, q->current_ss_common[cfi].loc, MAX_CANDIDATES_COM, cfi+1); } q->current_rnti = rnti; }
int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, srslte_rnti_type_t rnti_type) { srslte_dci_location_t locations[MAX_CANDIDATES]; uint32_t nof_locations; uint32_t nof_formats; srslte_dci_format_t *formats = NULL; /* Generate PDCCH candidates */ if (rnti_type == SRSLTE_RNTI_SI || rnti_type == SRSLTE_RNTI_PCH || rnti_type == SRSLTE_RNTI_RAR) { nof_locations = srslte_pdcch_common_locations(&q->pdcch, locations, MAX_CANDIDATES, q->cfi); formats = common_formats; nof_formats = nof_common_formats; } else { nof_locations = srslte_pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, q->cfi, rnti); formats = ue_formats; nof_formats = nof_ue_formats; } uint16_t crc_rem = 0; for (int f=0;f<nof_formats && crc_rem != rnti;f++) { for (int i=0;i<nof_locations && crc_rem != rnti;i++) { DEBUG("Trying format %s (nbits=%d), location L=%d, ncce=%d\n", srslte_dci_format_string(formats[f]), srslte_dci_format_sizeof_lut(formats[f], q->cell.nof_prb), locations[i].L, locations[i].ncce); q->last_n_cce = locations[i].ncce; if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &locations[i], formats[f], &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } if (crc_rem == rnti) { INFO("Found DCI nCCE: %d, L: %d, n_bits=%d\n", locations[i].ncce, locations[i].L, srslte_dci_format_sizeof_lut(formats[f], q->cell.nof_prb)); memcpy(&q->last_location, &locations[i], sizeof(srslte_dci_location_t)); } if (crc_rem == rnti && formats[f] == SRSLTE_DCI_FORMAT1A && dci_msg->data[0] != 1) { /* Save Format 0 msg. Recovered next call to srslte_ue_dl_find_ul_dci() */ q->pending_ul_dci_rnti = crc_rem; memcpy(&q->pending_ul_dci_msg, dci_msg, sizeof(srslte_dci_msg_t)); crc_rem = 0; } DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem); } } if (crc_rem == rnti) { return 1; } else { INFO("Couldn't find any DCI for RNTI=0x%x\n", rnti); return 0; } }
// Blind search for C-RNTI static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, uint32_t tm, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, srslte_dci_msg_t *dci_msg) { int ret = SRSLTE_SUCCESS; dci_blind_search_t search_space; dci_blind_search_t *current_ss = &search_space; if (cfi < 1 || cfi > 3) { ERROR("CFI must be 1 ≤ cfi ≤ 3 (cfi=%d)", cfi); return SRSLTE_ERROR; } // Search UE-specific search space if (q->current_rnti == rnti) { current_ss = &q->current_ss_ue[cfi-1][sf_idx]; } else { // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_ue_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_UE, sf_idx, cfi, rnti); } for (int f = 0; f < 2; f++) { srslte_dci_format_t format = ue_dci_formats[tm][f]; INFO("Searching DL C-RNTI %s in %d ue locations\n", srslte_dci_format_string(format), current_ss->nof_locations); current_ss->format = format; if ((ret = dci_blind_search(q, current_ss, rnti, cfi, dci_msg))) { return ret; } } // Search Format 1A in the Common SS also if (q->current_rnti == rnti) { current_ss = &q->current_ss_common[cfi-1]; } else { // If locations are not pre-generated, generate them now current_ss->nof_locations = srslte_pdcch_common_locations(&q->pdcch, current_ss->loc, MAX_CANDIDATES_COM, cfi); } // Search for RNTI only if there is room for the common search space if (current_ss->nof_locations > 0) { current_ss->format = SRSLTE_DCI_FORMAT1A; INFO("Searching DL C-RNTI in %d ue locations, format 1A\n", current_ss->nof_locations); return dci_blind_search(q, current_ss, rnti, cfi, dci_msg); } return SRSLTE_SUCCESS; }
// Blind search for SI/P/RA-RNTI static int find_dl_dci_type_siprarnti(srslte_ue_dl_t *q, uint32_t cfi, uint16_t rnti, srslte_dci_msg_t *dci_msg) { int ret = 0; // Configure and run DCI blind search dci_blind_search_t search_space; search_space.nof_locations = srslte_pdcch_common_locations(&q->pdcch, search_space.loc, MAX_CANDIDATES_COM, cfi); INFO("Searching SI/P/RA-RNTI in %d common locations, %d formats\n", search_space.nof_locations, nof_common_formats); // Search for RNTI only if there is room for the common search space if (search_space.nof_locations > 0) { for (int f=0;f<nof_common_formats;f++) { search_space.format = common_formats[f]; if ((ret = dci_blind_search(q, &search_space, rnti, cfi, dci_msg))) { return ret; } } } return SRSLTE_SUCCESS; }
int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) { srslte_dci_location_t locations[MAX_CANDIDATES]; uint32_t nof_locations; uint32_t nof_formats; srslte_dci_format_t *formats = NULL; /* Generate PDCCH candidates */ if (rnti == SRSLTE_SIRNTI) { nof_locations = srslte_pdcch_common_locations(&q->pdcch, locations, MAX_CANDIDATES, q->cfi); formats = common_formats; nof_formats = nof_common_formats; } else { nof_locations = srslte_pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, q->cfi, rnti); formats = ue_formats; nof_formats = nof_ue_formats; } uint16_t crc_rem = 0; for (int f=0;f<nof_formats && crc_rem != rnti;f++) { INFO("Trying format %s\n", srslte_dci_format_string(formats[f])); for (int i=0;i<nof_locations && crc_rem != rnti;i++) { q->last_n_cce = locations[i].ncce; if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &locations[i], formats[f], &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } if (formats[f] == SRSLTE_DCI_FORMAT1A) { if (dci_msg->data[0] != 1) { crc_rem = 0; } } DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem); } } if (crc_rem == rnti) { return 1; } else { return 0; } }
/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while * to execute, so shall be called once the final C-RNTI has been allocated for the session. * For the connection procedure, use srslte_pusch_encode_rnti() or srslte_pusch_decode_rnti() functions */ void srslte_ue_dl_set_rnti(srslte_ue_dl_t* q, uint16_t rnti) { srslte_pdsch_set_rnti(&q->pdsch, rnti); srslte_dl_sf_cfg_t sf_cfg; ZERO_OBJECT(sf_cfg); // Compute UE-specific and Common search space for this RNTI for (int i = 0; i < MI_NOF_REGS; i++) { srslte_pdcch_set_regs(&q->pdcch, &q->regs[i]); for (int cfi = 0; cfi < 3; cfi++) { sf_cfg.cfi = cfi + 1; for (int sf_idx = 0; sf_idx < 10; sf_idx++) { sf_cfg.tti = sf_idx; q->current_ss_ue[i][cfi][sf_idx].nof_locations = srslte_pdcch_ue_locations( &q->pdcch, &sf_cfg, q->current_ss_ue[i][cfi][sf_idx].loc, MAX_CANDIDATES_UE, rnti); } q->current_ss_common[i][cfi].nof_locations = srslte_pdcch_common_locations(&q->pdcch, q->current_ss_common[i][cfi].loc, MAX_CANDIDATES_COM, cfi + 1); } } q->pregen_rnti = rnti; }
int main(int argc, char **argv) { srslte_ra_dl_dci_t ra_dl; int i; int frame_cnt; int ret; srslte_dci_location_t locations[MAX_CANDIDATES]; uint32_t nof_locations; srslte_dci_msg_t dci_msg; if (argc < 3) { usage(argv[0]); exit(-1); } parse_args(argc,argv); if (base_init()) { fprintf(stderr, "Error initializing memory\n"); exit(-1); } ret = -1; frame_cnt = 0; do { srslte_filesource_read(&fsrc, input_buffer, flen); INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); /* Get channel estimates for each port */ srslte_chest_dl_estimate(&chest, fft_buffer, ce, frame_cnt %10); uint16_t crc_rem = 0; if (srslte_pdcch_extract_llr(&pdcch, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest), frame_cnt %10, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return -1; } if (rnti == SRSLTE_SIRNTI) { INFO("Initializing common search space for SI-RNTI\n",0); nof_locations = srslte_pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi); } else { INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti); nof_locations = srslte_pdcch_ue_locations(&pdcch, locations, MAX_CANDIDATES, frame_cnt %10, cfi, rnti); } for (i=0;i<nof_locations && crc_rem != rnti;i++) { if (srslte_pdcch_decode_msg(&pdcch, &dci_msg, &locations[i], dci_format, &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); return -1; } } if (crc_rem == rnti) { srslte_dci_msg_type_t type; if (srslte_dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti)) { fprintf(stderr, "Can't get DCI message type\n"); exit(-1); } printf("MSG %d: ",i); srslte_dci_msg_type_fprint(stdout, type); switch(type.type) { case SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED: bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t)); if (srslte_dci_msg_unpack_pdsch(&dci_msg, &ra_dl, cell.nof_prb, rnti != SRSLTE_SIRNTI)) { fprintf(stderr, "Can't unpack DCI message\n"); } else { srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); if (ra_dl.alloc_type == SRSLTE_RA_ALLOC_TYPE2 && ra_dl.type2_alloc.mode == SRSLTE_RA_TYPE2_LOC && ra_dl.type2_alloc.riv == 11 && ra_dl.rv_idx == 0 && ra_dl.harq_process == 0 && ra_dl.mcs_idx == 2) { printf("This is the file signal.1.92M.amar.dat\n"); ret = 0; } } break; default: fprintf(stderr, "Unsupported message type\n"); break; } } frame_cnt++; } while (frame_cnt <= max_frames); base_free(); exit(ret); }