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_pdsch_cfg_t pdsch_cfg;
srslte_softbuffer_tx_t softbuffer;
srslte_ra_dl_dci_t dl_dci;
srslte_dci_format_t dci_format;
@ -87,16 +86,23 @@ typedef struct SRSLTE_API {
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;
srslte_ra_dl_dci_t grant;
srslte_dci_location_t location;
uint8_t *data;
} srslte_enb_dl_grant_t;
} 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,
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

@ -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);

@ -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

@ -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);

@ -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;i<nof_rnti;i++) {
srslte_softbuffer_tx_init(&q->softbuffer[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;i<q->nof_rnti;i++) {
srslte_softbuffer_tx_free(&q->softbuffer[i]);
}
free(q->softbuffer);
}
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
if (q->sf_symbols[i]) {
@ -272,20 +279,35 @@ int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant,
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;i<nof_grants;i++) {
if (srslte_enb_dl_put_pdcch_ul(q, &grants[i].grant, grants[i].location, grants[i].rnti_idx, sf_idx)) {
fprintf(stderr, "Error putting PDCCH &d\n",i);
return SRSLTE_ERROR;
}
}
return SRSLTE_SUCCESS;
}
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;i<nof_grants;i++) {
if (grants[i].is_dl) {
srslte_dci_format_t format = SRSLTE_DCI_FORMAT1;
switch(grants[i].grant.dl.dci_format) {
switch(grants[i].grant.dci_format) {
case SRSLTE_RA_DCI_FORMAT1:
format = SRSLTE_DCI_FORMAT1;
break;
@ -296,17 +318,10 @@ int srslte_enb_dl_put_grant(srslte_enb_dl_t *q, srslte_enb_dl_grant_t *grants, u
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)) {
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;
}
} 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);
bool rnti_is_user = true;
@ -314,12 +329,13 @@ int srslte_enb_dl_put_grant(srslte_enb_dl_t *q, srslte_enb_dl_grant_t *grants, u
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)) {
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;
}

@ -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,

@ -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;

@ -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) {

@ -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;
}

Loading…
Cancel
Save