mirror of https://github.com/PentHertz/srsLTE.git
Added ENB processing functions
This commit is contained in:
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;
|
||||
|
@ -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
|
||||
|
|
|
@ -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]) {
|
||||
|
@ -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;i<nof_grants;i++) {
|
||||
if (grants[i].is_dl) {
|
||||
srslte_dci_format_t format = SRSLTE_DCI_FORMAT1;
|
||||
switch(grants[i].grant.dl.dci_format) {
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
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++) {
|
||||
srslte_dci_format_t format = SRSLTE_DCI_FORMAT1;
|
||||
switch(grants[i].grant.dci_format) {
|
||||
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, 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;
|
||||
}
|
|
@ -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…
Reference in New Issue