diff --git a/srslte/include/srslte/enb/enb_dl.h b/srslte/include/srslte/enb/enb_dl.h index 578a52350..3e9a6153d 100644 --- a/srslte/include/srslte/enb/enb_dl.h +++ b/srslte/include/srslte/enb/enb_dl.h @@ -76,7 +76,6 @@ typedef struct SRSLTE_API { srslte_refsignal_cs_t csr_signal; srslte_pdsch_cfg_t pdsch_cfg; - srslte_softbuffer_tx_t softbuffer; srslte_ra_dl_dci_t dl_dci; srslte_dci_format_t dci_format; @@ -86,17 +85,24 @@ typedef struct SRSLTE_API { float sss_signal0[SRSLTE_SSS_LEN]; float sss_signal5[SRSLTE_SSS_LEN]; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; + + srslte_softbuffer_tx_t *softbuffer; + uint32_t nof_rnti; } srslte_enb_dl_t; typedef struct { - bool is_dl; - srslte_ra_dci_grant_t grant; - srslte_dci_location_t location; - uint32_t rnti_idx; - uint32_t rv_idx; - uint8_t *data; -} srslte_enb_dl_grant_t; + uint32_t rnti_idx; + srslte_ra_dl_dci_t grant; + srslte_dci_location_t location; + uint8_t *data; +} srslte_enb_dl_grant_pdsch_t; + +typedef struct { + uint32_t rnti_idx; + srslte_ra_ul_dci_t grant; + srslte_dci_location_t location; +} srslte_enb_dl_grant_pusch_t; /* This function shall be called just after the initial synchronization */ @@ -156,10 +162,14 @@ SRSLTE_API int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, uint32_t rnti_idx, uint32_t sf_idx); -SRSLTE_API int srslte_enb_dl_put_grant(srslte_enb_dl_t *q, - srslte_enb_dl_grant_t *grants, - uint32_t nof_grants, - uint32_t sf_idx); +SRSLTE_API int srslte_enb_dl_put_grant_pdsch(srslte_enb_dl_t *q, + srslte_enb_dl_grant_pdsch_t *grants, + uint32_t nof_grants, + uint32_t sf_idx); +SRSLTE_API int srslte_enb_dl_put_grant_pusch(srslte_enb_dl_t *q, + srslte_enb_dl_grant_pusch_t *grants, + uint32_t nof_grants, + uint32_t sf_idx); #endif diff --git a/srslte/include/srslte/phch/dci.h b/srslte/include/srslte/phch/dci.h index 1d9bdd365..3edbac392 100644 --- a/srslte/include/srslte/phch/dci.h +++ b/srslte/include/srslte/phch/dci.h @@ -116,6 +116,9 @@ SRSLTE_API int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, SRSLTE_API void srslte_dci_rar_grant_unpack(srslte_dci_rar_grant_t *rar, uint8_t grant[SRSLTE_RAR_GRANT_LEN]); +SRSLTE_API void srslte_dci_rar_grant_pack(srslte_dci_rar_grant_t *rar, + uint8_t grant[SRSLTE_RAR_GRANT_LEN]); + SRSLTE_API void srslte_dci_rar_grant_fprint(FILE *stream, srslte_dci_rar_grant_t *rar); diff --git a/srslte/include/srslte/phch/pdcch.h b/srslte/include/srslte/phch/pdcch.h index d65c32dc2..10b6f9fa5 100644 --- a/srslte/include/srslte/phch/pdcch.h +++ b/srslte/include/srslte/phch/pdcch.h @@ -122,6 +122,11 @@ SRSLTE_API uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, uint32_t cfi, uint16_t rnti); +SRSLTE_API uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, + srslte_dci_location_t *c, + uint32_t max_candidates, + uint32_t nsubframe, uint16_t rnti); + /* Function for generation of common search space DCI locations */ SRSLTE_API uint32_t srslte_pdcch_common_locations(srslte_pdcch_t *q, srslte_dci_location_t *locations, @@ -132,4 +137,5 @@ SRSLTE_API uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_location_t *c, uint32_t max_candidates); + #endif diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index a4e95d81f..05562d7cf 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -178,11 +178,6 @@ typedef union { srslte_ra_dl_grant_t dl; } srslte_phy_grant_t; -typedef union { - srslte_ra_ul_dci_t ul; - srslte_ra_dl_dci_t dl; -} srslte_ra_dci_grant_t; - #define SRSLTE_PHY_GRANT_LEN sizeof(srslte_phy_grant_t) @@ -226,6 +221,8 @@ SRSLTE_API int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, SRSLTE_API int srslte_ra_tbs_idx_from_mcs(uint32_t mcs); +SRSLTE_API int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx); + SRSLTE_API int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb); diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index e66969cf5..a0dfd0d21 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -50,6 +50,7 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti q->cell = cell; q->cfi = 3; + q->nof_rnti = nof_rnti; if (srslte_ofdm_tx_init(&q->ifft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -90,9 +91,9 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell, uint32_t nof_rnti goto clean_exit; } - if (srslte_softbuffer_tx_init(&q->softbuffer, q->cell.nof_prb)) { - fprintf(stderr, "Error initiating soft buffer\n"); - goto clean_exit; + q->softbuffer = malloc(nof_rnti*sizeof(srslte_softbuffer_tx_t)); + for (int i=0;isoftbuffer[i], q->cell.nof_prb); } if (srslte_refsignal_cs_init(&q->csr_signal, q->cell)) { @@ -138,7 +139,13 @@ void srslte_enb_dl_free(srslte_enb_dl_t *q) srslte_pdsch_free(&q->pdsch); srslte_refsignal_cs_free(&q->csr_signal); - srslte_softbuffer_tx_free(&q->softbuffer); + + if (q->softbuffer) { + for (int i=0;inof_rnti;i++) { + srslte_softbuffer_tx_free(&q->softbuffer[i]); + } + free(q->softbuffer); + } for (int i=0;isf_symbols[i]) { @@ -271,55 +278,64 @@ int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, fprintf(stderr, "Error configuring PDSCH\n"); return SRSLTE_ERROR; } + + // Reset softwbuffer if this is the first transmission + if (data == NULL) { + srslte_softbuffer_tx_reset_cb(&q->softbuffer[rnti_idx], q->pdsch_cfg.cb_segm.C); + } /* Encode PDSCH */ - if (srslte_pdsch_encode_rnti_idx(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, data, rnti_idx, q->sf_symbols)) { + if (srslte_pdsch_encode_rnti_idx(&q->pdsch, &q->pdsch_cfg, &q->softbuffer[rnti_idx], data, rnti_idx, q->sf_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } -int srslte_enb_dl_put_grant(srslte_enb_dl_t *q, srslte_enb_dl_grant_t *grants, uint32_t nof_grants, uint32_t sf_idx) +int srslte_enb_dl_put_grant_pusch(srslte_enb_dl_t *q, srslte_enb_dl_grant_pusch_t *grants, uint32_t nof_grants, uint32_t sf_idx) { for (int i=0;ipdsch, grants[i].rnti_idx); + } + return SRSLTE_SUCCESS; +} - bool rnti_is_user = true; - if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || rnti == SRSLTE_MRNTI) { - rnti_is_user = false; - } - srslte_ra_dl_grant_t phy_grant; - srslte_ra_dl_dci_to_grant(&grants[i].grant.dl, q->cell.nof_prb, rnti_is_user, &phy_grant); - if (srslte_enb_dl_put_pdsch(q, &phy_grant, grants[i].rnti_idx, grants[i].rv_idx, sf_idx, grants[i].data)) { - fprintf(stderr, "Error putting PDCCH %d\n",i); - return SRSLTE_ERROR; - } +int srslte_enb_dl_put_grant_pdsch(srslte_enb_dl_t *q, srslte_enb_dl_grant_pdsch_t *grants, uint32_t nof_grants, uint32_t sf_idx) +{ + for (int i=0;ipdsch, grants[i].rnti_idx); + + bool rnti_is_user = true; + if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || rnti == SRSLTE_MRNTI) { + rnti_is_user = false; + } + srslte_ra_dl_grant_t phy_grant; + srslte_ra_dl_dci_to_grant(&grants[i].grant, q->cell.nof_prb, rnti_is_user, &phy_grant); + if (srslte_enb_dl_put_pdsch(q, &phy_grant, grants[i].rnti_idx, grants[i].grant.rv_idx, sf_idx, + grants[i].data)) + { + fprintf(stderr, "Error putting PDCCH %d\n",i); + return SRSLTE_ERROR; } } return SRSLTE_SUCCESS; -} +} \ No newline at end of file diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 719e3c5d0..342b21d7f 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -149,6 +149,18 @@ void srslte_dci_rar_grant_unpack(srslte_dci_rar_grant_t *rar, uint8_t grant[SRSL rar->cqi_request = srslte_bit_pack(&grant_ptr, 1)?true:false; } +/* Pack RAR UL grant as defined in Section 6.2 of 36.213 */ +void srslte_dci_rar_grant_pack(srslte_dci_rar_grant_t *rar, uint8_t grant[SRSLTE_RAR_GRANT_LEN]) +{ + uint8_t *grant_ptr = grant; + srslte_bit_unpack(rar->hopping_flag?1:0, &grant_ptr, 1); + srslte_bit_unpack(rar->rba, &grant_ptr, 10); + srslte_bit_unpack(rar->trunc_mcs, &grant_ptr, 4); + srslte_bit_unpack(rar->tpc_pusch, &grant_ptr, 3); + srslte_bit_unpack(rar->ul_delay?1:0, &grant_ptr, 1); + srslte_bit_unpack(rar->cqi_request?1:0, &grant_ptr, 1); +} + void srslte_dci_rar_grant_fprint(FILE *stream, srslte_dci_rar_grant_t *rar) { fprintf(stream, "RBA: %d, MCS: %d, TPC: %d, Hopping=%s, UL-Delay=%s, CQI=%s\n", rar->rba, rar->trunc_mcs, rar->tpc_pusch, diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 06dde712a..f41c43d0e 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -169,21 +169,26 @@ void srslte_pdcch_free(srslte_pdcch_t *q) { } +uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, uint32_t max_candidates, + uint32_t nsubframe, uint32_t cfi, uint16_t rnti) +{ + set_cfi(q, cfi); + return srslte_pdcch_ue_locations_ncce(q->nof_cce, c, max_candidates, nsubframe, rnti); +} + /** 36.213 v9.1.1 * Computes up to max_candidates UE-specific candidates for DCI messages and saves them * in the structure pointed by c. * Returns the number of candidates saved in the array c. */ -uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, uint32_t max_candidates, - uint32_t nsubframe, uint32_t cfi, uint16_t rnti) { +uint32_t srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t *c, uint32_t max_candidates, + uint32_t nsubframe, uint16_t rnti) { int l; // this must be int because of the for(;;--) loop uint32_t i, k, L, m; uint32_t Yk, ncce; const int S[4] = { 6, 12, 8, 16 }; - set_cfi(q, cfi); - // Compute Yk for this subframe Yk = rnti; for (m = 0; m < nsubframe+1; m++) { @@ -195,10 +200,10 @@ uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, for (l = 3; l >= 0; l--) { L = (1 << l); // For all possible ncce offset - for (i = 0; i < SRSLTE_MIN(q->nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { - ncce = L * ((Yk + i) % (q->nof_cce / L)); + for (i = 0; i < SRSLTE_MIN(nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { + ncce = L * ((Yk + i) % (nof_cce / L)); if (k < max_candidates && - ncce + PDCCH_FORMAT_NOF_CCE(l) <= q->nof_cce) + ncce + PDCCH_FORMAT_NOF_CCE(l) <= nof_cce) { c[k].L = l; c[k].ncce = ncce; diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index b6abb1f8a..32bdddb2a 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -564,6 +564,15 @@ int srslte_ra_tbs_idx_from_mcs(uint32_t mcs) { } } +int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx) { + for (int i=0;i<29;i++) { + if (tbs_idx == mcs_tbs_idx_table[i]) { + return i; + } + } + return SRSLTE_ERROR; +} + /* Table 7.1.7.2.1-1: Transport block size table on 36.213 */ int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb) { if (tbs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) { diff --git a/srslte/lib/phch/uci.c b/srslte/lib/phch/uci.c index ff656028b..ece0702c2 100644 --- a/srslte/lib/phch/uci.c +++ b/srslte/lib/phch/uci.c @@ -147,7 +147,7 @@ int srslte_uci_cqi_init(srslte_uci_cqi_pusch_t *q) { if (srslte_crc_init(&q->crc, SRSLTE_LTE_CRC8, 8)) { return SRSLTE_ERROR; } - uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; + int poly[3] = { 0x6D, 0x4F, 0x57 }; if (srslte_viterbi_init(&q->viterbi, SRSLTE_VITERBI_37, poly, SRSLTE_UCI_MAX_CQI_LEN_PUSCH, true)) { return SRSLTE_ERROR; }