mirror of https://github.com/PentHertz/srsLTE.git
Revert "Added Aperiodic mode 3-1 in enb and some more optimizations"
This reverts commit 8ab196901f
.
This commit is contained in:
parent
8ab196901f
commit
eefbdbc913
|
@ -141,7 +141,6 @@ SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q,
|
||||||
uint32_t rv_idx,
|
uint32_t rv_idx,
|
||||||
uint32_t current_tx_nb,
|
uint32_t current_tx_nb,
|
||||||
uint8_t *data,
|
uint8_t *data,
|
||||||
srslte_cqi_value_t *cqi_value,
|
|
||||||
srslte_uci_data_t *uci_data,
|
srslte_uci_data_t *uci_data,
|
||||||
uint32_t tti);
|
uint32_t tti);
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,6 @@ SRSLTE_API int srslte_pusch_decode(srslte_pusch_t *q,
|
||||||
float noise_estimate,
|
float noise_estimate,
|
||||||
uint16_t rnti,
|
uint16_t rnti,
|
||||||
uint8_t *data,
|
uint8_t *data,
|
||||||
srslte_cqi_value_t *cqi_value,
|
|
||||||
srslte_uci_data_t *uci_data);
|
srslte_uci_data_t *uci_data);
|
||||||
|
|
||||||
SRSLTE_API float srslte_pusch_average_noi(srslte_pusch_t *q);
|
SRSLTE_API float srslte_pusch_average_noi(srslte_pusch_t *q);
|
||||||
|
|
|
@ -131,25 +131,31 @@ SRSLTE_API int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
||||||
uint32_t H_prime_total,
|
uint32_t H_prime_total,
|
||||||
srslte_uci_bit_t *ri_bits);
|
srslte_uci_bit_t *ri_bits);
|
||||||
|
|
||||||
SRSLTE_API int srslte_uci_encode_ack_ri(srslte_pusch_cfg_t *cfg,
|
SRSLTE_API int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg,
|
||||||
uint8_t *data,
|
int16_t *q_bits,
|
||||||
uint32_t data_len,
|
uint8_t *c_seq,
|
||||||
|
float beta,
|
||||||
|
uint32_t H_prime_total,
|
||||||
|
uint32_t O_cqi,
|
||||||
|
srslte_uci_bit_t *ack_bits,
|
||||||
|
uint8_t acks[2],
|
||||||
|
uint32_t nof_acks);
|
||||||
|
|
||||||
|
SRSLTE_API int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
|
||||||
|
uint8_t data,
|
||||||
uint32_t O_cqi,
|
uint32_t O_cqi,
|
||||||
float beta,
|
float beta,
|
||||||
uint32_t H_prime_total,
|
uint32_t H_prime_total,
|
||||||
srslte_uci_bit_t *ri_bits,
|
srslte_uci_bit_t *ri_bits);
|
||||||
bool is_ri);
|
|
||||||
|
|
||||||
SRSLTE_API int srslte_uci_decode_ack_ri(srslte_pusch_cfg_t *cfg,
|
SRSLTE_API int srslte_uci_decode_ri(srslte_pusch_cfg_t *cfg,
|
||||||
int16_t *q_bits,
|
int16_t *q_bits,
|
||||||
uint8_t *c_seq,
|
uint8_t *c_seq,
|
||||||
float beta,
|
float beta,
|
||||||
uint32_t H_prime_total,
|
uint32_t H_prime_total,
|
||||||
uint32_t O_cqi,
|
uint32_t O_cqi,
|
||||||
srslte_uci_bit_t *ack_ri_bits,
|
srslte_uci_bit_t *ri_bits,
|
||||||
uint8_t data[2],
|
uint8_t *data);
|
||||||
uint32_t nof_bits,
|
|
||||||
bool is_ri);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -253,22 +253,18 @@ int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint16_t rnti,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void srslte_enb_ul_fft(srslte_enb_ul_t *q)
|
void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer)
|
||||||
{
|
{
|
||||||
srslte_ofdm_rx_sf(&q->fft);
|
srslte_ofdm_rx_sf(&q->fft);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
int get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
||||||
uint32_t pdcch_n_cce, uint32_t sf_rx,
|
uint32_t pdcch_n_cce, uint32_t sf_rx,
|
||||||
srslte_uci_data_t *uci_data, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], uint32_t nof_bits)
|
srslte_uci_data_t *uci_data, uint8_t bits[SRSLTE_PUCCH_MAX_BITS])
|
||||||
{
|
{
|
||||||
float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest);
|
float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest);
|
||||||
|
|
||||||
srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp);
|
srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp);
|
||||||
if (format == SRSLTE_PUCCH_FORMAT_ERROR) {
|
|
||||||
fprintf(stderr,"Error getting format\n");
|
|
||||||
return SRSLTE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->users[rnti]->pucch_sched);
|
uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->users[rnti]->pucch_sched);
|
||||||
|
|
||||||
|
@ -277,7 +273,7 @@ int get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, rnti, q->sf_symbols, q->ce, noise_power, bits, nof_bits);
|
int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, rnti, q->sf_symbols, q->ce, noise_power, bits);
|
||||||
if (ret_val < 0) {
|
if (ret_val < 0) {
|
||||||
fprintf(stderr,"Error decoding PUCCH\n");
|
fprintf(stderr,"Error decoding PUCCH\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
@ -292,16 +288,14 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
||||||
uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS];
|
uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS];
|
||||||
|
|
||||||
if (q->users[rnti]) {
|
if (q->users[rnti]) {
|
||||||
uint32_t nof_uci_bits = uci_data->ri_periodic_report ? uci_data->uci_ri_len : (uci_data->uci_cqi_len +
|
|
||||||
uci_data->uci_dif_cqi_len +
|
int ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, pucch_bits);
|
||||||
uci_data->uci_pmi_len);
|
|
||||||
int ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, pucch_bits, nof_uci_bits);
|
|
||||||
|
|
||||||
// If we are looking for SR and ACK at the same time and ret=0, means there is no SR.
|
// If we are looking for SR and ACK at the same time and ret=0, means there is no SR.
|
||||||
// try again to decode ACK only
|
// try again to decode ACK only
|
||||||
if (uci_data->scheduling_request && uci_data->uci_ack_len && ret_val != 1) {
|
if (uci_data->scheduling_request && uci_data->uci_ack_len && ret_val != 1) {
|
||||||
uci_data->scheduling_request = false;
|
uci_data->scheduling_request = false;
|
||||||
ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, pucch_bits, nof_uci_bits);
|
ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, pucch_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update schedulign request
|
// update schedulign request
|
||||||
|
@ -314,29 +308,9 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
||||||
uci_data->uci_ack = pucch_bits[0];
|
uci_data->uci_ack = pucch_bits[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uci_data->uci_ack_len > 1) {
|
|
||||||
uci_data->uci_ack_2 = pucch_bits[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUCCH2 CQI bits are decoded inside srslte_pucch_decode()
|
// PUCCH2 CQI bits are decoded inside srslte_pucch_decode()
|
||||||
if (uci_data->uci_cqi_len) {
|
if (uci_data->uci_cqi_len) {
|
||||||
memcpy(uci_data->uci_cqi, pucch_bits, uci_data->uci_cqi_len*sizeof(uint8_t));
|
memcpy(uci_data->uci_cqi, pucch_bits, uci_data->uci_cqi_len*sizeof(uint8_t));
|
||||||
}
|
|
||||||
|
|
||||||
if (uci_data->uci_dif_cqi_len) {
|
|
||||||
memcpy(uci_data->uci_dif_cqi, pucch_bits + uci_data->uci_cqi_len, uci_data->uci_dif_cqi_len*sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uci_data->uci_pmi_len) {
|
|
||||||
memcpy(uci_data->uci_pmi, pucch_bits + uci_data->uci_cqi_len + uci_data->uci_dif_cqi_len,
|
|
||||||
uci_data->uci_pmi_len*sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uci_data->uci_ri_len) {
|
|
||||||
uci_data->uci_ri = pucch_bits[0]; /* Assume only one bit of RI */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uci_data->uci_cqi_len || uci_data->uci_ri_len) {
|
|
||||||
if (uci_data->uci_ack_len >= 1) {
|
if (uci_data->uci_ack_len >= 1) {
|
||||||
uci_data->uci_ack = pucch_bits[20];
|
uci_data->uci_ack = pucch_bits[20];
|
||||||
}
|
}
|
||||||
|
@ -354,7 +328,7 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
||||||
|
|
||||||
int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer,
|
int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srslte_softbuffer_rx_t *softbuffer,
|
||||||
uint16_t rnti, uint32_t rv_idx, uint32_t current_tx_nb,
|
uint16_t rnti, uint32_t rv_idx, uint32_t current_tx_nb,
|
||||||
uint8_t *data, srslte_cqi_value_t *cqi_value, srslte_uci_data_t *uci_data, uint32_t tti)
|
uint8_t *data, srslte_uci_data_t *uci_data, uint32_t tti)
|
||||||
{
|
{
|
||||||
if (q->users[rnti]) {
|
if (q->users[rnti]) {
|
||||||
if (srslte_pusch_cfg(&q->pusch,
|
if (srslte_pusch_cfg(&q->pusch,
|
||||||
|
@ -390,7 +364,6 @@ int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srs
|
||||||
softbuffer, q->sf_symbols,
|
softbuffer, q->sf_symbols,
|
||||||
q->ce, noise_power,
|
q->ce, noise_power,
|
||||||
rnti, data,
|
rnti, data,
|
||||||
cqi_value,
|
|
||||||
uci_data);
|
uci_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,44 +199,17 @@ int srslte_cqi_value_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_value_
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_cqi_size(srslte_cqi_value_t *value) {
|
int srslte_cqi_size(srslte_cqi_value_t *value) {
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
switch(value->type) {
|
switch(value->type) {
|
||||||
case SRSLTE_CQI_TYPE_WIDEBAND:
|
case SRSLTE_CQI_TYPE_WIDEBAND:
|
||||||
size = 4;
|
return 4;
|
||||||
break;
|
|
||||||
case SRSLTE_CQI_TYPE_SUBBAND:
|
case SRSLTE_CQI_TYPE_SUBBAND:
|
||||||
size = 4 + (value->subband.subband_label_2_bits) ? 2 : 1;
|
return 4+(value->subband.subband_label_2_bits)?2:1;
|
||||||
break;
|
|
||||||
case SRSLTE_CQI_TYPE_SUBBAND_UE:
|
case SRSLTE_CQI_TYPE_SUBBAND_UE:
|
||||||
size = 4 + 2 + value->subband_ue.L;
|
return 4+2+value->subband_ue.L;
|
||||||
break;
|
|
||||||
case SRSLTE_CQI_TYPE_SUBBAND_HL:
|
case SRSLTE_CQI_TYPE_SUBBAND_HL:
|
||||||
/* First codeword */
|
return 4+2*value->subband_hl.N;
|
||||||
size += 4 + 2 * value->subband_hl.N;
|
|
||||||
|
|
||||||
/* Add Second codeword if required */
|
|
||||||
if (value->subband_hl.rank_is_not_one && value->subband_hl.pmi_present) {
|
|
||||||
size += 4 + 2 * value->subband_hl.N;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add PMI if required*/
|
|
||||||
if (value->subband_hl.pmi_present) {
|
|
||||||
if (value->subband_hl.four_antenna_ports) {
|
|
||||||
size += 4;
|
|
||||||
} else {
|
|
||||||
if (value->subband_hl.rank_is_not_one) {
|
|
||||||
size += 1;
|
|
||||||
} else {
|
|
||||||
size += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
size = SRSLTE_ERROR;
|
|
||||||
}
|
}
|
||||||
return size;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool srslte_cqi_get_N(uint32_t I_cqi_pmi, uint32_t *N_p, uint32_t *N_offset) {
|
static bool srslte_cqi_get_N(uint32_t I_cqi_pmi, uint32_t *N_p, uint32_t *N_offset) {
|
||||||
|
|
|
@ -566,9 +566,9 @@ int srslte_pusch_decode(srslte_pusch_t *q,
|
||||||
srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
|
srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
|
||||||
cf_t *sf_symbols,
|
cf_t *sf_symbols,
|
||||||
cf_t *ce, float noise_estimate, uint16_t rnti,
|
cf_t *ce, float noise_estimate, uint16_t rnti,
|
||||||
uint8_t *data, srslte_cqi_value_t *cqi_value, srslte_uci_data_t *uci_data)
|
uint8_t *data, srslte_uci_data_t *uci_data)
|
||||||
{
|
{
|
||||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
||||||
if (q != NULL &&
|
if (q != NULL &&
|
||||||
|
@ -607,42 +607,19 @@ int srslte_pusch_decode(srslte_pusch_t *q,
|
||||||
// Generate scrambling sequence if not pre-generated
|
// Generate scrambling sequence if not pre-generated
|
||||||
srslte_sequence_t *seq = get_user_sequence(q, rnti, cfg->sf_idx, cfg->nbits.nof_bits);
|
srslte_sequence_t *seq = get_user_sequence(q, rnti, cfg->sf_idx, cfg->nbits.nof_bits);
|
||||||
|
|
||||||
// Set CQI len assuming RI = 1 (3GPP 36.212 Clause 5.2.4.1. Uplink control information on PUSCH without UL-SCH data)
|
|
||||||
if (cqi_value) {
|
|
||||||
if (cqi_value->type == SRSLTE_CQI_TYPE_SUBBAND_HL) {
|
|
||||||
cqi_value->subband_hl.rank_is_not_one = false;
|
|
||||||
}
|
|
||||||
uci_data->uci_cqi_len = (uint32_t) srslte_cqi_size(cqi_value);
|
|
||||||
uci_data->uci_ri_len = (q->cell.nof_ports == 4) ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode RI/HARQ bits before descrambling
|
// Decode RI/HARQ bits before descrambling
|
||||||
if (srslte_ulsch_uci_decode_ri_ack(&q->ul_sch, cfg, softbuffer, q->q, seq->c, uci_data)) {
|
if (srslte_ulsch_uci_decode_ri_ack(&q->ul_sch, cfg, softbuffer, q->q, seq->c, uci_data)) {
|
||||||
fprintf(stderr, "Error decoding RI/HARQ bits\n");
|
fprintf(stderr, "Error decoding RI/HARQ bits\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set CQI len with corresponding RI
|
|
||||||
if (cqi_value) {
|
|
||||||
if (cqi_value->type == SRSLTE_CQI_TYPE_SUBBAND_HL) {
|
|
||||||
cqi_value->subband_hl.rank_is_not_one = (uci_data->uci_ri != 0);
|
|
||||||
}
|
|
||||||
uci_data->uci_cqi_len = (uint32_t) srslte_cqi_size(cqi_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Descrambling
|
// Descrambling
|
||||||
srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits);
|
srslte_scrambling_s_offset(seq, q->q, 0, cfg->nbits.nof_bits);
|
||||||
|
|
||||||
// Decode
|
return srslte_ulsch_uci_decode(&q->ul_sch, cfg, softbuffer, q->q, q->g, data, uci_data);
|
||||||
ret = srslte_ulsch_uci_decode(&q->ul_sch, cfg, softbuffer, q->q, q->g, data, uci_data);
|
} else {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
// Unpack CQI value if available
|
|
||||||
if (cqi_value) {
|
|
||||||
srslte_cqi_value_unpack(uci_data->uci_cqi, cqi_value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t srslte_pusch_last_noi(srslte_pusch_t *q) {
|
uint32_t srslte_pusch_last_noi(srslte_pusch_t *q) {
|
||||||
|
|
|
@ -658,7 +658,7 @@ int srslte_ulsch_uci_decode_ri_ack(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srs
|
||||||
if (cfg->cb_segm.tbs == 0) {
|
if (cfg->cb_segm.tbs == 0) {
|
||||||
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
||||||
}
|
}
|
||||||
ret = srslte_uci_decode_ack_ri(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, acks, uci_data->uci_ack_len, false);
|
ret = srslte_uci_decode_ack(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, acks, uci_data->uci_ack_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ int srslte_ulsch_uci_decode_ri_ack(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srs
|
||||||
if (cfg->cb_segm.tbs == 0) {
|
if (cfg->cb_segm.tbs == 0) {
|
||||||
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
||||||
}
|
}
|
||||||
ret = srslte_uci_decode_ack_ri(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, &uci_data->uci_ri, uci_data->uci_ri_len, true);
|
ret = srslte_uci_decode_ri(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, &uci_data->uci_ri);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -756,18 +756,13 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
|
||||||
uint32_t nb_q = cfg->nbits.nof_bits;
|
uint32_t nb_q = cfg->nbits.nof_bits;
|
||||||
uint32_t Qm = cfg->grant.Qm;
|
uint32_t Qm = cfg->grant.Qm;
|
||||||
|
|
||||||
// Encode RI if CQI enabled
|
// Encode RI
|
||||||
if (uci_data.uci_ri_len > 0 || uci_data.uci_cqi_len > 0) {
|
if (uci_data.uci_ri_len > 0) {
|
||||||
/* If no RI is reported set it to zero as specified in 3GPP 36.213 clause 7.2.1 */
|
|
||||||
if (uci_data.uci_ri_len == 0) {
|
|
||||||
uci_data.uci_ri = 0;
|
|
||||||
}
|
|
||||||
float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri];
|
float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri];
|
||||||
if (cfg->cb_segm.tbs == 0) {
|
if (cfg->cb_segm.tbs == 0) {
|
||||||
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
||||||
}
|
}
|
||||||
uint8_t ri[2] = {uci_data.uci_ri, 0};
|
ret = srslte_uci_encode_ri(cfg, uci_data.uci_ri, uci_data.uci_cqi_len, beta, nb_q/Qm, q->ack_ri_bits);
|
||||||
ret = srslte_uci_encode_ack_ri(cfg, ri, uci_data.uci_ri_len, uci_data.uci_cqi_len, beta, nb_q/Qm, q->ack_ri_bits, true);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -814,8 +809,8 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
|
||||||
if (cfg->cb_segm.tbs == 0) {
|
if (cfg->cb_segm.tbs == 0) {
|
||||||
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
||||||
}
|
}
|
||||||
ret = srslte_uci_encode_ack_ri(cfg, acks, uci_data.uci_ack_len, uci_data.uci_cqi_len,
|
ret = srslte_uci_encode_ack(cfg, acks, uci_data.uci_ack_len, uci_data.uci_cqi_len,
|
||||||
beta, nb_q / Qm, &q->ack_ri_bits[Q_prime_ri * Qm], false);
|
beta, nb_q / Qm, &q->ack_ri_bits[Q_prime_ri * Qm]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,7 +252,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gettimeofday(&t[1], NULL);
|
gettimeofday(&t[1], NULL);
|
||||||
int r = srslte_pusch_decode(&pusch_rx, &cfg, &softbuffer_rx, sf_symbols, ce, 0, rnti, data, NULL, &uci_data_rx);
|
int r = srslte_pusch_decode(&pusch_rx, &cfg, &softbuffer_rx, sf_symbols, ce, 0, rnti, data, &uci_data_rx);
|
||||||
gettimeofday(&t[2], NULL);
|
gettimeofday(&t[2], NULL);
|
||||||
get_time_interval(t);
|
get_time_interval(t);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
|
|
@ -108,24 +108,21 @@ static uint8_t M_basis_seq_pucch[20][13]={
|
||||||
void srslte_uci_cqi_pucch_init(srslte_uci_cqi_pucch_t *q) {
|
void srslte_uci_cqi_pucch_init(srslte_uci_cqi_pucch_t *q) {
|
||||||
uint8_t word[16];
|
uint8_t word[16];
|
||||||
|
|
||||||
uint32_t nwords = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH;
|
uint32_t nwords = 16;
|
||||||
q->cqi_table = srslte_vec_malloc(nwords * sizeof(int8_t *));
|
for (uint32_t w=0;w<nwords;w++) {
|
||||||
q->cqi_table_s = srslte_vec_malloc(nwords * sizeof(int16_t *));
|
q->cqi_table[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B*sizeof(int8_t));
|
||||||
|
q->cqi_table_s[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B*sizeof(int16_t));
|
||||||
for (uint32_t w = 0; w < nwords; w++) {
|
|
||||||
q->cqi_table[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B * sizeof(int8_t));
|
|
||||||
q->cqi_table_s[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B * sizeof(int16_t));
|
|
||||||
uint8_t *ptr = word;
|
uint8_t *ptr = word;
|
||||||
srslte_bit_unpack(w, &ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH);
|
srslte_bit_unpack(w, &ptr, 4);
|
||||||
srslte_uci_encode_cqi_pucch(word, SRSLTE_UCI_MAX_CQI_LEN_PUCCH, q->cqi_table[w]);
|
srslte_uci_encode_cqi_pucch(word, 4, q->cqi_table[w]);
|
||||||
for (int j = 0; j < SRSLTE_UCI_CQI_CODED_PUCCH_B; j++) {
|
for (int j=0;j<SRSLTE_UCI_CQI_CODED_PUCCH_B;j++) {
|
||||||
q->cqi_table_s[w][j] = (int16_t)(2 * q->cqi_table[w][j] - 1);
|
q->cqi_table_s[w][j] = 2*q->cqi_table[w][j]-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void srslte_uci_cqi_pucch_free(srslte_uci_cqi_pucch_t *q) {
|
void srslte_uci_cqi_pucch_free(srslte_uci_cqi_pucch_t *q) {
|
||||||
uint32_t nwords = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH;
|
uint32_t nwords = 16;
|
||||||
for (uint32_t w=0;w<nwords;w++) {
|
for (uint32_t w=0;w<nwords;w++) {
|
||||||
if (q->cqi_table[w]) {
|
if (q->cqi_table[w]) {
|
||||||
free(q->cqi_table[w]);
|
free(q->cqi_table[w]);
|
||||||
|
@ -134,8 +131,6 @@ void srslte_uci_cqi_pucch_free(srslte_uci_cqi_pucch_t *q) {
|
||||||
free(q->cqi_table_s[w]);
|
free(q->cqi_table_s[w]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(q->cqi_table);
|
|
||||||
free(q->cqi_table_s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode UCI CQI/PMI as described in 5.2.3.3 of 36.212
|
/* Encode UCI CQI/PMI as described in 5.2.3.3 of 36.212
|
||||||
|
@ -156,32 +151,17 @@ int srslte_uci_encode_cqi_pucch(uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_uci_encode_cqi_pucch_from_table(srslte_uci_cqi_pucch_t *q, uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_bits[SRSLTE_UCI_CQI_CODED_PUCCH_B])
|
|
||||||
{
|
|
||||||
if (cqi_len <= SRSLTE_UCI_MAX_CQI_LEN_PUCCH) {
|
|
||||||
bzero(&cqi_data[cqi_len], SRSLTE_UCI_MAX_CQI_LEN_PUCCH - cqi_len);
|
|
||||||
uint8_t *ptr = cqi_data;
|
|
||||||
uint32_t packed = srslte_bit_pack(&ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH);
|
|
||||||
memcpy(b_bits, q->cqi_table[packed], SRSLTE_UCI_CQI_CODED_PUCCH_B);
|
|
||||||
|
|
||||||
return SRSLTE_SUCCESS;
|
|
||||||
} else {
|
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decode UCI CQI/PMI over PUCCH
|
/* Decode UCI CQI/PMI over PUCCH
|
||||||
*/
|
*/
|
||||||
int16_t srslte_uci_decode_cqi_pucch(srslte_uci_cqi_pucch_t *q, int16_t b_bits[32], uint8_t *cqi_data, uint32_t cqi_len)
|
int16_t srslte_uci_decode_cqi_pucch(srslte_uci_cqi_pucch_t *q, int16_t b_bits[32], uint8_t *cqi_data, uint32_t cqi_len)
|
||||||
{
|
{
|
||||||
if (cqi_len < SRSLTE_UCI_MAX_CQI_LEN_PUCCH &&
|
if (cqi_len == 4 &&
|
||||||
b_bits != NULL &&
|
b_bits != NULL &&
|
||||||
cqi_data != NULL)
|
cqi_data != NULL)
|
||||||
{
|
{
|
||||||
uint32_t max_w = 0;
|
uint32_t max_w = 0;
|
||||||
int32_t max_corr = INT32_MIN;
|
int32_t max_corr = INT32_MIN;
|
||||||
uint32_t nwords = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH;
|
for (uint32_t w=0;w<16;w++) {
|
||||||
for (uint32_t w=0;w<nwords;w += 1<<(SRSLTE_UCI_MAX_CQI_LEN_PUCCH - cqi_len)) {
|
|
||||||
|
|
||||||
// Calculate correlation with pregenerated word and select maximum
|
// Calculate correlation with pregenerated word and select maximum
|
||||||
int32_t corr = srslte_vec_dot_prod_sss(q->cqi_table_s[w], b_bits, SRSLTE_UCI_CQI_CODED_PUCCH_B);
|
int32_t corr = srslte_vec_dot_prod_sss(q->cqi_table_s[w], b_bits, SRSLTE_UCI_CQI_CODED_PUCCH_B);
|
||||||
|
@ -192,7 +172,7 @@ int16_t srslte_uci_decode_cqi_pucch(srslte_uci_cqi_pucch_t *q, int16_t b_bits[32
|
||||||
}
|
}
|
||||||
// Convert word to bits again
|
// Convert word to bits again
|
||||||
uint8_t *ptr = cqi_data;
|
uint8_t *ptr = cqi_data;
|
||||||
srslte_bit_unpack(max_w, &ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH);
|
srslte_bit_unpack(max_w, &ptr, cqi_len);
|
||||||
|
|
||||||
INFO("Decoded CQI: w=%d, corr=%d\n", max_w, max_corr);
|
INFO("Decoded CQI: w=%d, corr=%d\n", max_w, max_corr);
|
||||||
return max_corr;
|
return max_corr;
|
||||||
|
@ -606,7 +586,9 @@ static uint32_t encode_ri_ack(uint8_t data[2], uint32_t data_len, srslte_uci_bit
|
||||||
/* Decode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212
|
/* Decode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212
|
||||||
* Currently only supporting 1-bit HARQ
|
* Currently only supporting 1-bit HARQ
|
||||||
*/
|
*/
|
||||||
static int32_t decode_ri_ack_1bit(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos)
|
#ifndef MIMO_ENB
|
||||||
|
|
||||||
|
static int32_t decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos)
|
||||||
{
|
{
|
||||||
uint32_t p0 = pos[0].position;
|
uint32_t p0 = pos[0].position;
|
||||||
uint32_t p1 = pos[1].position;
|
uint32_t p1 = pos[1].position;
|
||||||
|
@ -616,8 +598,33 @@ static int32_t decode_ri_ack_1bit(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bi
|
||||||
|
|
||||||
return -(q0+q1);
|
return -(q0+q1);
|
||||||
}
|
}
|
||||||
|
int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_seq,
|
||||||
|
float beta, uint32_t H_prime_total,
|
||||||
|
uint32_t O_cqi, srslte_uci_bit_t *ack_bits, uint8_t acks[2], uint32_t nof_acks)
|
||||||
|
{
|
||||||
|
int32_t rx_ack = 0;
|
||||||
|
|
||||||
static void decode_ri_ack_2bits(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos, uint32_t Qm, int32_t data[3])
|
if (beta < 0) {
|
||||||
|
fprintf(stderr, "Error beta is reserved\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta);
|
||||||
|
|
||||||
|
// Use the same interleaver function to get the HARQ bit position
|
||||||
|
for (uint32_t i=0;i<Qprime;i++) {
|
||||||
|
uci_ulsch_interleave_ack_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]);
|
||||||
|
rx_ack += (int32_t) decode_ri_ack(q_bits, c_seq, &ack_bits[cfg->grant.Qm*i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acks) {
|
||||||
|
acks[0] = rx_ack>0;
|
||||||
|
}
|
||||||
|
return (int) Qprime;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos, uint32_t Qm, int32_t data[3])
|
||||||
{
|
{
|
||||||
uint32_t p0 = pos[Qm * 0 + 0].position;
|
uint32_t p0 = pos[Qm * 0 + 0].position;
|
||||||
uint32_t p1 = pos[Qm * 0 + 1].position;
|
uint32_t p1 = pos[Qm * 0 + 1].position;
|
||||||
|
@ -638,91 +645,118 @@ static void decode_ri_ack_2bits(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_
|
||||||
data[2] -= q2 + q5;
|
data[2] -= q2 + q5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode UCI ACK/RI bits as described in 5.2.2.6 of 36.212
|
int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_seq,
|
||||||
* Currently only supporting 1-bit RI
|
float beta, uint32_t H_prime_total,
|
||||||
*/
|
uint32_t O_cqi, srslte_uci_bit_t *ack_bits, uint8_t acks[2], uint32_t nof_acks)
|
||||||
int srslte_uci_encode_ack_ri(srslte_pusch_cfg_t *cfg,
|
{
|
||||||
uint8_t *data, uint32_t data_len,
|
int32_t acks_sum[3] = {0, 0, 0};
|
||||||
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
|
||||||
srslte_uci_bit_t *bits, bool ack_ri) {
|
|
||||||
if (beta < 0) {
|
if (beta < 0) {
|
||||||
fprintf(stderr, "Error beta is reserved\n");
|
fprintf(stderr, "Error beta is reserved\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint32_t Qprime = Q_prime_ri_ack(cfg, data_len, O_cqi, beta);
|
|
||||||
|
uint32_t Qprime = Q_prime_ri_ack(cfg, nof_acks, O_cqi, beta);
|
||||||
|
|
||||||
|
// Use the same interleaver function to get the HARQ bit position
|
||||||
|
for (uint32_t i = 0; i < Qprime; i++) {
|
||||||
|
uci_ulsch_interleave_ack_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]);
|
||||||
|
if ((i % 3 == 0) && i > 0) {
|
||||||
|
decode_ri_ack(q_bits, &c_seq[0], &ack_bits[cfg->grant.Qm*(i-3)], cfg->grant.Qm, acks_sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acks) {
|
||||||
|
acks[0] = (uint8_t)(acks_sum[0] > 0);
|
||||||
|
acks[1] = (uint8_t)(acks_sum[1] > 0);
|
||||||
|
// TODO: Do something with acks_sum[2]
|
||||||
|
}
|
||||||
|
return (int) Qprime;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Encode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212
|
||||||
|
* Currently only supporting 1-bit HARQ
|
||||||
|
*/
|
||||||
|
int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg, uint8_t acks[2], uint32_t nof_acks,
|
||||||
|
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
||||||
|
srslte_uci_bit_t *ack_bits)
|
||||||
|
{
|
||||||
|
if (beta < 0) {
|
||||||
|
fprintf(stderr, "Error beta is reserved\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Qprime = Q_prime_ri_ack(cfg, nof_acks, O_cqi, beta);
|
||||||
srslte_uci_bit_type_t q_encoded_bits[18];
|
srslte_uci_bit_type_t q_encoded_bits[18];
|
||||||
|
|
||||||
uint32_t nof_encoded_bits = encode_ri_ack(data, data_len, q_encoded_bits, cfg->grant.Qm);
|
uint32_t nof_encoded_bits = encode_ri_ack(acks, nof_acks, q_encoded_bits, cfg->grant.Qm);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < Qprime; i++) {
|
for (uint32_t i=0;i<Qprime;i++) {
|
||||||
if (ack_ri) {
|
uci_ulsch_interleave_ack_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]);
|
||||||
uci_ulsch_interleave_ri_gen(i,
|
uci_ulsch_interleave_put(&q_encoded_bits[(i*cfg->grant.Qm)%nof_encoded_bits], cfg->grant.Qm, &ack_bits[cfg->grant.Qm*i]);
|
||||||
cfg->grant.Qm,
|
|
||||||
H_prime_total,
|
|
||||||
cfg->nbits.nof_symb,
|
|
||||||
cfg->cp,
|
|
||||||
&bits[cfg->grant.Qm * i]);
|
|
||||||
} else {
|
|
||||||
uci_ulsch_interleave_ack_gen(i,
|
|
||||||
cfg->grant.Qm,
|
|
||||||
H_prime_total,
|
|
||||||
cfg->nbits.nof_symb,
|
|
||||||
cfg->cp,
|
|
||||||
&bits[cfg->grant.Qm * i]);
|
|
||||||
}
|
|
||||||
uci_ulsch_interleave_put(&q_encoded_bits[(i * cfg->grant.Qm) % nof_encoded_bits],
|
|
||||||
cfg->grant.Qm,
|
|
||||||
&bits[cfg->grant.Qm * i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) Qprime;
|
return (int) Qprime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decode UCI ACK/RI bits as described in 5.2.2.6 of 36.212
|
/* Encode UCI RI bits as described in 5.2.2.6 of 36.212
|
||||||
* Currently only supporting 1-bit RI
|
* Currently only supporting 1-bit RI
|
||||||
*/
|
*/
|
||||||
int srslte_uci_decode_ack_ri(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_seq,
|
int srslte_uci_decode_ri(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_seq,
|
||||||
float beta, uint32_t H_prime_total,
|
float beta, uint32_t H_prime_total,
|
||||||
uint32_t O_cqi, srslte_uci_bit_t *ack_ri_bits, uint8_t data[2], uint32_t nof_bits, bool is_ri)
|
uint32_t O_cqi, srslte_uci_bit_t *ri_bits, uint8_t *data)
|
||||||
{
|
{
|
||||||
int32_t sum[3] = {0, 0, 0};
|
int32_t ri_sum[3] = {0, 0, 0};
|
||||||
|
|
||||||
if (beta < 0) {
|
if (beta < 0) {
|
||||||
fprintf(stderr, "Error beta is reserved\n");
|
fprintf(stderr, "Error beta is reserved\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Qprime = Q_prime_ri_ack(cfg, nof_bits, O_cqi, beta);
|
uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < Qprime; i++) {
|
// Use the same interleaver function to get the HARQ bit position
|
||||||
if (is_ri) {
|
for (uint32_t i=0;i<Qprime;i++) {
|
||||||
uci_ulsch_interleave_ri_gen(i,
|
uci_ulsch_interleave_ri_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ri_bits[cfg->grant.Qm*i]);
|
||||||
cfg->grant.Qm,
|
if ((i % 3 == 0) && i > 0) {
|
||||||
H_prime_total,
|
//decode_ri_ack(q_bits, &c_seq[0], &ri_bits[cfg->grant.Qm*(i-3)], cfg->grant.Qm, ri_sum);
|
||||||
cfg->nbits.nof_symb,
|
|
||||||
cfg->cp,
|
|
||||||
&ack_ri_bits[cfg->grant.Qm * i]);
|
|
||||||
} else {
|
|
||||||
uci_ulsch_interleave_ack_gen(i,
|
|
||||||
cfg->grant.Qm,
|
|
||||||
H_prime_total,
|
|
||||||
cfg->nbits.nof_symb,
|
|
||||||
cfg->cp,
|
|
||||||
&ack_ri_bits[cfg->grant.Qm * i]);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (nof_bits == 2 && (i % 3 == 0) && i > 0) {
|
|
||||||
decode_ri_ack_2bits(q_bits, &c_seq[0], &ack_ri_bits[cfg->grant.Qm * (i - 3)], cfg->grant.Qm, sum);
|
|
||||||
} else if (nof_bits == 1) {
|
|
||||||
sum[0] += (int32_t) decode_ri_ack_1bit(q_bits, c_seq, &ack_ri_bits[cfg->grant.Qm * i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data[0] = (uint8_t) (sum[0] > 0);
|
if (data) {
|
||||||
if (nof_bits == 2) {
|
*data = (uint8_t) ((ri_sum[0] + ri_sum[1] + ri_sum[2]) > 0);
|
||||||
data[1] = (uint8_t) (sum[1] > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) Qprime;
|
return (int) Qprime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Encode UCI RI bits as described in 5.2.2.6 of 36.212
|
||||||
|
* Currently only supporting 1-bit RI
|
||||||
|
*/
|
||||||
|
int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
|
||||||
|
uint8_t ri,
|
||||||
|
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
||||||
|
srslte_uci_bit_t *ri_bits)
|
||||||
|
{
|
||||||
|
// FIXME: It supports RI of 1 bit only
|
||||||
|
uint8_t data[2] = {ri, 0};
|
||||||
|
if (beta < 0) {
|
||||||
|
fprintf(stderr, "Error beta is reserved\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta);
|
||||||
|
srslte_uci_bit_type_t q_encoded_bits[18];
|
||||||
|
|
||||||
|
uint32_t nof_encoded_bits = encode_ri_ack(data, 1, q_encoded_bits, cfg->grant.Qm);
|
||||||
|
|
||||||
|
for (uint32_t i=0;i<Qprime;i++) {
|
||||||
|
uci_ulsch_interleave_ri_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ri_bits[cfg->grant.Qm*i]);
|
||||||
|
uci_ulsch_interleave_put(&q_encoded_bits[(i*cfg->grant.Qm)%nof_encoded_bits], cfg->grant.Qm, &ri_bits[cfg->grant.Qm*i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) Qprime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -725,8 +725,7 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo
|
||||||
/* Select the best Rank indicator (RI) and Precoding Matrix Indicator (PMI) */
|
/* Select the best Rank indicator (RI) and Precoding Matrix Indicator (PMI) */
|
||||||
for (uint32_t nof_layers = 1; nof_layers <= SRSLTE_MAX_LAYERS; nof_layers++) {
|
for (uint32_t nof_layers = 1; nof_layers <= SRSLTE_MAX_LAYERS; nof_layers++) {
|
||||||
float _sinr = q->sinr[nof_layers - 1][q->pmi[nof_layers - 1]] * nof_layers * nof_layers;
|
float _sinr = q->sinr[nof_layers - 1][q->pmi[nof_layers - 1]] * nof_layers * nof_layers;
|
||||||
/* Find best SINR, force maximum number of layers if SNR is higher than 30 dB */
|
if (_sinr > best_sinr + 0.1) {
|
||||||
if (_sinr > best_sinr + 0.1 || _sinr > 1.0e+3) {
|
|
||||||
best_sinr = _sinr;
|
best_sinr = _sinr;
|
||||||
best_pmi = (uint8_t) q->pmi[nof_layers - 1];
|
best_pmi = (uint8_t) q->pmi[nof_layers - 1];
|
||||||
best_ri = (uint8_t) (nof_layers - 1);
|
best_ri = (uint8_t) (nof_layers - 1);
|
||||||
|
|
|
@ -88,19 +88,16 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
|
||||||
pthread_mutex_init(&mutex, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
|
||||||
// Init cell here
|
// Init cell here
|
||||||
for(int p = 0; p < SRSLTE_MAX_PORTS; p++) {
|
signal_buffer_rx = (cf_t*) srslte_vec_malloc(2*SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t));
|
||||||
signal_buffer_rx[p] = (cf_t *) srslte_vec_malloc(2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
|
if (!signal_buffer_rx) {
|
||||||
if (!signal_buffer_rx[p]) {
|
fprintf(stderr, "Error allocating memory\n");
|
||||||
fprintf(stderr, "Error allocating memory\n");
|
return;
|
||||||
return;
|
}
|
||||||
}
|
bzero(&signal_buffer_tx, sizeof(cf_t *) * SRSLTE_MAX_PORTS);
|
||||||
bzero(signal_buffer_rx[p], 2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
|
signal_buffer_tx[0] = (cf_t*) srslte_vec_malloc(2*SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t));
|
||||||
signal_buffer_tx[p] = (cf_t *) srslte_vec_malloc(2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
|
if (!signal_buffer_tx[0]) {
|
||||||
if (!signal_buffer_tx[p]) {
|
fprintf(stderr, "Error allocating memory\n");
|
||||||
fprintf(stderr, "Error allocating memory\n");
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
bzero(signal_buffer_tx[p], 2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
|
|
||||||
}
|
}
|
||||||
if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, phy->cell.nof_prb)) {
|
if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, phy->cell.nof_prb)) {
|
||||||
fprintf(stderr, "Error initiating ENB DL\n");
|
fprintf(stderr, "Error initiating ENB DL\n");
|
||||||
|
@ -110,7 +107,7 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
|
||||||
fprintf(stderr, "Error initiating ENB DL\n");
|
fprintf(stderr, "Error initiating ENB DL\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx[0], phy->cell.nof_prb)) {
|
if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx, phy->cell.nof_prb)) {
|
||||||
fprintf(stderr, "Error initiating ENB UL\n");
|
fprintf(stderr, "Error initiating ENB UL\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -157,12 +154,12 @@ void phch_worker::stop()
|
||||||
|
|
||||||
srslte_enb_dl_free(&enb_dl);
|
srslte_enb_dl_free(&enb_dl);
|
||||||
srslte_enb_ul_free(&enb_ul);
|
srslte_enb_ul_free(&enb_ul);
|
||||||
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
|
if (signal_buffer_rx) {
|
||||||
if (signal_buffer_rx[p]) {
|
free(signal_buffer_rx);
|
||||||
free(signal_buffer_rx[p]);
|
}
|
||||||
}
|
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||||
if (signal_buffer_tx[p]) {
|
if (signal_buffer_tx[i]) {
|
||||||
free(signal_buffer_tx[p]);
|
free(signal_buffer_tx[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
@ -174,9 +171,9 @@ void phch_worker::reset()
|
||||||
ue_db.clear();
|
ue_db.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
cf_t* phch_worker::get_buffer_rx(uint32_t antenna_idx)
|
cf_t* phch_worker::get_buffer_rx()
|
||||||
{
|
{
|
||||||
return signal_buffer_rx[antenna_idx];
|
return signal_buffer_rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void phch_worker::set_time(uint32_t tti_, uint32_t tx_mutex_cnt_, srslte_timestamp_t tx_time_)
|
void phch_worker::set_time(uint32_t tti_, uint32_t tx_mutex_cnt_, srslte_timestamp_t tx_time_)
|
||||||
|
@ -217,29 +214,12 @@ uint32_t phch_worker::get_nof_rnti() {
|
||||||
return ue_db.size();
|
return ue_db.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void phch_worker::set_conf_dedicated_ack(uint16_t rnti, bool ack){
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
if (ue_db.count(rnti)) {
|
|
||||||
ue_db[rnti].dedicated_ack = ack;
|
|
||||||
} else {
|
|
||||||
Error("Setting dedicated ack: rnti=0x%x does not exist\n");
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void phch_worker::set_config_dedicated(uint16_t rnti,
|
void phch_worker::set_config_dedicated(uint16_t rnti,
|
||||||
srslte_uci_cfg_t *uci_cfg,
|
srslte_uci_cfg_t *uci_cfg,
|
||||||
srslte_pucch_sched_t *pucch_sched,
|
srslte_pucch_sched_t *pucch_sched,
|
||||||
srslte_refsignal_srs_cfg_t *srs_cfg,
|
srslte_refsignal_srs_cfg_t *srs_cfg,
|
||||||
LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT* dedicated)
|
uint32_t I_sr, bool pucch_cqi, uint32_t pmi_idx, bool pucch_cqi_ack)
|
||||||
{
|
{
|
||||||
uint32_t I_sr = dedicated->sched_request_cnfg.sr_cnfg_idx;
|
|
||||||
bool pucch_cqi = dedicated->cqi_report_cnfg.report_periodic_setup_present;
|
|
||||||
uint32_t pmi_idx = dedicated->cqi_report_cnfg.report_periodic.pmi_cnfg_idx;
|
|
||||||
bool pucch_cqi_ack = dedicated->cqi_report_cnfg.report_periodic.simult_ack_nack_and_cqi;
|
|
||||||
bool pucch_ri = dedicated->cqi_report_cnfg.report_periodic.ri_cnfg_idx_present;
|
|
||||||
uint32_t ri_idx = dedicated->cqi_report_cnfg.report_periodic.ri_cnfg_idx;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
if (ue_db.count(rnti)) {
|
if (ue_db.count(rnti)) {
|
||||||
pucch_sched->N_pucch_1 = phy->pucch_cfg.n1_pucch_an;
|
pucch_sched->N_pucch_1 = phy->pucch_cfg.n1_pucch_an;
|
||||||
|
@ -257,16 +237,6 @@ void phch_worker::set_config_dedicated(uint16_t rnti,
|
||||||
ue_db[rnti].cqi_en = false;
|
ue_db[rnti].cqi_en = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pucch_ri) {
|
|
||||||
ue_db[rnti].ri_idx = ri_idx;
|
|
||||||
ue_db[rnti].ri_en = true;
|
|
||||||
} else {
|
|
||||||
ue_db[rnti].ri_idx = 0;
|
|
||||||
ue_db[rnti].ri_en = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy all dedicated RRC configuration to UE */
|
|
||||||
memcpy(&ue_db[rnti].dedicated, dedicated, sizeof(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT));
|
|
||||||
} else {
|
} else {
|
||||||
Error("Setting config dedicated: rnti=0x%x does not exist\n");
|
Error("Setting config dedicated: rnti=0x%x does not exist\n");
|
||||||
}
|
}
|
||||||
|
@ -323,7 +293,7 @@ void phch_worker::work_imp()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process UL signal
|
// Process UL signal
|
||||||
srslte_enb_ul_fft(&enb_ul);
|
srslte_enb_ul_fft(&enb_ul, signal_buffer_rx);
|
||||||
|
|
||||||
// Decode pending UL grants for the tti they were scheduled
|
// Decode pending UL grants for the tti they were scheduled
|
||||||
decode_pusch(ul_grants[t_rx].sched_grants, ul_grants[t_rx].nof_grants);
|
decode_pusch(ul_grants[t_rx].sched_grants, ul_grants[t_rx].nof_grants);
|
||||||
|
@ -365,22 +335,15 @@ void phch_worker::work_imp()
|
||||||
phy->ack_clear(TTIMOD(TTI_TX(t_tx_dl)));
|
phy->ack_clear(TTIMOD(TTI_TX(t_tx_dl)));
|
||||||
for (uint32_t i=0;i<dl_grants[t_tx_dl].nof_grants;i++) {
|
for (uint32_t i=0;i<dl_grants[t_tx_dl].nof_grants;i++) {
|
||||||
// SI-RNTI and RAR-RNTI do not have ACK
|
// SI-RNTI and RAR-RNTI do not have ACK
|
||||||
uint16_t rnti = dl_grants[t_tx_dl].sched_grants[i].rnti;
|
if (dl_grants[t_tx_dl].sched_grants[i].rnti >= SRSLTE_CRNTI_START && dl_grants[t_tx_dl].sched_grants[i].rnti <= SRSLTE_CRNTI_END) {
|
||||||
if (rnti >= SRSLTE_CRNTI_START && rnti <= SRSLTE_CRNTI_END) {
|
phy->ack_set_pending(TTIMOD(TTI_TX(t_tx_dl)), dl_grants[t_tx_dl].sched_grants[i].rnti, dl_grants[t_tx_dl].sched_grants[i].location.ncce);
|
||||||
/* For each TB */
|
|
||||||
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
|
|
||||||
/* If TB enabled, set pending ACK */
|
|
||||||
if (dl_grants[t_tx_dl].sched_grants[i].grant.tb_en[tb_idx]) {
|
|
||||||
phy->ack_set_pending(TTIMOD(TTI_TX(t_tx_dl)), rnti, tb_idx, dl_grants[t_tx_dl].sched_grants[i].location.ncce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate signal and transmit
|
// Generate signal and transmit
|
||||||
srslte_enb_dl_gen_signal(&enb_dl);
|
srslte_enb_dl_gen_signal(&enb_dl);
|
||||||
Debug("Sending to radio\n");
|
Debug("Sending to radio\n");
|
||||||
phy->worker_end(tx_mutex_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
|
phy->worker_end(tx_mutex_cnt, signal_buffer_tx[0], SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
|
||||||
|
|
||||||
#ifdef DEBUG_WRITE_FILE
|
#ifdef DEBUG_WRITE_FILE
|
||||||
fwrite(signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t), 1, f);
|
fwrite(signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb)*sizeof(cf_t), 1, f);
|
||||||
|
@ -424,39 +387,24 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
gettimeofday(&t[1], NULL);
|
gettimeofday(&t[1], NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool acks_pending[SRSLTE_MAX_TB] = {false};
|
|
||||||
|
|
||||||
// Get pending ACKs with an associated PUSCH transmission
|
// Get pending ACKs with an associated PUSCH transmission
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
if (phy->ack_is_pending(t_rx, rnti)) {
|
||||||
acks_pending[tb] = phy->ack_is_pending(t_rx, rnti, tb);
|
uci_data.uci_ack_len = 1;
|
||||||
if (acks_pending[tb]) {
|
|
||||||
uci_data.uci_ack_len++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure PUSCH CQI channel
|
// Configure PUSCH CQI channel
|
||||||
srslte_cqi_value_t cqi_value = {0};
|
srslte_cqi_value_t cqi_value;
|
||||||
bool cqi_enabled = false;
|
bool cqi_enabled = false;
|
||||||
#if 0
|
if (ue_db[rnti].cqi_en && srslte_cqi_send(ue_db[rnti].pmi_idx, tti_rx)) {
|
||||||
if (ue_db[rnti].cqi_en && ue_db[rnti].ri_en && srslte_ri_send(ue_db[rnti].pmi_idx, ue_db[rnti].ri_idx, tti_rx) ) {
|
|
||||||
uci_data.uci_ri_len = 1; /* Asumes only 1 bit for RI */
|
|
||||||
ri_enabled = true;
|
|
||||||
} else if (ue_db[rnti].cqi_en && srslte_cqi_send(ue_db[rnti].pmi_idx, tti_rx)) {
|
|
||||||
cqi_value.type = SRSLTE_CQI_TYPE_WIDEBAND;
|
cqi_value.type = SRSLTE_CQI_TYPE_WIDEBAND;
|
||||||
cqi_enabled = true;
|
cqi_enabled = true;
|
||||||
if (ue_db[rnti].dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
} else if (grants[i].grant.cqi_request) {
|
||||||
//uci_data.uci_dif_cqi_len = 3;
|
|
||||||
uci_data.uci_pmi_len = 2;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (grants[i].grant.cqi_request) {
|
|
||||||
cqi_value.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
|
cqi_value.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
|
||||||
cqi_value.subband_hl.N = (phy->cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(phy->cell.nof_prb) : 0;
|
cqi_value.subband_hl.N = (phy->cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(phy->cell.nof_prb) : 0;
|
||||||
cqi_value.subband_hl.four_antenna_ports = (phy->cell.nof_ports == 4);
|
|
||||||
cqi_value.subband_hl.pmi_present = (ue_db[rnti].dedicated.cqi_report_cnfg.report_mode_aperiodic == LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31);
|
|
||||||
cqi_enabled = true;
|
cqi_enabled = true;
|
||||||
}
|
}
|
||||||
|
if (cqi_enabled) {
|
||||||
|
uci_data.uci_cqi_len = srslte_cqi_size(&cqi_value);
|
||||||
|
}
|
||||||
|
|
||||||
// mark this tti as having an ul grant to avoid pucch
|
// mark this tti as having an ul grant to avoid pucch
|
||||||
ue_db[rnti].has_grant_tti = tti_rx;
|
ue_db[rnti].has_grant_tti = tti_rx;
|
||||||
|
@ -464,6 +412,22 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
srslte_ra_ul_grant_t phy_grant;
|
srslte_ra_ul_grant_t phy_grant;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
if (!srslte_ra_ul_dci_to_grant(&grants[i].grant, enb_ul.cell.nof_prb, n_rb_ho, &phy_grant)) {
|
if (!srslte_ra_ul_dci_to_grant(&grants[i].grant, enb_ul.cell.nof_prb, n_rb_ho, &phy_grant)) {
|
||||||
|
|
||||||
|
// Handle Format0 adaptive retx
|
||||||
|
// Use last TBS for this TB in case of mcs>28
|
||||||
|
if (phy_grant.mcs.idx > 28) {
|
||||||
|
phy_grant.mcs.tbs = ue_db[rnti].last_ul_tbs[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)];
|
||||||
|
Info("RETX: mcs=%d, old_tbs=%d pid=%d\n", phy_grant.mcs.idx, phy_grant.mcs.tbs, TTI_TX(tti_rx)%(2*HARQ_DELAY_MS));
|
||||||
|
}
|
||||||
|
ue_db[rnti].last_ul_tbs[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)] = phy_grant.mcs.tbs;
|
||||||
|
|
||||||
|
if (phy_grant.mcs.mod == SRSLTE_MOD_LAST) {
|
||||||
|
phy_grant.mcs.mod = ue_db[rnti].last_ul_mod[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)];
|
||||||
|
phy_grant.Qm = srslte_mod_bits_x_symbol(phy_grant.mcs.mod);
|
||||||
|
}
|
||||||
|
ue_db[rnti].last_ul_mod[TTI_RX(tti_rx)%(2*HARQ_DELAY_MS)] = phy_grant.mcs.mod;
|
||||||
|
|
||||||
|
|
||||||
if (phy_grant.mcs.mod == SRSLTE_MOD_64QAM) {
|
if (phy_grant.mcs.mod == SRSLTE_MOD_64QAM) {
|
||||||
phy_grant.mcs.mod = SRSLTE_MOD_16QAM;
|
phy_grant.mcs.mod = SRSLTE_MOD_16QAM;
|
||||||
}
|
}
|
||||||
|
@ -472,7 +436,6 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
rnti, grants[i].rv_idx,
|
rnti, grants[i].rv_idx,
|
||||||
grants[i].current_tx_nb,
|
grants[i].current_tx_nb,
|
||||||
grants[i].data,
|
grants[i].data,
|
||||||
(cqi_enabled) ? &cqi_value : NULL,
|
|
||||||
&uci_data,
|
&uci_data,
|
||||||
sf_rx);
|
sf_rx);
|
||||||
} else {
|
} else {
|
||||||
|
@ -494,24 +457,11 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
|
|
||||||
char cqi_str[64];
|
char cqi_str[64];
|
||||||
if (cqi_enabled) {
|
if (cqi_enabled) {
|
||||||
|
srslte_cqi_value_unpack(uci_data.uci_cqi, &cqi_value);
|
||||||
if (ue_db[rnti].cqi_en) {
|
if (ue_db[rnti].cqi_en) {
|
||||||
wideband_cqi_value = cqi_value.wideband.wideband_cqi;
|
wideband_cqi_value = cqi_value.wideband.wideband_cqi;
|
||||||
} else if (grants[i].grant.cqi_request) {
|
} else if (grants[i].grant.cqi_request) {
|
||||||
wideband_cqi_value = cqi_value.subband_hl.wideband_cqi_cw0;
|
wideband_cqi_value = cqi_value.subband_hl.wideband_cqi_cw0;
|
||||||
if (cqi_value.subband_hl.pmi_present) {
|
|
||||||
if (cqi_value.subband_hl.rank_is_not_one) {
|
|
||||||
Info("PUSCH: Aperiodic ri~1, CQI=%02d/%02d, pmi=%d for %d subbands\n",
|
|
||||||
cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.wideband_cqi_cw1,
|
|
||||||
cqi_value.subband_hl.pmi, cqi_value.subband_hl.N);
|
|
||||||
} else {
|
|
||||||
Info("PUSCH: Aperiodic ri=1, CQI=%02d, pmi=%d for %d subbands\n",
|
|
||||||
cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.pmi, cqi_value.subband_hl.N);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Info("PUSCH: Aperiodic ri%s, CQI=%02d for %d subbands\n",
|
|
||||||
cqi_value.subband_hl.rank_is_not_one?"~1":"=1",
|
|
||||||
cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.N);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
snprintf(cqi_str, 64, ", cqi=%d", wideband_cqi_value);
|
snprintf(cqi_str, 64, ", cqi=%d", wideband_cqi_value);
|
||||||
}
|
}
|
||||||
|
@ -531,16 +481,14 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
log_h->info_hex(grants[i].data, phy_grant.mcs.tbs/8,
|
log_h->info_hex(grants[i].data, phy_grant.mcs.tbs/8,
|
||||||
"PUSCH: rnti=0x%x, prb=(%d,%d), tbs=%d, mcs=%d, rv=%d, snr=%.1f dB, n_iter=%d, crc=%s%s%s%s%s\n",
|
"PUSCH: rnti=0x%x, prb=(%d,%d), tbs=%d, mcs=%d, rv=%d, snr=%.1f dB, n_iter=%d, crc=%s%s%s%s\n",
|
||||||
rnti, phy_grant.n_prb[0], phy_grant.n_prb[0]+phy_grant.L_prb,
|
rnti, phy_grant.n_prb[0], phy_grant.n_prb[0]+phy_grant.L_prb,
|
||||||
phy_grant.mcs.tbs/8, phy_grant.mcs.idx, grants[i].grant.rv_idx,
|
phy_grant.mcs.tbs/8, phy_grant.mcs.idx, grants[i].grant.rv_idx,
|
||||||
snr_db,
|
snr_db,
|
||||||
srslte_pusch_last_noi(&enb_ul.pusch),
|
srslte_pusch_last_noi(&enb_ul.pusch),
|
||||||
crc_res?"OK":"KO",
|
crc_res?"OK":"KO",
|
||||||
(uci_data.uci_ack_len)?(uci_data.uci_ack?"1":"0"):"",
|
uci_data.uci_ack_len>0?(uci_data.uci_ack?", ack=1":", ack=0"):"",
|
||||||
(uci_data.uci_ack_len > 1)?(uci_data.uci_ack_2?"1":"0"):"",
|
|
||||||
uci_data.uci_cqi_len>0?cqi_str:"",
|
uci_data.uci_cqi_len>0?cqi_str:"",
|
||||||
uci_data.uci_ri_len>0?(uci_data.uci_ri?", ri=0":", ri=1"):"",
|
|
||||||
timestr);
|
timestr);
|
||||||
|
|
||||||
// Notify MAC of RL status
|
// Notify MAC of RL status
|
||||||
|
@ -555,28 +503,17 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
|
|
||||||
// Notify MAC new received data and HARQ Indication value
|
// Notify MAC new received data and HARQ Indication value
|
||||||
phy->mac->crc_info(tti_rx, rnti, phy_grant.mcs.tbs/8, crc_res);
|
phy->mac->crc_info(tti_rx, rnti, phy_grant.mcs.tbs/8, crc_res);
|
||||||
uint32_t ack_idx = 0;
|
if (uci_data.uci_ack_len) {
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
phy->mac->ack_info(tti_rx, rnti, uci_data.uci_ack && (crc_res || snr_db > PUSCH_RL_SNR_DB_TH));
|
||||||
if (acks_pending[tb]) {
|
|
||||||
bool ack = ((ack_idx++ == 0) ? uci_data.uci_ack : uci_data.uci_ack_2);
|
|
||||||
bool valid = (crc_res || snr_db > PUSCH_RL_SNR_DB_TH);
|
|
||||||
phy->mac->ack_info(tti_rx, rnti, tb, ack && valid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify MAC of UL SNR, DL CQI and DL RI
|
// Notify MAC of UL SNR and DL CQI
|
||||||
if (snr_db >= PUSCH_RL_SNR_DB_TH) {
|
if (snr_db >= PUSCH_RL_SNR_DB_TH) {
|
||||||
phy->mac->snr_info(tti_rx, rnti, snr_db);
|
phy->mac->snr_info(tti_rx, rnti, snr_db);
|
||||||
}
|
}
|
||||||
if (uci_data.uci_cqi_len>0 && crc_res) {
|
if (uci_data.uci_cqi_len>0 && crc_res) {
|
||||||
phy->mac->cqi_info(tti_rx, rnti, wideband_cqi_value);
|
phy->mac->cqi_info(tti_rx, rnti, wideband_cqi_value);
|
||||||
}
|
}
|
||||||
if (uci_data.uci_ri_len > 0 && crc_res) {
|
|
||||||
phy->mac->ri_info(tti_rx, rnti, uci_data.uci_ri);
|
|
||||||
}
|
|
||||||
if (cqi_value.subband_hl.pmi_present && crc_res) {
|
|
||||||
phy->mac->pmi_info(tti_rx, rnti, cqi_value.subband_hl.pmi);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save metrics stats
|
// Save metrics stats
|
||||||
ue_db[rnti].metrics_ul(phy_grant.mcs.idx, 0, snr_db, srslte_pusch_last_noi(&enb_ul.pusch));
|
ue_db[rnti].metrics_ul(phy_grant.mcs.idx, 0, snr_db, srslte_pusch_last_noi(&enb_ul.pusch));
|
||||||
|
@ -595,8 +532,7 @@ int phch_worker::decode_pucch()
|
||||||
|
|
||||||
if (rnti >= SRSLTE_CRNTI_START && rnti <= SRSLTE_CRNTI_END && ue_db[rnti].has_grant_tti != (int) tti_rx) {
|
if (rnti >= SRSLTE_CRNTI_START && rnti <= SRSLTE_CRNTI_END && ue_db[rnti].has_grant_tti != (int) tti_rx) {
|
||||||
// Check if user needs to receive PUCCH
|
// Check if user needs to receive PUCCH
|
||||||
bool needs_pucch = false, needs_ack[SRSLTE_MAX_TB] = {false}, needs_sr = false, needs_cqi = false,
|
bool needs_pucch = false, needs_ack=false, needs_sr=false, needs_cqi=false;
|
||||||
needs_ri = false;
|
|
||||||
uint32_t last_n_pdcch = 0;
|
uint32_t last_n_pdcch = 0;
|
||||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||||
|
|
||||||
|
@ -608,32 +544,18 @@ int phch_worker::decode_pucch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
if (phy->ack_is_pending(t_rx, rnti, &last_n_pdcch)) {
|
||||||
needs_ack[tb] = phy->ack_is_pending(t_rx, rnti, tb, &last_n_pdcch);
|
needs_pucch = true;
|
||||||
if (needs_ack[tb]) {
|
needs_ack = true;
|
||||||
needs_pucch = true;
|
uci_data.uci_ack_len = 1;
|
||||||
uci_data.uci_ack_len++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
srslte_cqi_value_t cqi_value;
|
srslte_cqi_value_t cqi_value;
|
||||||
LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated = &ue_db[rnti].dedicated;
|
if (ue_db[rnti].cqi_en && (ue_db[rnti].pucch_cqi_ack || !needs_ack)) {
|
||||||
LIBLTE_RRC_TRANSMISSION_MODE_ENUM tx_mode = dedicated->antenna_info_explicit_value.tx_mode;
|
if (srslte_cqi_send(ue_db[rnti].pmi_idx, tti_rx)) {
|
||||||
|
|
||||||
if (ue_db[rnti].cqi_en && (ue_db[rnti].pucch_cqi_ack || !needs_ack[0] || !needs_ack[1])) {
|
|
||||||
if (ue_db[rnti].ri_en && srslte_ri_send(ue_db[rnti].pmi_idx, ue_db[rnti].ri_idx, tti_rx)) {
|
|
||||||
needs_pucch = true;
|
|
||||||
needs_ri = true;
|
|
||||||
uci_data.uci_ri_len = 1;
|
|
||||||
uci_data.ri_periodic_report = true;
|
|
||||||
} else if (srslte_cqi_send(ue_db[rnti].pmi_idx, tti_rx)) {
|
|
||||||
needs_pucch = true;
|
needs_pucch = true;
|
||||||
needs_cqi = true;
|
needs_cqi = true;
|
||||||
cqi_value.type = SRSLTE_CQI_TYPE_WIDEBAND;
|
cqi_value.type = SRSLTE_CQI_TYPE_WIDEBAND;
|
||||||
uci_data.uci_cqi_len = srslte_cqi_size(&cqi_value);
|
uci_data.uci_cqi_len = srslte_cqi_size(&cqi_value);
|
||||||
if (tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
|
||||||
//uci_data.uci_dif_cqi_len = 3;
|
|
||||||
uci_data.uci_pmi_len = 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,48 +564,26 @@ int phch_worker::decode_pucch()
|
||||||
fprintf(stderr, "Error getting PUCCH\n");
|
fprintf(stderr, "Error getting PUCCH\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
/* If only one ACK is required, it can be for TB0 or TB1 */
|
if (uci_data.uci_ack_len > 0) {
|
||||||
uint32_t ack_idx = 0;
|
phy->mac->ack_info(tti_rx, rnti, uci_data.uci_ack && (srslte_pucch_get_last_corr(&enb_ul.pucch) >= PUCCH_RL_CORR_TH));
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
|
||||||
if (needs_ack[tb]) {
|
|
||||||
bool ack = ((ack_idx++ == 0) ? uci_data.uci_ack : uci_data.uci_ack_2);
|
|
||||||
bool valid = srslte_pucch_get_last_corr(&enb_ul.pucch) >= PUCCH_RL_CORR_TH;
|
|
||||||
phy->mac->ack_info(tti_rx, rnti, tb, ack && valid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (uci_data.scheduling_request) {
|
if (uci_data.scheduling_request) {
|
||||||
phy->mac->sr_detected(tti_rx, rnti);
|
phy->mac->sr_detected(tti_rx, rnti);
|
||||||
}
|
}
|
||||||
|
|
||||||
char cqi_ri_str[64];
|
char cqi_str[64];
|
||||||
if (srslte_pucch_get_last_corr(&enb_ul.pucch) > PUCCH_RL_CORR_TH) {
|
if (uci_data.uci_cqi_len) {
|
||||||
if (uci_data.uci_ri_len && needs_ri) {
|
srslte_cqi_value_unpack(uci_data.uci_cqi, &cqi_value);
|
||||||
phy->mac->ri_info(tti_rx, rnti, uci_data.uci_ri);
|
phy->mac->cqi_info(tti_rx, rnti, cqi_value.wideband.wideband_cqi);
|
||||||
sprintf(cqi_ri_str, ", ri=%d", uci_data.uci_ri);
|
sprintf(cqi_str, ", cqi=%d", cqi_value.wideband.wideband_cqi);
|
||||||
} else if (uci_data.uci_cqi_len && needs_cqi) {
|
|
||||||
srslte_cqi_value_unpack(uci_data.uci_cqi, &cqi_value);
|
|
||||||
phy->mac->cqi_info(tti_rx, rnti, cqi_value.wideband.wideband_cqi);
|
|
||||||
sprintf(cqi_ri_str, ", cqi=%d", cqi_value.wideband.wideband_cqi);
|
|
||||||
|
|
||||||
if (uci_data.uci_pmi_len) {
|
|
||||||
uint32_t packed_pmi = uci_data.uci_pmi[0];
|
|
||||||
if (uci_data.uci_pmi_len > 1) {
|
|
||||||
packed_pmi = (packed_pmi << 1) + uci_data.uci_pmi[1];
|
|
||||||
}
|
|
||||||
phy->mac->pmi_info(tti_rx, rnti, packed_pmi);
|
|
||||||
sprintf(cqi_ri_str, "%s, pmi=%c", cqi_ri_str, packed_pmi + 0x30);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log_h->info("PUCCH: rnti=0x%x, corr=%.2f, n_pucch=%d, n_prb=%d%s%s%s%s\n",
|
log_h->info("PUCCH: rnti=0x%x, corr=%.2f, n_pucch=%d, n_prb=%d%s%s%s\n",
|
||||||
rnti,
|
rnti,
|
||||||
srslte_pucch_get_last_corr(&enb_ul.pucch),
|
srslte_pucch_get_last_corr(&enb_ul.pucch),
|
||||||
enb_ul.pucch.last_n_pucch, enb_ul.pucch.last_n_prb,
|
enb_ul.pucch.last_n_pucch, enb_ul.pucch.last_n_prb,
|
||||||
(uci_data.uci_ack_len)?(uci_data.uci_ack?", ack=1":", ack=0"):"",
|
needs_ack?(uci_data.uci_ack?", ack=1":", ack=0"):"",
|
||||||
(uci_data.uci_ack_len > 1)?(uci_data.uci_ack_2?"1":"0"):"",
|
|
||||||
needs_sr?(uci_data.scheduling_request?", sr=yes":", sr=no"):"",
|
needs_sr?(uci_data.scheduling_request?", sr=yes":", sr=no"):"",
|
||||||
(needs_cqi || needs_ri)?cqi_ri_str:"");
|
needs_cqi?cqi_str:"");
|
||||||
|
|
||||||
|
|
||||||
// Notify MAC of RL status
|
// Notify MAC of RL status
|
||||||
|
@ -742,16 +642,25 @@ int phch_worker::encode_pdcch_ul(srslte_enb_ul_pusch_t *grants, uint32_t nof_gra
|
||||||
int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants)
|
int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants)
|
||||||
{
|
{
|
||||||
for (uint32_t i=0;i<nof_grants;i++) {
|
for (uint32_t i=0;i<nof_grants;i++) {
|
||||||
srslte_enb_dl_pdsch_t *grant = &grants[i];
|
uint16_t rnti = grants[i].rnti;
|
||||||
uint16_t rnti = grant->rnti;
|
|
||||||
if (rnti) {
|
if (rnti) {
|
||||||
if (srslte_enb_dl_put_pdcch_dl(&enb_dl, &grants[i].grant, grant->dci_format, grants[i].location, rnti, sf_tx)) {
|
srslte_dci_format_t format = SRSLTE_DCI_FORMAT1;
|
||||||
|
switch(grants[i].grant.alloc_type) {
|
||||||
|
case SRSLTE_RA_ALLOC_TYPE0:
|
||||||
|
case SRSLTE_RA_ALLOC_TYPE1:
|
||||||
|
format = SRSLTE_DCI_FORMAT1;
|
||||||
|
break;
|
||||||
|
case SRSLTE_RA_ALLOC_TYPE2:
|
||||||
|
format = SRSLTE_DCI_FORMAT1A;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (srslte_enb_dl_put_pdcch_dl(&enb_dl, &grants[i].grant, format, grants[i].location, rnti, sf_tx)) {
|
||||||
fprintf(stderr, "Error putting PDCCH %d\n",i);
|
fprintf(stderr, "Error putting PDCCH %d\n",i);
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOG_THIS(rnti)) {
|
if (LOG_THIS(rnti)) {
|
||||||
Info("PDCCH: DL DCI %s rnti=0x%x, cce_index=%d, L=%d, tti_tx_dl=%d\n", srslte_dci_format_string(grant->dci_format),
|
Info("PDCCH: DL DCI %s rnti=0x%x, cce_index=%d, L=%d, tti_tx_dl=%d\n", srslte_dci_format_string(format),
|
||||||
rnti, grants[i].location.ncce, (1<<grants[i].location.L), tti_tx_dl);
|
rnti, grants[i].location.ncce, (1<<grants[i].location.L), tti_tx_dl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -759,8 +668,9 @@ int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_gra
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants) {
|
int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants)
|
||||||
for (uint32_t i = 0; i < nof_grants; i++) {
|
{
|
||||||
|
for (uint32_t i=0;i<nof_grants;i++) {
|
||||||
uint16_t rnti = grants[i].rnti;
|
uint16_t rnti = grants[i].rnti;
|
||||||
if (rnti) {
|
if (rnti) {
|
||||||
|
|
||||||
|
@ -768,95 +678,45 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
|
||||||
if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || rnti == SRSLTE_MRNTI) {
|
if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || rnti == SRSLTE_MRNTI) {
|
||||||
rnti_is_user = false;
|
rnti_is_user = false;
|
||||||
}
|
}
|
||||||
/* Mimo type (tx scheme) shall be single or tx diversity by default */
|
|
||||||
srslte_mimo_type_t mimo_type = (enb_dl.cell.nof_ports == 1) ? SRSLTE_MIMO_TYPE_SINGLE_ANTENNA
|
|
||||||
: SRSLTE_MIMO_TYPE_TX_DIVERSITY;
|
|
||||||
srslte_ra_dl_grant_t phy_grant;
|
srslte_ra_dl_grant_t phy_grant;
|
||||||
srslte_ra_dl_dci_to_grant(&grants[i].grant, enb_dl.cell.nof_prb, rnti, &phy_grant);
|
srslte_ra_dl_dci_to_grant(&grants[i].grant, enb_dl.cell.nof_prb, rnti, &phy_grant);
|
||||||
|
|
||||||
char grant_str[64];
|
char grant_str[64];
|
||||||
switch (grants[i].grant.alloc_type) {
|
switch(grants[i].grant.alloc_type) {
|
||||||
case SRSLTE_RA_ALLOC_TYPE0:
|
case SRSLTE_RA_ALLOC_TYPE0:
|
||||||
sprintf(grant_str, "mask=0x%x", grants[i].grant.type0_alloc.rbg_bitmask);
|
sprintf(grant_str, "mask=0x%x",grants[i].grant.type0_alloc.rbg_bitmask);
|
||||||
break;
|
break;
|
||||||
case SRSLTE_RA_ALLOC_TYPE1:
|
case SRSLTE_RA_ALLOC_TYPE1:
|
||||||
sprintf(grant_str, "mask=0x%x", grants[i].grant.type1_alloc.vrb_bitmask);
|
sprintf(grant_str, "mask=0x%x",grants[i].grant.type1_alloc.vrb_bitmask);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(grant_str, "rb_start=%d", grants[i].grant.type2_alloc.RB_start);
|
sprintf(grant_str, "rb_start=%d",grants[i].grant.type2_alloc.RB_start);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
srslte_dci_format_t dci_format = grants[i].dci_format;
|
|
||||||
switch (dci_format) {
|
|
||||||
case SRSLTE_DCI_FORMAT1:
|
|
||||||
case SRSLTE_DCI_FORMAT1A:
|
|
||||||
/* Do nothing, it keeps default */
|
|
||||||
break;
|
|
||||||
case SRSLTE_DCI_FORMAT2A:
|
|
||||||
if (SRSLTE_RA_DL_GRANT_NOF_TB(&phy_grant) == 1) {
|
|
||||||
mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
|
|
||||||
} else if (SRSLTE_RA_DL_GRANT_NOF_TB(&phy_grant) == 2) {
|
|
||||||
mimo_type = SRSLTE_MIMO_TYPE_CDD;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SRSLTE_DCI_FORMAT2:
|
|
||||||
if (SRSLTE_RA_DL_GRANT_NOF_TB(&phy_grant) == 1) {
|
|
||||||
if (phy_grant.pinfo == 0) {
|
|
||||||
mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
|
|
||||||
} else {
|
|
||||||
mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
|
||||||
}
|
|
||||||
} else if (SRSLTE_RA_DL_GRANT_NOF_TB(&phy_grant) == 2) {
|
|
||||||
mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SRSLTE_DCI_FORMAT0:
|
|
||||||
case SRSLTE_DCI_FORMAT1C:
|
|
||||||
case SRSLTE_DCI_FORMAT1B:
|
|
||||||
case SRSLTE_DCI_FORMAT1D:
|
|
||||||
case SRSLTE_DCI_FORMAT2B:
|
|
||||||
default:
|
|
||||||
Error("Not implemented/Undefined DCI format (%d)\n", dci_format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOG_THIS(rnti)) {
|
if (LOG_THIS(rnti)) {
|
||||||
uint8_t x = 0;
|
uint8_t x = 0;
|
||||||
uint8_t *ptr = grants[i].data[0];
|
uint8_t *ptr = grants[i].data;
|
||||||
uint32_t len = phy_grant.mcs[0].tbs / (uint32_t) 8;
|
uint32_t len = phy_grant.mcs[0].tbs / (uint32_t) 8;
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
ptr = &x;
|
ptr = &x;
|
||||||
len = 1;
|
len = 1;
|
||||||
}
|
}
|
||||||
char pinfo_str[16] = {0};
|
|
||||||
if (dci_format == SRSLTE_DCI_FORMAT2) {
|
|
||||||
snprintf(pinfo_str, 15, ", pinfo=%x", phy_grant.pinfo);
|
|
||||||
}
|
|
||||||
char tbstr[SRSLTE_MAX_TB][128];
|
|
||||||
for (int tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
|
||||||
if (phy_grant.tb_en[tb]) {
|
|
||||||
snprintf(tbstr[tb], 128, ", TB%d: tbs=%d, mcs=%d, rv=%d%s%s",
|
|
||||||
tb,
|
|
||||||
phy_grant.mcs[tb].tbs / 8,
|
|
||||||
phy_grant.mcs[tb].idx,
|
|
||||||
(tb == 0) ? grants[i].grant.rv_idx : grants[i].grant.rv_idx_1,
|
|
||||||
grants[i].softbuffers[tb]==NULL?", \e[31msoftbuffer=NULL\e[0m":"",
|
|
||||||
grants[i].data[tb]==NULL?", \e[31mdata=NULL\e[0m":"");
|
|
||||||
} else {
|
|
||||||
tbstr[tb][0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log_h->info_hex(ptr, len,
|
log_h->info_hex(ptr, len,
|
||||||
"PDSCH: rnti=0x%x, l_crb=%2d, %s, harq=%d, tti_tx_dl=%d, tx_scheme=%s%s%s%s\n",
|
"PDSCH: rnti=0x%x, l_crb=%2d, %s, harq=%d, tbs=%d, mcs=%d, rv=%d, tti_tx_dl=%d\n",
|
||||||
rnti, phy_grant.nof_prb, grant_str, grants[i].grant.harq_process, tti_tx_dl,
|
rnti, phy_grant.nof_prb, grant_str, grants[i].grant.harq_process,
|
||||||
srslte_mimotype2str(mimo_type), pinfo_str, tbstr[0], tbstr[1]);
|
phy_grant.mcs[0].tbs/8, phy_grant.mcs[0].idx, grants[i].grant.rv_idx, tti_tx_dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rv[SRSLTE_MAX_CODEWORDS] = {grants[i].grant.rv_idx, grants[i].grant.rv_idx_1};
|
srslte_softbuffer_tx_t *sb[SRSLTE_MAX_CODEWORDS] = {grants[i].softbuffer, NULL};
|
||||||
|
uint8_t *d[SRSLTE_MAX_CODEWORDS] = {grants[i].data, NULL};
|
||||||
|
int rv[SRSLTE_MAX_CODEWORDS] = {grants[i].grant.rv_idx, 0};
|
||||||
|
|
||||||
if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, grants[i].softbuffers, rnti, rv, sf_tx, grants[i].data, mimo_type)) {
|
|
||||||
fprintf(stderr, "Error putting PDSCH %d\n", i);
|
if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, sb, rnti, rv, sf_tx, d, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error putting PDSCH %d\n",i);
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1142,11 +1142,7 @@ void rrc::ue::send_connection_setup(bool is_setup)
|
||||||
phy_cfg->cqi_report_cnfg_present = true;
|
phy_cfg->cqi_report_cnfg_present = true;
|
||||||
if(parent->cfg.cqi_cfg.mode == RRC_CFG_CQI_MODE_APERIODIC) {
|
if(parent->cfg.cqi_cfg.mode == RRC_CFG_CQI_MODE_APERIODIC) {
|
||||||
phy_cfg->cqi_report_cnfg.report_mode_aperiodic_present = true;
|
phy_cfg->cqi_report_cnfg.report_mode_aperiodic_present = true;
|
||||||
if (phy_cfg->antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
phy_cfg->cqi_report_cnfg.report_mode_aperiodic = LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30;
|
||||||
phy_cfg->cqi_report_cnfg.report_mode_aperiodic = LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31;
|
|
||||||
} else {
|
|
||||||
phy_cfg->cqi_report_cnfg.report_mode_aperiodic = LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
phy_cfg->cqi_report_cnfg.report_periodic_present = true;
|
phy_cfg->cqi_report_cnfg.report_periodic_present = true;
|
||||||
phy_cfg->cqi_report_cnfg.report_periodic_setup_present = true;
|
phy_cfg->cqi_report_cnfg.report_periodic_setup_present = true;
|
||||||
|
|
|
@ -859,9 +859,7 @@ void phch_worker::set_uci_periodic_cqi()
|
||||||
|
|
||||||
if (period_cqi.configured && rnti_is_set) {
|
if (period_cqi.configured && rnti_is_set) {
|
||||||
if (period_cqi.ri_idx_present && srslte_ri_send(period_cqi.pmi_idx, period_cqi.ri_idx, TTI_TX(tti))) {
|
if (period_cqi.ri_idx_present && srslte_ri_send(period_cqi.pmi_idx, period_cqi.ri_idx, TTI_TX(tti))) {
|
||||||
/* Compute RI, PMI and SINR */
|
|
||||||
compute_ri();
|
compute_ri();
|
||||||
|
|
||||||
uci_data.ri_periodic_report = true;
|
uci_data.ri_periodic_report = true;
|
||||||
Info("PUCCH: Periodic RI=%d\n", uci_data.uci_ri);
|
Info("PUCCH: Periodic RI=%d\n", uci_data.uci_ri);
|
||||||
} else if (srslte_cqi_send(period_cqi.pmi_idx, TTI_TX(tti))) {
|
} else if (srslte_cqi_send(period_cqi.pmi_idx, TTI_TX(tti))) {
|
||||||
|
@ -904,9 +902,6 @@ void phch_worker::set_uci_periodic_cqi()
|
||||||
void phch_worker::set_uci_aperiodic_cqi()
|
void phch_worker::set_uci_aperiodic_cqi()
|
||||||
{
|
{
|
||||||
if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) {
|
if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) {
|
||||||
/* Compute RI, PMI and SINR */
|
|
||||||
compute_ri();
|
|
||||||
|
|
||||||
switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) {
|
switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) {
|
||||||
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30:
|
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30:
|
||||||
/* only Higher Layer-configured subband feedback support right now, according to TS36.213 section 7.2.1
|
/* only Higher Layer-configured subband feedback support right now, according to TS36.213 section 7.2.1
|
||||||
|
@ -944,6 +939,9 @@ void phch_worker::set_uci_aperiodic_cqi()
|
||||||
other transmission modes they are reported conditioned on rank 1.
|
other transmission modes they are reported conditioned on rank 1.
|
||||||
*/
|
*/
|
||||||
if (rnti_is_set) {
|
if (rnti_is_set) {
|
||||||
|
/* Compute RI, PMI and SINR */
|
||||||
|
compute_ri();
|
||||||
|
|
||||||
/* Select RI, PMI and SINR */
|
/* Select RI, PMI and SINR */
|
||||||
uint32_t ri = ue_dl.ri; // Select RI (0: 1 layer, 1: 2 layer, otherwise: not implemented)
|
uint32_t ri = ue_dl.ri; // Select RI (0: 1 layer, 1: 2 layer, otherwise: not implemented)
|
||||||
uint32_t pmi = ue_dl.pmi[ri]; // Select PMI
|
uint32_t pmi = ue_dl.pmi[ri]; // Select PMI
|
||||||
|
@ -974,9 +972,9 @@ void phch_worker::set_uci_aperiodic_cqi()
|
||||||
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1,
|
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1,
|
||||||
sinr_db, sinr_db, pmi, cqi_report.subband_hl.N);
|
sinr_db, sinr_db, pmi, cqi_report.subband_hl.N);
|
||||||
} else {
|
} else {
|
||||||
Info("PUSCH: Aperiodic ri=1, CQI=%02d, SINR=%2.1f, pmi=%d for %d subbands\n",
|
Info("PUSCH: Aperiodic ri=1, CQI=%d/%d, SINR=%2.1f dB, for %d subbands\n",
|
||||||
cqi_report.subband_hl.wideband_cqi_cw0,
|
cqi_report.wideband.wideband_cqi,
|
||||||
sinr_db, pmi, cqi_report.subband_hl.N);
|
phy->avg_snr_db, cqi_report.subband_hl.N);
|
||||||
}
|
}
|
||||||
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue