Fixing RSRP measurements

This commit is contained in:
Ismael Gomez 2017-11-25 10:40:53 +01:00
parent a604cfb99b
commit 8447c965e3
8 changed files with 110 additions and 28 deletions

View File

@ -546,7 +546,10 @@ public:
} phy_cfg_t;
virtual void get_current_cell(srslte_cell_t *cell, uint32_t *current_earfcn = NULL) = 0;
virtual void get_config(phy_cfg_t *phy_cfg) = 0;
virtual uint32_t get_current_earfcn() = 0;
virtual uint32_t get_current_pci() = 0;
virtual void get_config(phy_cfg_t *phy_cfg) = 0;
virtual void set_config(phy_cfg_t *phy_cfg) = 0;
virtual void set_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated) = 0;
virtual void set_config_common(phy_cfg_common_t *common) = 0;

View File

@ -435,7 +435,9 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui
}
/* Compute RSRP for the channel estimates in this port */
q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id));
uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
float energy = cabsf(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots);
q->rsrp[rxant_id][port_id] = energy*energy;
if (port_id == 0) {
/* compute rssi only for port 0 */
q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id);

View File

@ -137,7 +137,10 @@ public:
float get_pathloss_db();
uint32_t get_current_tti();
void get_current_cell(srslte_cell_t *cell, uint32_t *current_earfcn = NULL);
uint32_t get_current_earfcn();
uint32_t get_current_pci();
void start_plot();

View File

@ -346,6 +346,27 @@ private:
rrc_meas measurements;
// Cell selection/reselection functions/variables
typedef struct {
float Qrxlevmin;
float Qrxlevminoffset;
float Qqualmin;
float Qqualminoffset;
float s_intrasearchP;
float s_intrasearchQ;
float q_hyst;
float threshservinglow;
} cell_resel_cfg_t;
cell_resel_cfg_t cell_resel_cfg;
float get_srxlev(float Qrxlevmeas);
float get_squal(float Qqualmeas);
void cell_reselection_eval(float rsrp, float rsrq);
// RLC interface
void max_retx_attempted();

View File

@ -213,10 +213,8 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32
for (uint32_t i=0;i<lch.size();i++) {
lch[i].buffer_len = rlc->get_buffer_state(lch[i].id);
lch[i].sched_len = 0;
Info("lch[%d].buffer_len=%d\n",i,lch[i].buffer_len);
}
// data from any Logical Channel, except data from UL-CCCH;
// first only those with positive Bj
for (uint32_t i=0;i<lch.size();i++) {

View File

@ -1063,14 +1063,20 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx)
float rsrq = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest));
float snr = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest));
mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt);
mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt);
mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt);
if (cnt == 0) {
mean_rsrp = rsrp;
mean_rsrq = rsrq;
mean_snr = snr;
} else {
mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt);
mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt);
mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt);
}
cnt++;
log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n",
cnt, nof_subframes, sf_idx,
rsrp, snr);
cnt, nof_subframes, sf_idx, rsrp, snr);
if (cnt >= nof_subframes) {
return MEASURE_OK;
@ -1107,7 +1113,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h)
}
srslte_sync_cp_en(&sync_find, false);
srslte_sync_set_cfo_ema_alpha(&sync_find, 0.8);
srslte_sync_set_threshold(&sync_find, 2.0);
srslte_sync_set_threshold(&sync_find, 1.2);
reset();
}
@ -1126,6 +1132,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
fprintf(stderr, "Error resizing sync\n");
return SRSLTE_ERROR;
}
int nof_cells = 0;
uint32_t peak_idx = 0;
uint32_t sf_idx = 0;
@ -1143,7 +1150,9 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
if (current_cell.id%3 != n_id_2) {
srslte_sync_set_N_id_2(&sync_find, n_id_2);
switch(srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx)) {
srslte_sync_find_ret_t sync_res = srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx);
switch(sync_res) {
case SRSLTE_SYNC_ERROR:
return SRSLTE_ERROR;
fprintf(stderr, "Error finding correlation peak\n");
@ -1155,6 +1164,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
peak_idx, n_id_2, cell_id, sf_idx);
found_cell.id = cell_id;
found_cell.nof_ports = 1; // Use port 0 only for measurement
measure_p.set_cell(found_cell);
offset = peak_idx-sf_len/2;
@ -1208,7 +1218,9 @@ void phch_recv::meas_reset() {
int phch_recv::meas_start(uint32_t earfcn, int pci) {
if (earfcn == current_earfcn) {
worker_com->pcell_meas_enabled = true;
intra_freq_meas.add_cell(pci);
if (pci != (int) cell.id) {
intra_freq_meas.add_cell(pci);
}
return 0;
} else {
Warning("INTRA: Inter-frequency measurements not supported (current EARFCN=%d, requested measurement for %d)\n",
@ -1331,7 +1343,7 @@ void phch_recv::intra_measure::run_thread()
}
if (running) {
Info("INTRA: Running intra-frequency measurement for %d cells\n", active_pci.size());
Info("INTRA: Running intra-frequency measurements\n");
// Read 5 ms data from buffer
srslte_ringbuffer_read(&ring_buffer, search_buffer, CAPTURE_LEN_SF*current_sflen*sizeof(cf_t));

View File

@ -301,6 +301,18 @@ void phy::get_current_cell(srslte_cell_t *cell, uint32_t *current_earfcn)
sf_recv.get_current_cell(cell, current_earfcn);
}
uint32_t phy::get_current_pci() {
srslte_cell_t cell;
sf_recv.get_current_cell(&cell);
return cell.id;
}
uint32_t phy::get_current_earfcn() {
uint32_t earfcn;
sf_recv.get_current_cell(NULL, &earfcn);
return earfcn;
}
void phy::prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm)
{

View File

@ -255,6 +255,7 @@ void rrc::run_thread() {
rrc_log->info("Leaving RRC_CONNECTED state\n");
drb_up = false;
reestablishment_in_progress = false;
measurements.reset();
pdcp->reset();
rlc->reset();
phy->reset();
@ -264,6 +265,11 @@ void rrc::run_thread() {
mac->pcch_start_rx();
mac_timers->timer_get(t310)->stop();
mac_timers->timer_get(t311)->stop();
// Instruct PHY to measure serving cell for cell reselection
phy->meas_start(phy->get_current_earfcn(), phy->get_current_pci());
// Move to RRC_IDLE
state = RRC_STATE_IDLE;
break;
default:
@ -460,7 +466,11 @@ void rrc::select_next_cell_in_plmn() {
}
void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, uint32_t earfcn, uint32_t pci) {
measurements.new_phy_meas(earfcn, pci, rsrp, rsrq, tti);
if (state == RRC_STATE_CONNECTED) {
measurements.new_phy_meas(earfcn, pci, rsrp, rsrq, tti);
} else {
cell_reselection_eval(rsrp, rsrq);
}
}
void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) {
@ -493,6 +503,7 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) {
cell.earfcn = earfcn;
cell.has_valid_sib1 = false;
cell.has_valid_sib2 = false;
cell.has_valid_sib3 = false;
known_cells.push_back(cell);
// save current cell
@ -532,8 +543,31 @@ void rrc::add_neighbour_cell(uint32_t earfcn, uint32_t pci, float rsrp) {
known_cells.push_back(c);
}
// Cell reselection in IDLE Section 5.2.4 of 36.304
void rrc::cell_reselection_eval(float rsrp, float rsrq)
{
// Intra-frequency cell-reselection criteria
if (get_srxlev(rsrp) > cell_resel_cfg.s_intrasearchP && get_squal(rsrq) > cell_resel_cfg.s_intrasearchQ) {
// UE may not perform intra-frequency measurements
phy->meas_reset();
} else {
// UE must start intra-frequency measurements
phy->meas_start(phy->get_current_earfcn(), -1);
}
// TODO: Inter-frequency cell reselection
}
float rrc::get_srxlev(float Qrxlevmeas) {
// TODO: Do max power limitation
float Pcompensation = 0;
return Qrxlevmeas - (cell_resel_cfg.Qrxlevmin + cell_resel_cfg.Qrxlevminoffset) - Pcompensation;
}
float rrc::get_squal(float Qqualmeas) {
return Qqualmeas - (cell_resel_cfg.Qqualmin + cell_resel_cfg.Qqualminoffset);
}
@ -865,14 +899,11 @@ void rrc::ho_prepare() {
mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci);
apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common);
uint32_t current_earfcn = 0;
phy->get_current_cell(NULL, &current_earfcn);
bool found = false;
for (uint32_t i = 0; i < known_cells.size(); i++) {
rrc_log->info("cell[%d]=%d:%d, cur_earfcn=%d\n", i, known_cells[i].earfcn, known_cells[i].phy_cell.id,
current_cell->earfcn);
if (known_cells[i].earfcn == current_earfcn &&
if (known_cells[i].earfcn == phy->get_current_earfcn() &&
known_cells[i].phy_cell.id == mob_reconf.mob_ctrl_info.target_pci) {
rrc_log->info("Selecting new cell pci=%d\n", known_cells[i].phy_cell.id);
if (!phy->cell_handover(known_cells[i].phy_cell)) {
@ -895,7 +926,7 @@ void rrc::ho_prepare() {
}
printf("ncc=%d\n", mob_reconf.sec_cnfg_ho.intra_lte.next_hop_chaining_count);
usim->generate_as_keys_ho(mob_reconf.mob_ctrl_info.target_pci, current_earfcn,
usim->generate_as_keys_ho(mob_reconf.mob_ctrl_info.target_pci, phy->get_current_earfcn(),
k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo);
pdcp->config_security(1, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
send_rrc_con_reconfig_complete(NULL);
@ -1094,6 +1125,8 @@ void rrc::handle_sib2()
void rrc::handle_sib3()
{
rrc_log->info("SIB3 received\n");
}
void rrc::handle_sib13()
@ -1591,8 +1624,8 @@ void rrc::apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT
sizeof(LIBLTE_RRC_UL_POWER_CONTROL_DEDICATED_STRUCT));
} else if (apply_defaults) {
current_cfg->ul_pwr_ctrl_ded.p0_ue_pusch = 0;
current_cfg->ul_pwr_ctrl_ded.delta_mcs_en = LIBLTE_RRC_DELTA_MCS_ENABLED_EN0;
current_cfg->ul_pwr_ctrl_ded.accumulation_en = true;
current_cfg->ul_pwr_ctrl_ded.delta_mcs_en = LIBLTE_RRC_DELTA_MCS_ENABLED_EN0;
current_cfg->ul_pwr_ctrl_ded.accumulation_en = true;
current_cfg->ul_pwr_ctrl_ded.p0_ue_pucch = 0;
current_cfg->ul_pwr_ctrl_ded.p_srs_offset = 7;
}
@ -1741,7 +1774,7 @@ void rrc::apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cnfg
default_cfg.time_alignment_timer = mac_cnfg->time_alignment_timer;
}
// Setup MAC configuration
// Setup MAC configuration
mac->set_config_main(&default_cfg);
// Update UL HARQ config
@ -2099,7 +2132,7 @@ void rrc::rrc_meas::generate_report(uint32_t meas_id)
report->pcell_rsrp_result = value_to_range(RSRP, pcell_measurement.ms[RSRP]);
report->pcell_rsrq_result = value_to_range(RSRQ, pcell_measurement.ms[RSRQ]);
log_h->info("MEAS: Generate report MeasId=%d, rsrp=%f rsrq=%f\n",
log_h->console("MEAS: Generate report MeasId=%d, rsrp=%f rsrq=%f\n",
report->meas_id, pcell_measurement.ms[RSRP], pcell_measurement.ms[RSRQ]);
// TODO: report up to 8 best cells
@ -2189,16 +2222,14 @@ void rrc::rrc_meas::calculate_triggers(uint32_t tti)
// Get serving cell
if (active.size()) {
uint32_t current_earfcn = 0;
srslte_cell_t current_cell;
phy->get_current_cell(&current_cell, &current_earfcn);
if (find_earfcn_cell(current_earfcn, current_cell.id, &serving_object, &serving_cell_idx)) {
if (find_earfcn_cell(phy->get_current_earfcn(), phy->get_current_pci(), &serving_object, &serving_cell_idx)) {
Ofp = serving_object->q_offset;
if (serving_cell_idx >= 0) {
Ocp = serving_object->cells[serving_cell_idx].q_offset;
}
} else {
log_h->warning("Can't find current eafcn=%d, pci=%d in objects list. Using Ofp=0, Ocp=0\n", current_earfcn, current_cell.id);
log_h->warning("Can't find current eafcn=%d, pci=%d in objects list. Using Ofp=0, Ocp=0\n",
phy->get_current_earfcn(), phy->get_current_pci());
}
}