/* Encode UCI ACK/RI bits as described in 5.2.2.6 of 36.212 * Currently only supporting 1-bit RI */ int srslte_uci_encode_ack_ri(srslte_pusch_cfg_t* cfg, uint8_t* data, uint32_t O_ack, uint32_t O_cqi, float beta, uint32_t H_prime_total, bool input_is_ri, uint32_t N_bundle, srslte_uci_bit_t* bits) { if (beta < 0) { ERROR("Error beta is reserved\n"); return -1; } uint32_t Q_prime = Q_prime_ri_ack(cfg, O_ack, O_cqi, beta); uint32_t Q_ack = 0; uint32_t Qm = srslte_mod_bits_x_symbol(cfg->grant.tb.mod); if (O_ack < 3) { uint32_t enc_len = encode_ri_ack(data, O_ack, Qm, bits); // Repeat bits Q_prime times, remainder bits will be ignored later while (Q_ack < Q_prime * Qm) { for (uint32_t j = 0; j < enc_len; j++) { bits[Q_ack++].type = bits[j].type; } } } else { Q_ack = encode_ack_long(data, O_ack, Qm, Q_prime, bits); } // Generate interleaver positions if (Q_ack > 0) { for (uint32_t i = 0; i < Q_prime; i++) { if (input_is_ri) { uci_ulsch_interleave_ri_gen(i, Qm, H_prime_total, cfg->grant.nof_symb, &bits[Qm * i]); } else { uci_ulsch_interleave_ack_gen(i, Qm, H_prime_total, cfg->grant.nof_symb, &bits[Qm * i]); } } // TDD-bundling scrambling if (!input_is_ri && N_bundle && O_ack > 0) { uci_ack_scramble_tdd(bits, O_ack, Q_prime * Qm, N_bundle); } } return (int)Q_prime; }
/* Decode UCI ACK/RI bits as described in 5.2.2.6 of 36.212 * 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, 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) { int32_t sum[3] = {0, 0, 0}; if (beta < 0) { fprintf(stderr, "Error beta is reserved\n"); return -1; } uint32_t Qprime = Q_prime_ri_ack(cfg, nof_bits, O_cqi, beta); for (uint32_t i = 0; i < Qprime; i++) { if (is_ri) { uci_ulsch_interleave_ri_gen(i, cfg->grant.Qm, H_prime_total, 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 (nof_bits == 2) { data[1] = (uint8_t) (sum[1] > 0); } return (int) Qprime; }
/* Encode UCI ACK/RI bits as described in 5.2.2.6 of 36.212 * Currently only supporting 1-bit RI */ int srslte_uci_encode_ack_ri(srslte_pusch_cfg_t *cfg, uint8_t *data, uint32_t data_len, uint32_t O_cqi, float beta, uint32_t H_prime_total, srslte_uci_bit_t *bits, bool ack_ri) { if (beta < 0) { fprintf(stderr, "Error beta is reserved\n"); return -1; } uint32_t Qprime = Q_prime_ri_ack(cfg, data_len, O_cqi, beta); 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); if (nof_encoded_bits > 0) { for (uint32_t i = 0; i < Qprime; i++) { if (ack_ri) { uci_ulsch_interleave_ri_gen(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; }
/* 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; }