mirror of https://github.com/PentHertz/srsLTE.git
Added 2nd Codeword interface in scheduler, plus pmi close loop reporting
This commit is contained in:
parent
af669a6cbb
commit
6985682ef0
|
@ -65,6 +65,7 @@ public:
|
|||
virtual int rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv) = 0;
|
||||
|
||||
virtual int ri_info(uint32_t tti, uint16_t rnti, uint32_t ri_value) = 0;
|
||||
virtual int pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value) = 0;
|
||||
virtual int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) = 0;
|
||||
virtual int snr_info(uint32_t tti, uint16_t rnti, float snr_db) = 0;
|
||||
virtual int ack_info(uint32_t tti, uint16_t rnti, bool ack) = 0;
|
||||
|
@ -113,6 +114,7 @@ public:
|
|||
/* Manages UE bearers and associated configuration */
|
||||
virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t *cfg) = 0;
|
||||
virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0;
|
||||
virtual int set_dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) = 0;
|
||||
virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0;
|
||||
|
||||
};
|
||||
|
|
|
@ -131,9 +131,10 @@ public:
|
|||
|
||||
typedef struct {
|
||||
uint32_t rnti;
|
||||
srslte_dci_format_t dci_format;
|
||||
srslte_ra_dl_dci_t dci;
|
||||
srslte_dci_location_t dci_location;
|
||||
uint32_t tbs;
|
||||
uint32_t tbs[SRSLTE_MAX_TB];
|
||||
bool mac_ce_ta;
|
||||
bool mac_ce_rnti;
|
||||
uint32_t nof_pdu_elems;
|
||||
|
@ -228,6 +229,7 @@ public:
|
|||
virtual int dl_ack_info(uint32_t tti, uint16_t rnti, bool ack) = 0;
|
||||
virtual int dl_rach_info(uint32_t tti, uint32_t ra_id, uint16_t rnti, uint32_t estimated_size) = 0;
|
||||
virtual int dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t ri_value) = 0;
|
||||
virtual int dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value) = 0;
|
||||
virtual int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) = 0;
|
||||
|
||||
/* UL information */
|
||||
|
|
|
@ -95,6 +95,7 @@ typedef struct SRSLTE_API {
|
|||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
srslte_dci_format_t dci_format;
|
||||
srslte_ra_dl_dci_t grant;
|
||||
srslte_dci_location_t location;
|
||||
srslte_softbuffer_tx_t *softbuffers[SRSLTE_MAX_TB];
|
||||
|
@ -162,8 +163,7 @@ SRSLTE_API int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q,
|
|||
int rv_idx[SRSLTE_MAX_CODEWORDS],
|
||||
uint32_t sf_idx,
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
srslte_mimo_type_t mimo_type,
|
||||
uint32_t pmi);
|
||||
srslte_mimo_type_t mimo_type);
|
||||
|
||||
SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q,
|
||||
srslte_ra_dl_dci_t *grant,
|
||||
|
|
|
@ -326,8 +326,30 @@ int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, srslte_ra_ul_dci_t *grant,
|
|||
|
||||
int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer[SRSLTE_MAX_CODEWORDS],
|
||||
uint16_t rnti, int rv_idx[SRSLTE_MAX_CODEWORDS], uint32_t sf_idx,
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, uint32_t pmi)
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type)
|
||||
{
|
||||
uint32_t pmi = 0;
|
||||
uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(grant);
|
||||
|
||||
/* Translates Precoding Information (pinfo) to Precoding matrix Index (pmi) as 3GPP 36.212 Table 5.3.3.1.5-4 */
|
||||
if (mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
|
||||
if (nof_tb == 1) {
|
||||
if (grant->pinfo > 0 && grant->pinfo < 5) {
|
||||
pmi = grant->pinfo - 1;
|
||||
} else {
|
||||
ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (grant->pinfo < 2) {
|
||||
pmi = grant->pinfo;
|
||||
} else {
|
||||
ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure pdsch_cfg parameters */
|
||||
if (srslte_pdsch_cfg_mimo(&q->pdsch_cfg, q->cell, grant, q->cfi, sf_idx, rv_idx, mimo_type, pmi)) {
|
||||
fprintf(stderr, "Error configuring PDSCH\n");
|
||||
|
|
|
@ -323,9 +323,17 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti,
|
|||
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) {
|
||||
uint8_t *ptr = pucch_bits;
|
||||
uci_data->uci_ri = (uint8_t) srslte_bit_pack(&ptr, 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) {
|
||||
|
|
|
@ -677,6 +677,7 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo
|
|||
}
|
||||
|
||||
/* Set RI */
|
||||
q->ri = best_ri;
|
||||
if (ri != NULL) {
|
||||
*ri = best_ri;
|
||||
}
|
||||
|
@ -712,9 +713,10 @@ int srslte_ue_dl_ri_select(srslte_ue_dl_t *q, uint8_t *ri, float *cn) {
|
|||
*cn = _cn;
|
||||
}
|
||||
|
||||
q->ri = (uint8_t)((_cn < 17.0f)? 1:0);
|
||||
/* Set rank indicator */
|
||||
if (!ret && ri) {
|
||||
*ri = (uint8_t)((_cn < 17.0f)? 1:0);
|
||||
*ri = (uint8_t) q->ri;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -281,8 +281,9 @@ void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format
|
|||
}
|
||||
if (format >= SRSLTE_PUCCH_FORMAT_2) {
|
||||
/* Append RI */
|
||||
uint8_t *ptr = uci_buffer;
|
||||
srslte_bit_unpack(uci_data->uci_ri, &ptr, uci_data->uci_ri_len);
|
||||
if (uci_data->uci_ri_len) {
|
||||
uci_data->uci_ri = uci_buffer[0]; // It assumes only 1 bit of RI
|
||||
}
|
||||
uci_buffer_len += uci_data->uci_ri_len;
|
||||
|
||||
/* Append CQI */
|
||||
|
|
|
@ -72,7 +72,10 @@ public:
|
|||
int sr_detected(uint32_t tti, uint16_t rnti);
|
||||
int rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv);
|
||||
|
||||
int set_dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info);
|
||||
|
||||
int ri_info(uint32_t tti, uint16_t rnti, uint32_t ri_value);
|
||||
int pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value);
|
||||
int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value);
|
||||
int snr_info(uint32_t tti, uint16_t rnti, float snr);
|
||||
int ack_info(uint32_t tti, uint16_t rnti, bool ack);
|
||||
|
|
|
@ -45,6 +45,7 @@ struct mac_metrics_t
|
|||
int dl_buffer;
|
||||
float dl_cqi;
|
||||
float dl_ri;
|
||||
float dl_pmi;
|
||||
float phr;
|
||||
};
|
||||
|
||||
|
|
|
@ -103,9 +103,11 @@ public:
|
|||
int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue);
|
||||
int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code);
|
||||
|
||||
int dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dedicated);
|
||||
int dl_ack_info(uint32_t tti, uint16_t rnti, bool ack);
|
||||
int dl_rach_info(uint32_t tti, uint32_t ra_id, uint16_t rnti, uint32_t estimated_size);
|
||||
int dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t ri_value);
|
||||
int dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value);
|
||||
int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value);
|
||||
|
||||
int ul_crc_info(uint32_t tti, uint16_t rnti, bool crc);
|
||||
|
|
|
@ -38,50 +38,50 @@ class harq_proc
|
|||
public:
|
||||
void config(uint32_t id, uint32_t max_retx, srslte::log* log_h);
|
||||
void set_max_retx(uint32_t max_retx);
|
||||
void reset();
|
||||
void reset(uint32_t tb_idx);
|
||||
uint32_t get_id();
|
||||
bool is_empty();
|
||||
bool is_empty(uint32_t tb_idx);
|
||||
|
||||
void new_retx(uint32_t tti, int *mcs, int *tbs);
|
||||
void new_retx(uint32_t tb_idx, uint32_t tti, int *mcs, int *tbs);
|
||||
|
||||
bool get_ack();
|
||||
void set_ack(bool ack);
|
||||
bool get_ack(uint32_t tb_idx);
|
||||
void set_ack(uint32_t tb_idx, bool ack);
|
||||
|
||||
uint32_t nof_tx();
|
||||
uint32_t nof_retx();
|
||||
uint32_t nof_tx(uint32_t tb_idx);
|
||||
uint32_t nof_retx(uint32_t tb_idx);
|
||||
uint32_t get_tti();
|
||||
bool get_ndi();
|
||||
bool get_ndi(uint32_t tb_idx);
|
||||
|
||||
protected:
|
||||
|
||||
void new_tx_common(uint32_t tti, int mcs, int tbs);
|
||||
bool has_pending_retx_common();
|
||||
void new_tx_common(uint32_t tb_idx, uint32_t tti, int mcs, int tbs);
|
||||
bool has_pending_retx_common(uint32_t tb_idx);
|
||||
|
||||
bool ack;
|
||||
bool ack[SRSLTE_MAX_TB];
|
||||
bool active;
|
||||
bool ndi;
|
||||
bool ndi[SRSLTE_MAX_TB];
|
||||
uint32_t id;
|
||||
uint32_t max_retx;
|
||||
uint32_t n_rtx;
|
||||
uint32_t tx_cnt;
|
||||
uint32_t n_rtx[SRSLTE_MAX_TB];
|
||||
uint32_t tx_cnt[SRSLTE_MAX_TB];
|
||||
int tti;
|
||||
int last_mcs;
|
||||
int last_tbs;
|
||||
int last_mcs[SRSLTE_MAX_TB];
|
||||
int last_tbs[SRSLTE_MAX_TB];
|
||||
|
||||
srslte::log* log_h;
|
||||
|
||||
private:
|
||||
bool ack_received;
|
||||
bool ack_received[SRSLTE_MAX_TB];
|
||||
};
|
||||
|
||||
class dl_harq_proc : public harq_proc
|
||||
{
|
||||
public:
|
||||
void new_tx(uint32_t tti, int mcs, int tbs, uint32_t n_cce);
|
||||
void new_tx(uint32_t tb_idx, uint32_t tti, int mcs, int tbs, uint32_t n_cce);
|
||||
uint32_t get_rbgmask();
|
||||
void set_rbgmask(uint32_t new_mask);
|
||||
bool has_pending_retx(uint32_t tti);
|
||||
int get_tbs();
|
||||
bool has_pending_retx(uint32_t tb_idx, uint32_t tti);
|
||||
int get_tbs(uint32_t tb_idx);
|
||||
uint32_t get_n_cce();
|
||||
private:
|
||||
uint32_t rbgmask;
|
||||
|
|
|
@ -68,8 +68,10 @@ public:
|
|||
void ul_phr(int phr);
|
||||
void mac_buffer_state(uint32_t ce_code);
|
||||
void ul_recv_len(uint32_t lcid, uint32_t len);
|
||||
void set_dl_ant_info(LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dedicated);
|
||||
void set_ul_cqi(uint32_t tti, uint32_t cqi, uint32_t ul_ch_code);
|
||||
void set_dl_ri(uint32_t tti, uint32_t ri);
|
||||
void set_dl_pmi(uint32_t tti, uint32_t ri);
|
||||
void set_dl_cqi(uint32_t tti, uint32_t cqi);
|
||||
int set_ack_info(uint32_t tti, bool ack);
|
||||
void set_ul_crc(uint32_t tti, bool crc_res);
|
||||
|
@ -108,8 +110,11 @@ public:
|
|||
void unset_sr();
|
||||
|
||||
int generate_format1(dl_harq_proc *h, sched_interface::dl_sched_data_t *data, uint32_t tti, uint32_t cfi);
|
||||
int generate_format2a(dl_harq_proc *h, sched_interface::dl_sched_data_t *data, uint32_t tti, uint32_t cfi);
|
||||
int generate_format2(dl_harq_proc *h, sched_interface::dl_sched_data_t *data, uint32_t tti, uint32_t cfi);
|
||||
int generate_format0(ul_harq_proc *h, sched_interface::ul_sched_data_t *data, uint32_t tti, bool cqi_request);
|
||||
|
||||
srslte_dci_format_t get_dci_format();
|
||||
uint32_t get_aggr_level(uint32_t nof_bits);
|
||||
sched_dci_cce_t *get_locations(uint32_t current_cfi, uint32_t sf_idx);
|
||||
|
||||
|
@ -158,6 +163,8 @@ private:
|
|||
int power_headroom;
|
||||
uint32_t dl_ri;
|
||||
uint32_t dl_ri_tti;
|
||||
uint32_t dl_pmi;
|
||||
uint32_t dl_pmi_tti;
|
||||
uint32_t dl_cqi;
|
||||
uint32_t dl_cqi_tti;
|
||||
uint32_t cqi_request_tti;
|
||||
|
@ -180,6 +187,7 @@ private:
|
|||
ul_harq_proc ul_harq[SCHED_MAX_HARQ_PROC];
|
||||
|
||||
bool phy_config_dedicated_enabled;
|
||||
LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT dl_ant_info;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ public:
|
|||
void metrics_tx(bool crc, uint32_t tbs);
|
||||
void metrics_phr(float phr);
|
||||
void metrics_dl_ri(uint32_t dl_cqi);
|
||||
void metrics_dl_pmi(uint32_t dl_cqi);
|
||||
void metrics_dl_cqi(uint32_t dl_cqi);
|
||||
|
||||
|
||||
|
@ -110,6 +111,7 @@ private:
|
|||
uint32_t phr_counter;
|
||||
uint32_t dl_cqi_counter;
|
||||
uint32_t dl_ri_counter;
|
||||
uint32_t dl_pmi_counter;
|
||||
mac_metrics_t metrics;
|
||||
|
||||
srslte::mac_pcap* pcap;
|
||||
|
|
|
@ -305,6 +305,18 @@ int mac::crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc)
|
|||
}
|
||||
}
|
||||
|
||||
int mac::set_dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) {
|
||||
log_h->step(tti);
|
||||
|
||||
if (ue_db.count(rnti)) {
|
||||
scheduler.dl_ant_info(rnti, dl_ant_info);
|
||||
} else {
|
||||
Error("User rnti=0x%x not found\n", rnti);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t ri_value)
|
||||
{
|
||||
log_h->step(tti);
|
||||
|
@ -319,6 +331,20 @@ int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t ri_value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value)
|
||||
{
|
||||
log_h->step(tti);
|
||||
|
||||
if (ue_db.count(rnti)) {
|
||||
scheduler.dl_pmi_info(tti, rnti, pmi_value);
|
||||
ue_db[rnti]->metrics_dl_pmi(pmi_value);
|
||||
} else {
|
||||
Error("User rnti=0x%x not found\n", rnti);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value)
|
||||
{
|
||||
log_h->step(tti);
|
||||
|
@ -445,6 +471,7 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res)
|
|||
|
||||
// Copy grant info
|
||||
dl_sched_res->sched_grants[n].rnti = rnti;
|
||||
dl_sched_res->sched_grants[n].dci_format = sched_result.data[i].dci_format;
|
||||
memcpy(&dl_sched_res->sched_grants[n].grant, &sched_result.data[i].dci, sizeof(srslte_ra_dl_dci_t));
|
||||
memcpy(&dl_sched_res->sched_grants[n].location, &sched_result.data[i].dci_location, sizeof(srslte_dci_location_t));
|
||||
|
||||
|
@ -454,10 +481,10 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res)
|
|||
if (sched_result.data[i].nof_pdu_elems > 0) {
|
||||
dl_sched_res->sched_grants[n].data[0] = ue_db[rnti]->generate_pdu(sched_result.data[i].pdu,
|
||||
sched_result.data[i].nof_pdu_elems,
|
||||
sched_result.data[i].tbs);
|
||||
sched_result.data[i].tbs[0]);
|
||||
|
||||
if (pcap) {
|
||||
pcap->write_dl_crnti(dl_sched_res->sched_grants[n].data[0], sched_result.data[i].tbs, rnti, true, tti);
|
||||
pcap->write_dl_crnti(dl_sched_res->sched_grants[n].data[0], sched_result.data[i].tbs[0], rnti, true, tti);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -470,6 +497,7 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res)
|
|||
for (uint32_t i=0;i<sched_result.nof_rar_elems;i++) {
|
||||
// Copy grant info
|
||||
dl_sched_res->sched_grants[n].rnti = sched_result.rar[i].rarnti;
|
||||
dl_sched_res->sched_grants[n].dci_format = SRSLTE_DCI_FORMAT1A; // Force Format 1A
|
||||
memcpy(&dl_sched_res->sched_grants[n].grant, &sched_result.rar[i].dci, sizeof(srslte_ra_dl_dci_t));
|
||||
memcpy(&dl_sched_res->sched_grants[n].location, &sched_result.rar[i].dci_location, sizeof(srslte_dci_location_t));
|
||||
|
||||
|
@ -481,7 +509,7 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res)
|
|||
|
||||
|
||||
if (pcap) {
|
||||
pcap->write_dl_ranti(dl_sched_res->sched_grants[n].data[0], sched_result.data[i].tbs, dl_sched_res->sched_grants[n].rnti, true, tti);
|
||||
pcap->write_dl_ranti(dl_sched_res->sched_grants[n].data[0], sched_result.data[i].tbs[0], dl_sched_res->sched_grants[n].rnti, true, tti);
|
||||
}
|
||||
|
||||
n++;
|
||||
|
@ -491,6 +519,7 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res)
|
|||
for (uint32_t i=0;i<sched_result.nof_bc_elems;i++) {
|
||||
// Copy grant info
|
||||
dl_sched_res->sched_grants[n].rnti = (sched_result.bc[i].type == sched_interface::dl_sched_bc_t::BCCH ) ? SRSLTE_SIRNTI : SRSLTE_PRNTI;
|
||||
dl_sched_res->sched_grants[n].dci_format = SRSLTE_DCI_FORMAT1A; // Force Format 1A
|
||||
memcpy(&dl_sched_res->sched_grants[n].grant, &sched_result.bc[i].dci, sizeof(srslte_ra_dl_dci_t));
|
||||
memcpy(&dl_sched_res->sched_grants[n].location, &sched_result.bc[i].dci_location, sizeof(srslte_dci_location_t));
|
||||
|
||||
|
|
|
@ -238,6 +238,19 @@ int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int sched::dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
int ret = 0;
|
||||
if (ue_db.count(rnti)) {
|
||||
ue_db[rnti].set_dl_ant_info(dl_ant_info);
|
||||
} else {
|
||||
Error("User rnti=0x%x not found\n", rnti);
|
||||
ret = -1;
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sched::dl_ack_info(uint32_t tti, uint16_t rnti, bool ack)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
@ -280,6 +293,20 @@ int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
int ret = 0;
|
||||
if (ue_db.count(rnti)) {
|
||||
ue_db[rnti].set_dl_pmi(tti, pmi_value);
|
||||
} else {
|
||||
Error("User rnti=0x%x not found\n", rnti);
|
||||
ret = -1;
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value)
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
@ -611,19 +638,34 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST])
|
|||
uint16_t rnti = (uint16_t) iter->first;
|
||||
|
||||
dl_harq_proc *h = dl_metric->get_user_allocation(user);
|
||||
srslte_dci_format_t dci_format = user->get_dci_format();
|
||||
data[nof_data_elems].dci_format = dci_format;
|
||||
|
||||
if (h) {
|
||||
// Try to schedule DCI first
|
||||
if (generate_dci(&data[nof_data_elems].dci_location,
|
||||
user->get_locations(current_cfi, sf_idx),
|
||||
user->get_aggr_level(srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, cfg.cell.nof_prb, cfg.cell.nof_ports)), user))
|
||||
user->get_aggr_level(srslte_dci_format_sizeof(dci_format, cfg.cell.nof_prb, cfg.cell.nof_ports)), user))
|
||||
{
|
||||
bool is_newtx = h->is_empty();
|
||||
int tbs = user->generate_format1(h, &data[nof_data_elems], current_tti, current_cfi);
|
||||
bool is_newtx = h->is_empty(0);
|
||||
int tbs = 0;
|
||||
switch(dci_format) {
|
||||
case SRSLTE_DCI_FORMAT1:
|
||||
tbs = user->generate_format1(h, &data[nof_data_elems], current_tti, current_cfi);
|
||||
break;
|
||||
case SRSLTE_DCI_FORMAT2:
|
||||
tbs = user->generate_format2(h, &data[nof_data_elems], current_tti, current_cfi);
|
||||
break;
|
||||
case SRSLTE_DCI_FORMAT2A:
|
||||
tbs = user->generate_format2a(h, &data[nof_data_elems], current_tti, current_cfi);
|
||||
break;
|
||||
default:
|
||||
Error("DCI format (%d) not implemented\n", dci_format);
|
||||
}
|
||||
if (tbs >= 0) {
|
||||
log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d\n",
|
||||
!is_newtx?"retx":"tx", rnti, h->get_id(), h->get_rbgmask(),
|
||||
data[nof_data_elems].dci_location.L, data[nof_data_elems].dci_location.ncce, h->nof_retx(),
|
||||
data[nof_data_elems].dci_location.L, data[nof_data_elems].dci_location.ncce, h->nof_retx(0),
|
||||
tbs, user->get_pending_dl_new_data(current_tti));
|
||||
nof_data_elems++;
|
||||
} else {
|
||||
|
@ -633,7 +675,7 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST])
|
|||
tbs, user->get_pending_dl_new_data(current_tti));
|
||||
}
|
||||
} else {
|
||||
h->reset();
|
||||
h->reset(0);
|
||||
Warning("SCHED: Could not schedule DL DCI for rnti=0x%x, pid=%d\n", rnti, h->get_id());
|
||||
}
|
||||
}
|
||||
|
@ -721,7 +763,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
|
|||
|
||||
/* Indicate PHICH acknowledgment if needed */
|
||||
if (h->has_pending_ack()) {
|
||||
sched_result->phich[nof_phich_elems].phich = h->get_ack()?ul_sched_phich_t::ACK:ul_sched_phich_t::NACK;
|
||||
sched_result->phich[nof_phich_elems].phich = h->get_ack(0)?ul_sched_phich_t::ACK:ul_sched_phich_t::NACK;
|
||||
sched_result->phich[nof_phich_elems].rnti = rnti;
|
||||
nof_phich_elems++;
|
||||
}
|
||||
|
@ -778,7 +820,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
|
|||
if (h)
|
||||
{
|
||||
ul_harq_proc::ul_alloc_t alloc = h->get_alloc();
|
||||
bool is_newtx = h->is_empty();
|
||||
bool is_newtx = h->is_empty(0);
|
||||
bool needs_pdcch = !h->is_adaptive_retx() && !is_rar;
|
||||
|
||||
// Set number of retx
|
||||
|
@ -797,7 +839,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
|
|||
user->get_locations(current_cfi, sf_idx),
|
||||
aggr_level))
|
||||
{
|
||||
h->reset();
|
||||
h->reset(0);
|
||||
log_h->warning("SCHED: Could not schedule UL DCI rnti=0x%x, pid=%d, L=%d\n",
|
||||
rnti, h->get_id(), aggr_level);
|
||||
sched_result->pusch[nof_dci_elems].needs_pdcch = false;
|
||||
|
@ -824,7 +866,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
|
|||
is_newtx?"tx":"retx",
|
||||
rnti, h->get_id(),
|
||||
sched_result->pusch[nof_dci_elems].dci_location.L, sched_result->pusch[nof_dci_elems].dci_location.ncce,
|
||||
alloc.RB_start, alloc.RB_start+alloc.L, h->nof_retx(), sched_result->pusch[nof_dci_elems].tbs,
|
||||
alloc.RB_start, alloc.RB_start+alloc.L, h->nof_retx(0), sched_result->pusch[nof_dci_elems].tbs,
|
||||
user->get_pending_ul_new_data(current_tti),pending_data_before, user->get_pending_ul_old_data());
|
||||
|
||||
nof_dci_elems++;
|
||||
|
|
|
@ -50,7 +50,9 @@ void harq_proc::config(uint32_t id_, uint32_t max_retx_, srslte::log* log_h_)
|
|||
log_h = log_h_;
|
||||
id = id_;
|
||||
max_retx = max_retx_;
|
||||
ndi = false;
|
||||
for (int i = 0; i < SRSLTE_MAX_TB; i++) {
|
||||
ndi[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void harq_proc::set_max_retx(uint32_t max_retx_) {
|
||||
|
@ -63,57 +65,57 @@ uint32_t harq_proc::get_id()
|
|||
return id;
|
||||
}
|
||||
|
||||
void harq_proc::reset()
|
||||
void harq_proc::reset(uint32_t tb_idx)
|
||||
{
|
||||
active = false;
|
||||
ack = true;
|
||||
ack_received = false;
|
||||
n_rtx = 0;
|
||||
ack[tb_idx] = true;
|
||||
ack_received[tb_idx] = false;
|
||||
n_rtx[tb_idx] = 0;
|
||||
tti = 0;
|
||||
last_mcs = -1;
|
||||
last_tbs = -1;
|
||||
tx_cnt = 0;
|
||||
last_mcs[tb_idx] = -1;
|
||||
last_tbs[tb_idx] = -1;
|
||||
tx_cnt[tb_idx] = 0;
|
||||
}
|
||||
|
||||
bool harq_proc::is_empty()
|
||||
bool harq_proc::is_empty(uint32_t tb_idx)
|
||||
{
|
||||
return !active || (active && ack && ack_received);
|
||||
return !active || (active && ack[tb_idx] && ack_received[tb_idx]);
|
||||
}
|
||||
|
||||
bool harq_proc::has_pending_retx_common()
|
||||
bool harq_proc::has_pending_retx_common(uint32_t tb_idx)
|
||||
{
|
||||
return !ack && n_rtx < max_retx;
|
||||
return !ack[tb_idx] && n_rtx[tb_idx] < max_retx;
|
||||
}
|
||||
|
||||
uint32_t harq_proc::get_tti()
|
||||
{
|
||||
return tti;
|
||||
return (uint32_t) tti;
|
||||
}
|
||||
|
||||
bool harq_proc::get_ack()
|
||||
bool harq_proc::get_ack(uint32_t tb_idx)
|
||||
{
|
||||
return ack;
|
||||
return ack[tb_idx];
|
||||
}
|
||||
|
||||
void harq_proc::set_ack(bool ack_)
|
||||
void harq_proc::set_ack(uint32_t tb_idx, bool ack_)
|
||||
{
|
||||
ack = ack_;
|
||||
ack_received = true;
|
||||
log_h->debug("ACK=%d received pid=%d, n_rtx=%d, max_retx=%d\n", ack_, id, n_rtx, max_retx);
|
||||
if (n_rtx + 1 >= max_retx) {
|
||||
Warning("SCHED: discarting TB pid=%d, tti=%d, maximum number of retx exceeded (%d)\n", id, tti, max_retx);
|
||||
ack[tb_idx] = ack_;
|
||||
ack_received[tb_idx] = true;
|
||||
log_h->debug("ACK=%d received pid=%d, tb_idx=%d, n_rtx=%d, max_retx=%d\n", ack_, id, tb_idx, n_rtx[tb_idx], max_retx);
|
||||
if (n_rtx[tb_idx] + 1 >= max_retx) {
|
||||
Warning("SCHED: discarting TB %d pid=%d, tti=%d, maximum number of retx exceeded (%d)\n", tb_idx, id, tti, max_retx);
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void harq_proc::new_tx_common(uint32_t tti_, int mcs, int tbs)
|
||||
void harq_proc::new_tx_common(uint32_t tb_idx, uint32_t tti_, int mcs, int tbs)
|
||||
{
|
||||
reset();
|
||||
ndi = !ndi;
|
||||
reset(tb_idx);
|
||||
ndi[tb_idx] = !ndi[tb_idx];
|
||||
tti = tti_;
|
||||
tx_cnt++;
|
||||
last_mcs = mcs;
|
||||
last_tbs = tbs;
|
||||
tx_cnt[tb_idx]++;
|
||||
last_mcs[tb_idx] = mcs;
|
||||
last_tbs[tb_idx] = tbs;
|
||||
|
||||
if (max_retx) {
|
||||
active = true;
|
||||
|
@ -122,42 +124,42 @@ void harq_proc::new_tx_common(uint32_t tti_, int mcs, int tbs)
|
|||
}
|
||||
}
|
||||
|
||||
void harq_proc::new_retx(uint32_t tti_, int *mcs, int *tbs)
|
||||
void harq_proc::new_retx(uint32_t tb_idx, uint32_t tti_, int *mcs, int *tbs)
|
||||
{
|
||||
ack_received = false;
|
||||
ack_received[tb_idx] = false;
|
||||
tti = tti_;
|
||||
n_rtx++;
|
||||
n_rtx[tb_idx]++;
|
||||
if (mcs) {
|
||||
*mcs = last_mcs;
|
||||
*mcs = last_mcs[tb_idx];
|
||||
}
|
||||
if (tbs) {
|
||||
*tbs = last_tbs;
|
||||
*tbs = last_tbs[tb_idx];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t harq_proc::nof_tx()
|
||||
uint32_t harq_proc::nof_tx(uint32_t tb_idx)
|
||||
{
|
||||
return tx_cnt;
|
||||
return tx_cnt[tb_idx];
|
||||
}
|
||||
|
||||
uint32_t harq_proc::nof_retx()
|
||||
uint32_t harq_proc::nof_retx(uint32_t tb_idx)
|
||||
{
|
||||
return n_rtx;
|
||||
return n_rtx[tb_idx];
|
||||
}
|
||||
|
||||
bool harq_proc::get_ndi()
|
||||
bool harq_proc::get_ndi(uint32_t tb_idx)
|
||||
{
|
||||
return ndi;
|
||||
return ndi[tb_idx];
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* UE::DL HARQ class *
|
||||
******************************************************/
|
||||
|
||||
void dl_harq_proc::new_tx(uint32_t tti, int mcs, int tbs, uint32_t n_cce_)
|
||||
void dl_harq_proc::new_tx(uint32_t tb_idx, uint32_t tti, int mcs, int tbs, uint32_t n_cce_)
|
||||
{
|
||||
n_cce = n_cce_;
|
||||
new_tx_common(tti, mcs, tbs);
|
||||
new_tx_common(tb_idx, tti, mcs, tbs);
|
||||
}
|
||||
|
||||
uint32_t dl_harq_proc::get_n_cce()
|
||||
|
@ -175,14 +177,14 @@ void dl_harq_proc::set_rbgmask(uint32_t new_mask)
|
|||
rbgmask = new_mask;
|
||||
}
|
||||
|
||||
bool dl_harq_proc::has_pending_retx(uint32_t current_tti)
|
||||
bool dl_harq_proc::has_pending_retx(uint32_t tb_idx, uint32_t current_tti)
|
||||
{
|
||||
return srslte_tti_interval(current_tti, tti) >= 8 && has_pending_retx_common();
|
||||
return srslte_tti_interval(current_tti, tti) >= 8 && has_pending_retx_common(tb_idx);
|
||||
}
|
||||
|
||||
int dl_harq_proc::get_tbs()
|
||||
int dl_harq_proc::get_tbs(uint32_t tb_idx)
|
||||
{
|
||||
return last_tbs;
|
||||
return last_tbs[tb_idx];
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,7 +217,7 @@ bool ul_harq_proc::is_adaptive_retx()
|
|||
void ul_harq_proc::new_tx(uint32_t tti_, int mcs, int tbs)
|
||||
{
|
||||
need_ack = true;
|
||||
new_tx_common(tti_, mcs, tbs);
|
||||
new_tx_common(0, tti_, mcs, tbs);
|
||||
pending_data = tbs;
|
||||
}
|
||||
|
||||
|
@ -225,7 +227,7 @@ bool ul_harq_proc::has_pending_ack()
|
|||
bool ret = need_ack;
|
||||
|
||||
// Reset if already received a positive ACK
|
||||
if (active && ack) {
|
||||
if (active && ack[0]) {
|
||||
active = false;
|
||||
}
|
||||
if (!active) {
|
||||
|
@ -244,9 +246,9 @@ void ul_harq_proc::reset_pending_data()
|
|||
}
|
||||
|
||||
|
||||
uint32_t ul_harq_proc::get_pending_data()
|
||||
uint32_t ul_harq_proc::get_pending_data()
|
||||
{
|
||||
return pending_data;
|
||||
return (uint32_t) pending_data;
|
||||
}
|
||||
|
||||
void ul_harq_proc::set_rar_mcs(uint32_t mcs)
|
||||
|
|
|
@ -212,7 +212,7 @@ void ul_metric_rr::new_tti(std::map<uint16_t,sched_ue> &ue_db, uint32_t nof_rb_,
|
|||
nof_users_with_data = 0;
|
||||
for(std::map<uint16_t, sched_ue>::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) {
|
||||
sched_ue *user = (sched_ue*) &iter->second;
|
||||
if (user->get_pending_ul_new_data(current_tti) || !user->get_ul_harq(current_tti)->is_empty()) {
|
||||
if (user->get_pending_ul_new_data(current_tti) || !user->get_ul_harq(current_tti)->is_empty(0)) {
|
||||
user->ue_idx = nof_users_with_data;
|
||||
nof_users_with_data++;
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ ul_harq_proc* ul_metric_rr::get_user_allocation(sched_ue *user)
|
|||
uint32_t pending_data = user->get_pending_ul_new_data(current_tti);
|
||||
ul_harq_proc *h = user->get_ul_harq(current_tti);
|
||||
|
||||
if (pending_data || !h->is_empty()) {
|
||||
if (pending_data || !h->is_empty(0)) {
|
||||
if (nof_users_with_data) {
|
||||
if ((current_tti%nof_users_with_data) != user->ue_idx) {
|
||||
return NULL;
|
||||
|
@ -294,7 +294,7 @@ ul_harq_proc* ul_metric_rr::get_user_allocation(sched_ue *user)
|
|||
|
||||
// Schedule retx if we have space
|
||||
|
||||
if (!h->is_empty()) {
|
||||
if (!h->is_empty(0)) {
|
||||
|
||||
ul_harq_proc::ul_alloc_t alloc = h->get_alloc();
|
||||
|
||||
|
@ -313,7 +313,7 @@ ul_harq_proc* ul_metric_rr::get_user_allocation(sched_ue *user)
|
|||
}
|
||||
}
|
||||
// If could not schedule the reTx, or there wasn't any pending retx, find an empty PID
|
||||
if (h->is_empty()) {
|
||||
if (h->is_empty(0)) {
|
||||
// Allocate resources based on pending data
|
||||
if (pending_data) {
|
||||
uint32_t pending_rb = user->get_required_prb_ul(pending_data);
|
||||
|
|
|
@ -109,8 +109,8 @@ void sched_ue::reset()
|
|||
ul_cqi_tti = 0;
|
||||
cqi_request_tti = 0;
|
||||
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
|
||||
dl_harq[i].reset();
|
||||
ul_harq[i].reset();
|
||||
dl_harq[i].reset(0);
|
||||
ul_harq[i].reset(0);
|
||||
}
|
||||
for (int i=0;i<sched_interface::MAX_LC; i++) {
|
||||
rem_bearer(i);
|
||||
|
@ -291,8 +291,8 @@ int sched_ue::set_ack_info(uint32_t tti, bool ack)
|
|||
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
|
||||
if (((dl_harq[i].get_tti()+4)%10240) == tti) {
|
||||
Debug("SCHED: Set ACK=%d for rnti=0x%x, pid=%d, tti=%d\n", ack, rnti, i, tti);
|
||||
dl_harq[i].set_ack(ack);
|
||||
return dl_harq[i].get_tbs();
|
||||
dl_harq[i].set_ack(0, ack);
|
||||
return dl_harq[i].get_tbs(0);
|
||||
}
|
||||
}
|
||||
Warning("SCHED: Received ACK info for unknown TTI=%d\n", tti);
|
||||
|
@ -320,7 +320,7 @@ void sched_ue::ul_recv_len(uint32_t lcid, uint32_t len)
|
|||
|
||||
void sched_ue::set_ul_crc(uint32_t tti, bool crc_res)
|
||||
{
|
||||
get_ul_harq(tti)->set_ack(crc_res);
|
||||
get_ul_harq(tti)->set_ack(0, crc_res);
|
||||
}
|
||||
|
||||
void sched_ue::set_dl_ri(uint32_t tti, uint32_t ri)
|
||||
|
@ -329,12 +329,23 @@ void sched_ue::set_dl_ri(uint32_t tti, uint32_t ri)
|
|||
dl_ri_tti = tti;
|
||||
}
|
||||
|
||||
void sched_ue::set_dl_pmi(uint32_t tti, uint32_t pmi)
|
||||
{
|
||||
dl_pmi = pmi;
|
||||
dl_pmi_tti = tti;
|
||||
}
|
||||
|
||||
void sched_ue::set_dl_cqi(uint32_t tti, uint32_t cqi)
|
||||
{
|
||||
dl_cqi = cqi;
|
||||
dl_cqi_tti = tti;
|
||||
}
|
||||
|
||||
void sched_ue::set_dl_ant_info(LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *d)
|
||||
{
|
||||
memcpy(&dl_ant_info, d, sizeof(LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT));
|
||||
}
|
||||
|
||||
void sched_ue::set_ul_cqi(uint32_t tti, uint32_t cqi, uint32_t ul_ch_code)
|
||||
{
|
||||
ul_cqi = cqi;
|
||||
|
@ -385,7 +396,7 @@ int sched_ue::generate_format1(dl_harq_proc *h,
|
|||
if (is_first_dl_tx()) {
|
||||
need_conres_ce = true;
|
||||
}
|
||||
if (h->is_empty()) {
|
||||
if (h->is_empty(0)) {
|
||||
|
||||
uint32_t req_bytes = get_pending_dl_new_data(tti);
|
||||
|
||||
|
@ -401,11 +412,11 @@ int sched_ue::generate_format1(dl_harq_proc *h,
|
|||
mcs = fixed_mcs_dl;
|
||||
}
|
||||
|
||||
h->new_tx(tti, mcs, tbs, data->dci_location.ncce);
|
||||
h->new_tx(0, tti, mcs, tbs, data->dci_location.ncce);
|
||||
|
||||
Debug("SCHED: Alloc format1 new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes);
|
||||
} else {
|
||||
h->new_retx(tti, &mcs, &tbs);
|
||||
h->new_retx(0, tti, &mcs, &tbs);
|
||||
Debug("SCHED: Alloc format1 previous mcs=%d, tbs=%d\n", mcs, tbs);
|
||||
}
|
||||
|
||||
|
@ -431,11 +442,151 @@ int sched_ue::generate_format1(dl_harq_proc *h,
|
|||
if (tbs > 0) {
|
||||
dci->harq_process = h->get_id();
|
||||
dci->mcs_idx = mcs;
|
||||
dci->rv_idx = sched::get_rvidx(h->nof_retx());
|
||||
dci->ndi = h->get_ndi();
|
||||
dci->rv_idx = sched::get_rvidx(h->nof_retx(0));
|
||||
dci->ndi = h->get_ndi(0);
|
||||
dci->tpc_pucch = next_tpc_pucch;
|
||||
next_tpc_pucch = 1;
|
||||
data->tbs = tbs;
|
||||
data->tbs[0] = tbs;
|
||||
dci->tb_en[0] = true;
|
||||
dci->tb_en[1] = false;
|
||||
}
|
||||
return tbs;
|
||||
}
|
||||
|
||||
// Generates a Format2a grant
|
||||
int sched_ue::generate_format2a(dl_harq_proc *h,
|
||||
sched_interface::dl_sched_data_t *data,
|
||||
uint32_t tti,
|
||||
uint32_t cfi)
|
||||
{
|
||||
srslte_ra_dl_dci_t *dci = &data->dci;
|
||||
bzero(dci, sizeof(srslte_ra_dl_dci_t));
|
||||
|
||||
uint32_t sf_idx = tti%10;
|
||||
|
||||
int mcs = 0;
|
||||
int tbs = 0;
|
||||
|
||||
dci->alloc_type = SRSLTE_RA_ALLOC_TYPE0;
|
||||
dci->type0_alloc.rbg_bitmask = h->get_rbgmask();
|
||||
|
||||
if (h->is_empty(0)) {
|
||||
|
||||
uint32_t req_bytes = get_pending_dl_new_data(tti);
|
||||
|
||||
uint32_t nof_prb = format1_count_prb(h->get_rbgmask(), cell.nof_prb);
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_dl_dci_to_grant_prb_allocation(dci, &grant, cell.nof_prb);
|
||||
uint32_t nof_ctrl_symbols = cfi+(cell.nof_prb<10?1:0);
|
||||
uint32_t nof_re = srslte_ra_dl_grant_nof_re(&grant, cell, sf_idx, nof_ctrl_symbols);
|
||||
if (fixed_mcs_dl < 0) {
|
||||
tbs = alloc_tbs_dl(nof_prb, nof_re, req_bytes, &mcs);
|
||||
} else {
|
||||
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_dl), nof_prb)/8;
|
||||
mcs = fixed_mcs_dl;
|
||||
}
|
||||
|
||||
h->new_tx(0, tti, mcs, tbs, data->dci_location.ncce);
|
||||
|
||||
Debug("SCHED: Alloc format1 new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes);
|
||||
} else {
|
||||
h->new_retx(0, tti, &mcs, &tbs);
|
||||
Debug("SCHED: Alloc format1 previous mcs=%d, tbs=%d\n", mcs, tbs);
|
||||
}
|
||||
|
||||
int rem_tbs = tbs;
|
||||
int x = 0;
|
||||
do {
|
||||
x = alloc_pdu(rem_tbs, &data->pdu[data->nof_pdu_elems]);
|
||||
rem_tbs -= x;
|
||||
if (x) {
|
||||
data->nof_pdu_elems++;
|
||||
}
|
||||
} while(rem_tbs > 0 && x > 0);
|
||||
|
||||
data->rnti = rnti;
|
||||
|
||||
if (tbs > 0) {
|
||||
dci->harq_process = h->get_id();
|
||||
dci->mcs_idx = mcs;
|
||||
dci->rv_idx = sched::get_rvidx(h->nof_retx(0));
|
||||
dci->ndi = h->get_ndi(0);
|
||||
dci->tpc_pucch = next_tpc_pucch;
|
||||
next_tpc_pucch = 1;
|
||||
data->tbs[0] = tbs;
|
||||
dci->tb_en[0] = true;
|
||||
dci->tb_en[1] = false;
|
||||
}
|
||||
return tbs;
|
||||
}
|
||||
|
||||
// Generates a Format2 grant
|
||||
int sched_ue::generate_format2(dl_harq_proc *h,
|
||||
sched_interface::dl_sched_data_t *data,
|
||||
uint32_t tti,
|
||||
uint32_t cfi)
|
||||
{
|
||||
srslte_ra_dl_dci_t *dci = &data->dci;
|
||||
bzero(dci, sizeof(srslte_ra_dl_dci_t));
|
||||
|
||||
uint32_t sf_idx = tti%10;
|
||||
|
||||
int mcs = 0;
|
||||
int tbs = 0;
|
||||
|
||||
dci->alloc_type = SRSLTE_RA_ALLOC_TYPE0;
|
||||
dci->type0_alloc.rbg_bitmask = h->get_rbgmask();
|
||||
|
||||
if (h->is_empty(0)) {
|
||||
|
||||
uint32_t req_bytes = get_pending_dl_new_data(tti);
|
||||
|
||||
uint32_t nof_prb = format1_count_prb(h->get_rbgmask(), cell.nof_prb);
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_dl_dci_to_grant_prb_allocation(dci, &grant, cell.nof_prb);
|
||||
uint32_t nof_ctrl_symbols = cfi+(cell.nof_prb<10?1:0);
|
||||
uint32_t nof_re = srslte_ra_dl_grant_nof_re(&grant, cell, sf_idx, nof_ctrl_symbols);
|
||||
if (fixed_mcs_dl < 0) {
|
||||
tbs = alloc_tbs_dl(nof_prb, nof_re, req_bytes, &mcs);
|
||||
} else {
|
||||
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_dl), nof_prb)/8;
|
||||
mcs = fixed_mcs_dl;
|
||||
}
|
||||
|
||||
h->new_tx(0, tti, mcs, tbs, data->dci_location.ncce);
|
||||
|
||||
Debug("SCHED: Alloc format2 new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes);
|
||||
} else {
|
||||
h->new_retx(0, tti, &mcs, &tbs);
|
||||
Debug("SCHED: Alloc format2 previous mcs=%d, tbs=%d\n", mcs, tbs);
|
||||
}
|
||||
|
||||
int rem_tbs = tbs;
|
||||
int x = 0;
|
||||
do {
|
||||
x = alloc_pdu(rem_tbs, &data->pdu[data->nof_pdu_elems]);
|
||||
rem_tbs -= x;
|
||||
if (x) {
|
||||
data->nof_pdu_elems++;
|
||||
}
|
||||
} while(rem_tbs > 0 && x > 0);
|
||||
|
||||
data->rnti = rnti;
|
||||
|
||||
if (tbs > 0) {
|
||||
dci->pinfo = (uint8_t) (dl_pmi + 1);
|
||||
/* if (SRSLTE_RA_DL_GRANT_NOF_TB(dci) == 1) {
|
||||
dci->pinfo = (uint8_t) (dl_pmi + 1);
|
||||
} else {
|
||||
dci->pinfo = (uint8_t) (dl_pmi & 1);
|
||||
}*/
|
||||
dci->harq_process = h->get_id();
|
||||
dci->mcs_idx = mcs;
|
||||
dci->rv_idx = sched::get_rvidx(h->nof_retx(0));
|
||||
dci->ndi = h->get_ndi(0);
|
||||
dci->tpc_pucch = next_tpc_pucch;
|
||||
next_tpc_pucch = 1;
|
||||
data->tbs[0] = tbs;
|
||||
dci->tb_en[0] = true;
|
||||
dci->tb_en[1] = false;
|
||||
}
|
||||
|
@ -459,7 +610,7 @@ int sched_ue::generate_format0(ul_harq_proc *h,
|
|||
if (h->get_rar_mcs(&mcs)) {
|
||||
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs), allocation.L)/8;
|
||||
h->new_tx(tti, mcs, tbs);
|
||||
} else if (h->is_empty()) {
|
||||
} else if (h->is_empty(0)) {
|
||||
|
||||
uint32_t req_bytes = get_pending_ul_new_data(tti);
|
||||
|
||||
|
@ -475,7 +626,7 @@ int sched_ue::generate_format0(ul_harq_proc *h,
|
|||
h->new_tx(tti, mcs, tbs);
|
||||
|
||||
} else {
|
||||
h->new_retx(tti, &mcs, NULL);
|
||||
h->new_retx(0, tti, &mcs, NULL);
|
||||
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs), allocation.L)/8;
|
||||
}
|
||||
|
||||
|
@ -486,8 +637,8 @@ int sched_ue::generate_format0(ul_harq_proc *h,
|
|||
dci->type2_alloc.L_crb = allocation.L;
|
||||
dci->type2_alloc.RB_start = allocation.RB_start;
|
||||
dci->mcs_idx = mcs;
|
||||
dci->rv_idx = sched::get_rvidx(h->nof_retx());
|
||||
dci->ndi = h->get_ndi();
|
||||
dci->rv_idx = sched::get_rvidx(h->nof_retx(0));
|
||||
dci->ndi = h->get_ndi(0);
|
||||
dci->cqi_request = cqi_request;
|
||||
dci->freq_hop_fl = srslte_ra_ul_dci_t::SRSLTE_RA_PUSCH_HOP_DISABLED;
|
||||
dci->tpc_pusch = next_tpc_pusch;
|
||||
|
@ -518,7 +669,7 @@ uint32_t sched_ue::get_max_retx() {
|
|||
bool sched_ue::is_first_dl_tx()
|
||||
{
|
||||
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
|
||||
if (dl_harq[i].nof_tx() > 0) {
|
||||
if (dl_harq[i].nof_tx(0) > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -666,7 +817,7 @@ dl_harq_proc* sched_ue::get_pending_dl_harq(uint32_t tti)
|
|||
int oldest_idx=-1;
|
||||
uint32_t oldest_tti = 0;
|
||||
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
|
||||
if (dl_harq[i].has_pending_retx(tti)) {
|
||||
if (dl_harq[i].has_pending_retx(0, tti)) {
|
||||
uint32_t x = srslte_tti_interval(tti, dl_harq[i].get_tti());
|
||||
if (x > oldest_tti) {
|
||||
oldest_idx = i;
|
||||
|
@ -684,7 +835,7 @@ dl_harq_proc* sched_ue::get_pending_dl_harq(uint32_t tti)
|
|||
dl_harq_proc* sched_ue::get_empty_dl_harq()
|
||||
{
|
||||
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
|
||||
if (dl_harq[i].is_empty()) {
|
||||
if (dl_harq[i].is_empty(0)) {
|
||||
return &dl_harq[i];
|
||||
}
|
||||
}
|
||||
|
@ -696,6 +847,36 @@ ul_harq_proc* sched_ue::get_ul_harq(uint32_t tti)
|
|||
return &ul_harq[tti%SCHED_MAX_HARQ_PROC];
|
||||
}
|
||||
|
||||
srslte_dci_format_t sched_ue::get_dci_format() {
|
||||
srslte_dci_format_t ret = SRSLTE_DCI_FORMAT1;
|
||||
|
||||
if (phy_config_dedicated_enabled) {
|
||||
/* FIXME: Assumes UE-Specific Search Space (Not common) */
|
||||
switch (dl_ant_info.tx_mode) {
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_1:
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_2:
|
||||
ret = SRSLTE_DCI_FORMAT1;
|
||||
break;
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_3:
|
||||
ret = SRSLTE_DCI_FORMAT2A;
|
||||
break;
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_4:
|
||||
ret = SRSLTE_DCI_FORMAT2;
|
||||
break;
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_5:
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_6:
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_7:
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_8:
|
||||
case LIBLTE_RRC_TRANSMISSION_MODE_N_ITEMS:
|
||||
default:
|
||||
Warning("Incorrect transmission mode (rnti=%04x)\n", rnti);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Find lowest DCI aggregation level supported by the UE spectral efficiency */
|
||||
uint32_t sched_ue::get_aggr_level(uint32_t nof_bits)
|
||||
{
|
||||
|
|
|
@ -412,6 +412,11 @@ void ue::metrics_dl_ri(uint32_t dl_ri) {
|
|||
dl_ri_counter++;
|
||||
}
|
||||
|
||||
void ue::metrics_dl_pmi(uint32_t dl_ri) {
|
||||
metrics.dl_pmi = SRSLTE_VEC_CMA((float) dl_ri, metrics.dl_pmi, dl_pmi_counter);
|
||||
dl_pmi_counter++;
|
||||
}
|
||||
|
||||
void ue::metrics_dl_cqi(uint32_t dl_cqi) {
|
||||
metrics.dl_cqi = SRSLTE_VEC_CMA((float) dl_cqi, metrics.dl_cqi, dl_cqi_counter);
|
||||
dl_cqi_counter++;
|
||||
|
|
|
@ -99,6 +99,7 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
|
|||
fprintf(stderr, "Error allocating memory\n");
|
||||
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, phy->cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initiating ENB DL\n");
|
||||
|
@ -566,6 +567,10 @@ int phch_worker::decode_pucch(uint32_t tti_rx)
|
|||
needs_cqi = true;
|
||||
cqi_value.type = SRSLTE_CQI_TYPE_WIDEBAND;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,6 +594,17 @@ int phch_worker::decode_pucch(uint32_t tti_rx)
|
|||
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) {
|
||||
uint8_t *ptr = uci_data.uci_pmi;
|
||||
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\n",
|
||||
rnti,
|
||||
|
@ -656,35 +672,16 @@ int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_gra
|
|||
{
|
||||
/* For each grant... */
|
||||
for (uint32_t i=0;i<nof_grants;i++) {
|
||||
uint16_t rnti = grants[i].rnti;
|
||||
srslte_enb_dl_pdsch_t *grant = &grants[i];
|
||||
uint16_t rnti = grant->rnti;
|
||||
if (rnti) {
|
||||
bool dedicated_acknowledged = ue_db[grants[i].rnti].dedicated_ack;
|
||||
bool antenna_info_present = ue_db[grants[i].rnti].dedicated.antenna_info_present;
|
||||
LIBLTE_RRC_TRANSMISSION_MODE_ENUM tx_mode = ue_db[grants[i].rnti].dedicated.antenna_info_explicit_value.tx_mode;
|
||||
|
||||
srslte_dci_format_t format = SRSLTE_DCI_FORMAT1;
|
||||
switch(grants[i].grant.alloc_type) {
|
||||
case SRSLTE_RA_ALLOC_TYPE0:
|
||||
case SRSLTE_RA_ALLOC_TYPE1:
|
||||
if (dedicated_acknowledged && antenna_info_present && tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) {
|
||||
format = SRSLTE_DCI_FORMAT2A;
|
||||
} else if (dedicated_acknowledged && antenna_info_present && tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
||||
format = SRSLTE_DCI_FORMAT2;
|
||||
} else {
|
||||
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_idx)) {
|
||||
if (srslte_enb_dl_put_pdcch_dl(&enb_dl, &grants[i].grant, grant->dci_format, grants[i].location, rnti, sf_idx)) {
|
||||
fprintf(stderr, "Error putting PDCCH %d\n",i);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (LOG_THIS(rnti)) {
|
||||
Info("PDCCH: DL DCI %s rnti=0x%x, cce_index=%d, L=%d, tti_tx=%d\n", srslte_dci_format_string(format),
|
||||
Info("PDCCH: DL DCI %s rnti=0x%x, cce_index=%d, L=%d, tti_tx=%d\n", srslte_dci_format_string(grant->dci_format),
|
||||
rnti, grants[i].location.ncce, (1<<grants[i].location.L), tti_tx);
|
||||
}
|
||||
}
|
||||
|
@ -694,18 +691,16 @@ int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_gra
|
|||
|
||||
int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants, uint32_t sf_idx)
|
||||
{
|
||||
/* FIXME: currently, it assumes TM1, TM2 or TM3 */
|
||||
srslte_mimo_type_t mimo_type = (enb_dl.cell.nof_ports == 1) ? SRSLTE_MIMO_TYPE_SINGLE_ANTENNA : SRSLTE_MIMO_TYPE_TX_DIVERSITY;
|
||||
|
||||
for (uint32_t i=0;i<nof_grants;i++) {
|
||||
uint16_t rnti = grants[i].rnti;
|
||||
if (rnti) {
|
||||
|
||||
bool rnti_is_user = true;
|
||||
if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || rnti == SRSLTE_MRNTI) {
|
||||
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_dci_to_grant(&grants[i].grant, enb_dl.cell.nof_prb, rnti, &phy_grant);
|
||||
|
||||
|
@ -717,11 +712,41 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
|
|||
case SRSLTE_RA_ALLOC_TYPE1:
|
||||
sprintf(grant_str, "mask=0x%x",grants[i].grant.type1_alloc.vrb_bitmask);
|
||||
break;
|
||||
case SRSLTE_RA_ALLOC_TYPE2:
|
||||
default:
|
||||
sprintf(grant_str, "rb_start=%d",grants[i].grant.type2_alloc.RB_start);
|
||||
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:
|
||||
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) == 1 && phy_grant.pinfo == 0) {
|
||||
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)) {
|
||||
uint8_t x = 0;
|
||||
uint8_t *ptr = grants[i].data[0];
|
||||
|
@ -730,15 +755,19 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
|
|||
ptr = &x;
|
||||
len = 1;
|
||||
}
|
||||
char pinfo_str[16] = {0};
|
||||
if (dci_format == SRSLTE_DCI_FORMAT2) {
|
||||
snprintf(pinfo_str, 15, ", pinfo=%x", phy_grant.pinfo);
|
||||
}
|
||||
log_h->info_hex(ptr, len,
|
||||
"PDSCH: rnti=0x%x, l_crb=%2d, %s, harq=%d, tbs=%d, mcs=%d, rv=%d, tti_tx=%d\n",
|
||||
"PDSCH: rnti=0x%x, l_crb=%2d, %s, harq=%d, tbs=%d, mcs=%d, rv=%d, tti_tx=%d, tx_scheme=%s%s\n",
|
||||
rnti, phy_grant.nof_prb, grant_str, grants[i].grant.harq_process,
|
||||
phy_grant.mcs[0].tbs/8, phy_grant.mcs[0].idx, grants[i].grant.rv_idx, tti_tx);
|
||||
phy_grant.mcs[0].tbs/8, phy_grant.mcs[0].idx, grants[i].grant.rv_idx, tti_tx, srslte_mimotype2str(mimo_type), pinfo_str);
|
||||
}
|
||||
|
||||
int rv[SRSLTE_MAX_CODEWORDS] = {grants[i].grant.rv_idx, grants[i].grant.rv_idx_1};
|
||||
|
||||
if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, grants[i].softbuffers, rnti, rv, sf_idx, grants[i].data, mimo_type, 0)) {
|
||||
if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, grants[i].softbuffers, rnti, rv, sf_idx, grants[i].data, mimo_type)) {
|
||||
fprintf(stderr, "Error putting PDSCH %d\n",i);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
|
|
@ -864,6 +864,7 @@ void rrc::ue::handle_rrc_con_setup_complete(LIBLTE_RRC_CONNECTION_SETUP_COMPLETE
|
|||
|
||||
// Acknowledge Dedicated Configuration
|
||||
parent->phy->set_conf_dedicated_ack(rnti, true);
|
||||
parent->mac->phy_config_enabled(rnti, true);
|
||||
|
||||
if(has_tmsi) {
|
||||
parent->s1ap->initial_ue(rnti, pdu, m_tmsi, mmec);
|
||||
|
@ -1211,7 +1212,8 @@ void rrc::ue::send_connection_setup(bool is_setup)
|
|||
// Configure PHY layer
|
||||
parent->phy->set_config_dedicated(rnti, phy_cfg);
|
||||
parent->phy->set_conf_dedicated_ack(rnti, false);
|
||||
parent->mac->phy_config_enabled(rnti, true);
|
||||
parent->mac->set_dl_ant_info(rnti, &phy_cfg->antenna_info_explicit_value);
|
||||
parent->mac->phy_config_enabled(rnti, false);
|
||||
|
||||
rr_cfg->drb_to_add_mod_list_size = 0;
|
||||
rr_cfg->drb_to_release_list_size = 0;
|
||||
|
|
|
@ -374,7 +374,6 @@ void phch_worker::compute_ri() {
|
|||
float sinr = 0.0f;
|
||||
uint8 packed_pmi = 0;
|
||||
srslte_ue_dl_ri_pmi_select(&ue_dl, &uci_data.uci_ri, &packed_pmi, &sinr);
|
||||
srslte_bit_unpack_vector(&packed_pmi, uci_data.uci_pmi, 2);
|
||||
if (uci_data.uci_ri == 0) {
|
||||
uci_data.uci_pmi_len = 2;
|
||||
uci_data.uci_dif_cqi_len = 0;
|
||||
|
@ -382,6 +381,8 @@ void phch_worker::compute_ri() {
|
|||
uci_data.uci_pmi_len = 1;
|
||||
uci_data.uci_dif_cqi_len = 3;
|
||||
}
|
||||
srslte_bit_unpack_vector(&packed_pmi, uci_data.uci_pmi, uci_data.uci_pmi_len);
|
||||
Info("pmi=%d\n", packed_pmi);
|
||||
|
||||
/* If only one antenna in TM4 print limitation warning */
|
||||
if (ue_dl.nof_rx_antennas < 2) {
|
||||
|
@ -615,9 +616,13 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL
|
|||
snprintf(timestr, 64, ", dec_time=%4d us", (int) t[0].tv_usec);
|
||||
#endif
|
||||
|
||||
snprintf(commonstr, 128, "PDSCH: l_crb=%2d, harq=%d, snr=%.1f dB, tx_scheme=%s", grant->nof_prb, harq_pid,
|
||||
10 * log10(srslte_chest_dl_get_snr(&ue_dl.chest)), srslte_mimotype2str(mimo_type));
|
||||
char pinfo_str[16] = {0};
|
||||
if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
||||
snprintf(pinfo_str, 15, ", pinfo=%x", grant->pinfo);
|
||||
}
|
||||
|
||||
snprintf(commonstr, 128, "PDSCH: l_crb=%2d, harq=%d, snr=%.1f dB, tx_scheme=%s%s", grant->nof_prb, harq_pid,
|
||||
10 * log10(srslte_chest_dl_get_snr(&ue_dl.chest)), srslte_mimotype2str(mimo_type), pinfo_str);
|
||||
for (int i=0;i<SRSLTE_MAX_CODEWORDS;i++) {
|
||||
if (grant->tb_en[i]) {
|
||||
snprintf(tbstr[i], 128, ", TB%d: tbs=%d, mcs=%d, rv=%d, crc=%s, it=%d",
|
||||
|
@ -826,6 +831,16 @@ void phch_worker::set_uci_periodic_cqi()
|
|||
}
|
||||
Info("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db);
|
||||
}
|
||||
if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
||||
if (ue_dl.ri == 0) {
|
||||
uci_data.uci_pmi_len = 2;
|
||||
} else {
|
||||
uci_data.uci_pmi_len = 1;
|
||||
uci_data.uci_dif_cqi_len = 3;
|
||||
}
|
||||
uint8_t *ptr = uci_data.uci_pmi;
|
||||
srslte_bit_unpack(ue_dl.pmi[ue_dl.ri], &ptr, uci_data.uci_pmi_len);
|
||||
}
|
||||
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
||||
rar_cqi_request = false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue