diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index 8a6d3724e..0d3aa6c4a 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -609,7 +609,7 @@ int main(int argc, char **argv) { /* Encode PDCCH */ INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L); - srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, false); + srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false); if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], UE_CRNTI, sf_symbols, sf_idx, cfi)) { fprintf(stderr, "Error encoding DCI message\n"); exit(-1); diff --git a/srslte/include/srslte/phch/dci.h b/srslte/include/srslte/phch/dci.h index dcc8cf215..1bc169f77 100644 --- a/srslte/include/srslte/phch/dci.h +++ b/srslte/include/srslte/phch/dci.h @@ -165,6 +165,7 @@ SRSLTE_API int srslte_dci_msg_pack_pdsch(srslte_ra_dl_dci_t *data, srslte_dci_format_t format, srslte_dci_msg_t *msg, uint32_t nof_prb, + uint32_t nof_ports, bool crc_is_crnti); SRSLTE_API int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg, diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index 82fc8491e..33809015d 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -238,7 +238,7 @@ int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, rnti_is_user = false; } - srslte_dci_msg_pack_pdsch(grant, format, &dci_msg, q->cell.nof_prb, rnti_is_user); + srslte_dci_msg_pack_pdsch(grant, format, &dci_msg, q->cell.nof_prb, q->cell.nof_ports, rnti_is_user); if (srslte_pdcch_encode(&q->pdcch, &dci_msg, location, rnti, q->sf_symbols, sf_idx, q->cfi)) { fprintf(stderr, "Error encoding DCI message\n"); return SRSLTE_ERROR; diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 206d2d289..9e653e8f5 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -1010,6 +1010,76 @@ int dci_format1D_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_ } +int dci_format2AB_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t nof_prb, uint32_t nof_ports) { + + /* pack bits */ + uint8_t *y = msg->data; + + if (nof_prb > 10) { + *y++ = data->alloc_type; + } + + /* Resource allocation: type0 or type 1 */ + uint32_t P = srslte_ra_type0_P(nof_prb); + uint32_t alloc_size = (uint32_t) ceilf((float) nof_prb / P); + switch (data->alloc_type) { + case SRSLTE_RA_ALLOC_TYPE0: + srslte_bit_unpack((uint32_t) data->type0_alloc.rbg_bitmask, &y, alloc_size); + break; + case SRSLTE_RA_ALLOC_TYPE1: + srslte_bit_unpack((uint32_t) data->type1_alloc.rbg_subset, &y, (int) ceilf(log2f(P))); + *y++ = data->type1_alloc.shift ? 1 : 0; + srslte_bit_unpack((uint32_t) data->type1_alloc.vrb_bitmask, &y, + alloc_size - (int) ceilf(log2f(P)) - 1); + break; + default: + fprintf(stderr, + "Format 1 accepts type0 or type1 resource allocation only\n"); + return SRSLTE_ERROR; + + } + + // pack TPC command for PUCCH (not implemented) + y+=2; + + /* harq process number */ + srslte_bit_unpack(data->harq_process, &y, harq_pid_len); + + + // Transpor block to codeword swap flag + if (msg->format == SRSLTE_DCI_FORMAT2B) { + *y++ = data->sram_id; + } else { + *y++ = data->tb_cw_swap; + } + + /* pack TB1 */ + srslte_bit_unpack(data->mcs_idx, &y, 5); + *y++ = data->ndi; + srslte_bit_unpack(data->rv_idx, &y, 2); + + /* pack TB2 */ + srslte_bit_unpack(data->mcs_idx_1, &y, 5); + *y++ = data->ndi_1; + srslte_bit_unpack(data->rv_idx_1, &y, 2); + + // Precoding information + if (msg->format == SRSLTE_DCI_FORMAT2A) { + srslte_bit_unpack(data->pinfo, &y, precoding_bits_f2(nof_ports)); + } else if (msg->format == SRSLTE_DCI_FORMAT2A) { + srslte_bit_unpack(data->pinfo, &y, precoding_bits_f2a(nof_ports)); + } + + // Padding with zeros + uint32_t n = srslte_dci_format_sizeof(msg->format, nof_prb, nof_ports); + while (y - msg->data < n) { + *y++ = 0; + } + msg->nof_bits = (y - msg->data); + + return SRSLTE_SUCCESS; +} + int dci_format2AB_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t nof_prb, uint32_t nof_ports) { /* pack bits */ @@ -1086,7 +1156,7 @@ int dci_format2AB_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 int srslte_dci_msg_pack_pdsch(srslte_ra_dl_dci_t *data, srslte_dci_format_t format, - srslte_dci_msg_t *msg, uint32_t nof_prb, + srslte_dci_msg_t *msg, uint32_t nof_prb, uint32_t nof_ports, bool crc_is_crnti) { msg->format = format; @@ -1097,6 +1167,10 @@ int srslte_dci_msg_pack_pdsch(srslte_ra_dl_dci_t *data, srslte_dci_format_t form return dci_format1As_pack(data, msg, nof_prb, crc_is_crnti); case SRSLTE_DCI_FORMAT1C: return dci_format1Cs_pack(data, msg, nof_prb); + case SRSLTE_DCI_FORMAT2: + case SRSLTE_DCI_FORMAT2A: + case SRSLTE_DCI_FORMAT2B: + return dci_format2AB_pack(data, msg, nof_prb, nof_ports); default: fprintf(stderr, "DCI pack pdsch: Invalid DCI format %s\n", srslte_dci_format_string(format)); diff --git a/srslte/lib/phch/test/pdcch_test.c b/srslte/lib/phch/test/pdcch_test.c index d03532b45..5d4fb0a7c 100644 --- a/srslte/lib/phch/test/pdcch_test.c +++ b/srslte/lib/phch/test/pdcch_test.c @@ -191,11 +191,11 @@ int main(int argc, char **argv) { ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0; ra_dl.type0_alloc.rbg_bitmask = 0x5; - srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_tx[0], cell.nof_prb, false); + srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_tx[0], cell.nof_prb, cell.nof_ports, false); srslte_dci_location_set(&dci_locations[0], 0, 0); ra_dl.mcs_idx = 15; - srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_tx[1], cell.nof_prb, false); + srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_tx[1], cell.nof_prb, cell.nof_ports, false); srslte_dci_location_set(&dci_locations[1], 0, 1); for (i=0;i