Added ENB processing functions

master
Ismael Gomez 9 years ago
parent 3c6fcf3656
commit 5c6311fc56

@ -76,7 +76,6 @@ typedef struct SRSLTE_API {
srslte_refsignal_cs_t csr_signal; srslte_refsignal_cs_t csr_signal;
srslte_pdsch_cfg_t pdsch_cfg; srslte_pdsch_cfg_t pdsch_cfg;
srslte_softbuffer_tx_t softbuffer;
srslte_ra_dl_dci_t dl_dci; srslte_ra_dl_dci_t dl_dci;
srslte_dci_format_t dci_format; srslte_dci_format_t dci_format;
@ -86,17 +85,24 @@ typedef struct SRSLTE_API {
float sss_signal0[SRSLTE_SSS_LEN]; float sss_signal0[SRSLTE_SSS_LEN];
float sss_signal5[SRSLTE_SSS_LEN]; float sss_signal5[SRSLTE_SSS_LEN];
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
srslte_softbuffer_tx_t *softbuffer;
uint32_t nof_rnti;
} srslte_enb_dl_t; } srslte_enb_dl_t;
typedef struct { typedef struct {
bool is_dl; uint32_t rnti_idx;
srslte_ra_dci_grant_t grant; srslte_ra_dl_dci_t grant;
srslte_dci_location_t location; srslte_dci_location_t location;
uint32_t rnti_idx; uint8_t *data;
uint32_t rv_idx; } srslte_enb_dl_grant_pdsch_t;
uint8_t *data;
} srslte_enb_dl_grant_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 */ /* 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 rnti_idx,
uint32_t sf_idx); uint32_t sf_idx);
SRSLTE_API int srslte_enb_dl_put_grant(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_put_grant_pdsch(srslte_enb_dl_t *q,
srslte_enb_dl_grant_t *grants, srslte_enb_dl_grant_pdsch_t *grants,
uint32_t nof_grants, uint32_t nof_grants,
uint32_t sf_idx); 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 #endif

@ -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, SRSLTE_API void srslte_dci_rar_grant_unpack(srslte_dci_rar_grant_t *rar,
uint8_t grant[SRSLTE_RAR_GRANT_LEN]); 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_API void srslte_dci_rar_grant_fprint(FILE *stream,
srslte_dci_rar_grant_t *rar); srslte_dci_rar_grant_t *rar);

@ -122,6 +122,11 @@ SRSLTE_API uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q,
uint32_t cfi, uint32_t cfi,
uint16_t rnti); 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 */ /* Function for generation of common search space DCI locations */
SRSLTE_API uint32_t srslte_pdcch_common_locations(srslte_pdcch_t *q, SRSLTE_API uint32_t srslte_pdcch_common_locations(srslte_pdcch_t *q,
srslte_dci_location_t *locations, 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, srslte_dci_location_t *c,
uint32_t max_candidates); uint32_t max_candidates);
#endif #endif

@ -178,11 +178,6 @@ typedef union {
srslte_ra_dl_grant_t dl; srslte_ra_dl_grant_t dl;
} srslte_phy_grant_t; } 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) #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_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, SRSLTE_API int srslte_ra_tbs_from_idx(uint32_t tbs_idx,
uint32_t n_prb); uint32_t n_prb);

@ -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->cell = cell;
q->cfi = 3; q->cfi = 3;
q->nof_rnti = nof_rnti;
if (srslte_ofdm_tx_init(&q->ifft, q->cell.cp, q->cell.nof_prb)) { if (srslte_ofdm_tx_init(&q->ifft, q->cell.cp, q->cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n"); 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; goto clean_exit;
} }
if (srslte_softbuffer_tx_init(&q->softbuffer, q->cell.nof_prb)) { q->softbuffer = malloc(nof_rnti*sizeof(srslte_softbuffer_tx_t));
fprintf(stderr, "Error initiating soft buffer\n"); for (int i=0;i<nof_rnti;i++) {
goto clean_exit; srslte_softbuffer_tx_init(&q->softbuffer[i], q->cell.nof_prb);
} }
if (srslte_refsignal_cs_init(&q->csr_signal, q->cell)) { 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_pdsch_free(&q->pdsch);
srslte_refsignal_cs_free(&q->csr_signal); srslte_refsignal_cs_free(&q->csr_signal);
srslte_softbuffer_tx_free(&q->softbuffer);
if (q->softbuffer) {
for (int i=0;i<q->nof_rnti;i++) {
srslte_softbuffer_tx_free(&q->softbuffer[i]);
}
free(q->softbuffer);
}
for (int i=0;i<SRSLTE_MAX_PORTS;i++) { for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
if (q->sf_symbols[i]) { if (q->sf_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"); fprintf(stderr, "Error configuring PDSCH\n");
return SRSLTE_ERROR; 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 */ /* 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"); fprintf(stderr, "Error encoding PDSCH\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SRSLTE_SUCCESS; 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;i<nof_grants;i++) { for (int i=0;i<nof_grants;i++) {
if (grants[i].is_dl) { if (srslte_enb_dl_put_pdcch_ul(q, &grants[i].grant, grants[i].location, grants[i].rnti_idx, sf_idx)) {
srslte_dci_format_t format = SRSLTE_DCI_FORMAT1; fprintf(stderr, "Error putting PDCCH &d\n",i);
switch(grants[i].grant.dl.dci_format) { return SRSLTE_ERROR;
case SRSLTE_RA_DCI_FORMAT1:
format = SRSLTE_DCI_FORMAT1;
break;
case SRSLTE_RA_DCI_FORMAT1A:
format = SRSLTE_DCI_FORMAT1A;
break;
case SRSLTE_RA_DCI_FORMAT1C:
format = SRSLTE_DCI_FORMAT1C;
break;
}
if (srslte_enb_dl_put_pdcch_dl(q, &grants[i].grant.dl, format, grants[i].location, grants[i].rnti_idx, sf_idx)) {
fprintf(stderr, "Error putting PDCCH &d\n",i);
return SRSLTE_ERROR;
}
} else {
if (srslte_enb_dl_put_pdcch_ul(q, &grants[i].grant.ul, grants[i].location, grants[i].rnti_idx, sf_idx)) {
fprintf(stderr, "Error putting PDCCH &d\n",i);
return SRSLTE_ERROR;
}
} }
if (grants[i].is_dl) { }
uint16_t rnti = srslte_pdsch_get_rnti_multi(&q->pdsch, grants[i].rnti_idx); return SRSLTE_SUCCESS;
}
bool rnti_is_user = true; 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)
if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || rnti == SRSLTE_MRNTI) { {
rnti_is_user = false; for (int i=0;i<nof_grants;i++) {
} srslte_dci_format_t format = SRSLTE_DCI_FORMAT1;
srslte_ra_dl_grant_t phy_grant; switch(grants[i].grant.dci_format) {
srslte_ra_dl_dci_to_grant(&grants[i].grant.dl, q->cell.nof_prb, rnti_is_user, &phy_grant); case SRSLTE_RA_DCI_FORMAT1:
if (srslte_enb_dl_put_pdsch(q, &phy_grant, grants[i].rnti_idx, grants[i].rv_idx, sf_idx, grants[i].data)) { format = SRSLTE_DCI_FORMAT1;
fprintf(stderr, "Error putting PDCCH %d\n",i); break;
return SRSLTE_ERROR; case SRSLTE_RA_DCI_FORMAT1A:
} format = SRSLTE_DCI_FORMAT1A;
break;
case SRSLTE_RA_DCI_FORMAT1C:
format = SRSLTE_DCI_FORMAT1C;
break;
}
if (srslte_enb_dl_put_pdcch_dl(q, &grants[i].grant, format, grants[i].location, grants[i].rnti_idx, sf_idx)) {
fprintf(stderr, "Error putting PDCCH &d\n",i);
return SRSLTE_ERROR;
}
uint16_t rnti = srslte_pdsch_get_rnti_multi(&q->pdsch, 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; return SRSLTE_SUCCESS;
} }

@ -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; 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) { 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", fprintf(stream, "RBA: %d, MCS: %d, TPC: %d, Hopping=%s, UL-Delay=%s, CQI=%s\n",
rar->rba, rar->trunc_mcs, rar->tpc_pusch, rar->rba, rar->trunc_mcs, rar->tpc_pusch,

@ -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 /** 36.213 v9.1.1
* Computes up to max_candidates UE-specific candidates for DCI messages and saves them * Computes up to max_candidates UE-specific candidates for DCI messages and saves them
* in the structure pointed by c. * in the structure pointed by c.
* Returns the number of candidates saved in the array 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 srslte_pdcch_ue_locations_ncce(uint32_t nof_cce, srslte_dci_location_t *c, uint32_t max_candidates,
uint32_t nsubframe, uint32_t cfi, uint16_t rnti) { uint32_t nsubframe, uint16_t rnti) {
int l; // this must be int because of the for(;;--) loop int l; // this must be int because of the for(;;--) loop
uint32_t i, k, L, m; uint32_t i, k, L, m;
uint32_t Yk, ncce; uint32_t Yk, ncce;
const int S[4] = { 6, 12, 8, 16 }; const int S[4] = { 6, 12, 8, 16 };
set_cfi(q, cfi);
// Compute Yk for this subframe // Compute Yk for this subframe
Yk = rnti; Yk = rnti;
for (m = 0; m < nsubframe+1; m++) { 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--) { for (l = 3; l >= 0; l--) {
L = (1 << l); L = (1 << l);
// For all possible ncce offset // For all possible ncce offset
for (i = 0; i < SRSLTE_MIN(q->nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { for (i = 0; i < SRSLTE_MIN(nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) {
ncce = L * ((Yk + i) % (q->nof_cce / L)); ncce = L * ((Yk + i) % (nof_cce / L));
if (k < max_candidates && 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].L = l;
c[k].ncce = ncce; c[k].ncce = ncce;

@ -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 */ /* 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) { 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) { if (tbs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {

@ -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)) { if (srslte_crc_init(&q->crc, SRSLTE_LTE_CRC8, 8)) {
return SRSLTE_ERROR; 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)) { if (srslte_viterbi_init(&q->viterbi, SRSLTE_VITERBI_37, poly, SRSLTE_UCI_MAX_CQI_LEN_PUSCH, true)) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

Loading…
Cancel
Save